console/libgnt/gnttextview.c

changeset 13958
bd1c3bb3f33d
parent 13950
bd8d39b3a9e2
child 13989
9a647311c9ac
equal deleted inserted replaced
13957:c6ca17e312aa 13958:bd1c3bb3f33d
3 enum 3 enum
4 { 4 {
5 SIGS = 1, 5 SIGS = 1,
6 }; 6 };
7 7
8 typedef struct
9 {
10 GntTextViewFlags flags;
11 char *text;
12 } GntTextSegment;
13
14 typedef struct
15 {
16 GList *segments; /* A list of GntTextSegments */
17 int length; /* The current length of the line so far */
18 } GntTextLine;
19
8 static GntWidgetClass *parent_class = NULL; 20 static GntWidgetClass *parent_class = NULL;
9 static guint signals[SIGS] = { 0 }; 21 static guint signals[SIGS] = { 0 };
10 22
11 static void 23 static void
12 gnt_text_view_draw(GntWidget *widget) 24 gnt_text_view_draw(GntWidget *widget)
13 { 25 {
14 GntTextView *view = GNT_TEXT_VIEW(widget); 26 GntTextView *view = GNT_TEXT_VIEW(widget);
15 27 int i = 0;
16 copywin(view->scroll, widget->window, view->pos, 0, 0, 0, 28 GList *lines;
17 widget->priv.height - 1, widget->priv.width - 1, FALSE); 29
30 werase(widget->window);
31
32 for (i = 0, lines = view->list; i < widget->priv.height && lines; i++, lines = lines->next)
33 {
34 GList *iter;
35 GntTextLine *line = lines->data;
36
37 wmove(widget->window, widget->priv.height - 1 - i, 0);
38
39 for (iter = line->segments; iter; iter = iter->next)
40 {
41 GntTextSegment *seg = iter->data;
42 wattrset(widget->window, seg->flags);
43 wprintw(widget->window, "%s", seg->text);
44 if (!iter->next)
45 whline(widget->window, ' ' | seg->flags, widget->priv.width - line->length - 1);
46 }
47 }
18 48
19 DEBUG; 49 DEBUG;
20 } 50 }
21 51
22 static void 52 static void
41 { 71 {
42 return FALSE; 72 return FALSE;
43 } 73 }
44 74
45 static void 75 static void
76 free_text_segment(gpointer data, gpointer null)
77 {
78 GntTextSegment *seg = data;
79 g_free(seg->text);
80 g_free(seg);
81 }
82
83 static void
84 free_text_line(gpointer data, gpointer null)
85 {
86 GntTextLine *line = data;
87 g_list_foreach(line->segments, free_text_segment, NULL);
88 g_list_free(line->segments);
89 g_free(line);
90 }
91
92 static void
46 gnt_text_view_destroy(GntWidget *widget) 93 gnt_text_view_destroy(GntWidget *widget)
47 { 94 {
95 GntTextView *view = GNT_TEXT_VIEW(widget);
96 g_list_foreach(view->list, free_text_line, NULL);
97 g_list_free(view->list);
48 } 98 }
49 99
50 static void 100 static void
51 gnt_text_view_class_init(GntTextViewClass *klass) 101 gnt_text_view_class_init(GntTextViewClass *klass)
52 { 102 {
98 148
99 GntWidget *gnt_text_view_new() 149 GntWidget *gnt_text_view_new()
100 { 150 {
101 GntWidget *widget = g_object_new(GNT_TYPE_TEXTVIEW, NULL); 151 GntWidget *widget = g_object_new(GNT_TYPE_TEXTVIEW, NULL);
102 GntTextView *view = GNT_TEXT_VIEW(widget); 152 GntTextView *view = GNT_TEXT_VIEW(widget);
103 153 GntTextLine *line = g_new0(GntTextLine, 1);
104 view->scroll = newwin(255, widget->priv.width, widget->priv.y, widget->priv.x); 154
105 scrollok(view->scroll, TRUE);
106 wsetscrreg(view->scroll, 0, 254);
107 wbkgd(view->scroll, COLOR_PAIR(GNT_COLOR_NORMAL));
108 werase(view->scroll);
109 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER); 155 GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER);
156
157 view->list = g_list_append(view->list, line);
110 158
111 return widget; 159 return widget;
112 } 160 }
113 161
114 void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextViewFlags flags) 162 void gnt_text_view_append_text_with_flags(GntTextView *view, const char *text, GntTextViewFlags flags)
115 { 163 {
116 GntWidget *widget = GNT_WIDGET(view); 164 GntWidget *widget = GNT_WIDGET(view);
117 int fl = 0; 165 int fl = 0;
118 char **split; 166 char **split;
119 int i; 167 int i;
168 GList *list = view->list;
120 169
121 if (text == NULL || *text == '\0') 170 if (text == NULL || *text == '\0')
122 return; 171 return;
123 172
124 if (flags & GNT_TEXT_FLAG_BOLD) 173 if (flags & GNT_TEXT_FLAG_BOLD)
126 if (flags & GNT_TEXT_FLAG_UNDERLINE) 175 if (flags & GNT_TEXT_FLAG_UNDERLINE)
127 fl |= A_UNDERLINE; 176 fl |= A_UNDERLINE;
128 if (flags & GNT_TEXT_FLAG_BLINK) 177 if (flags & GNT_TEXT_FLAG_BLINK)
129 fl |= A_BLINK; 178 fl |= A_BLINK;
130 179
131 wattrset(view->scroll, fl | COLOR_PAIR(GNT_COLOR_NORMAL)); 180 if (flags & GNT_TEXT_FLAG_DIM)
181 fl |= (A_DIM | COLOR_PAIR(GNT_COLOR_DISABLED));
182 else if (flags & GNT_TEXT_FLAG_HIGHLIGHT)
183 fl |= (A_DIM | COLOR_PAIR(GNT_COLOR_HIGHLIGHT));
184 else
185 fl |= COLOR_PAIR(GNT_COLOR_NORMAL);
186
187 view->list = g_list_first(view->list);
132 188
133 split = g_strsplit(text, "\n", 0); 189 split = g_strsplit(text, "\n", 0);
134 for (i = 0; split[i + 1]; i++) 190 for (i = 0; split[i]; i++)
135 { 191 {
136 /* XXX: Do something if the strlen of split[i] is big 192 GntTextLine *line = view->list->data;
137 * enough to cause the text to wrap. */ 193 int len = g_utf8_strlen(split[i], -1);
138 wprintw(view->scroll, "%s\n", split[i]); 194 char *iter = split[i];
139 view->lines++; 195 int prev = 0;
140 } 196
141 wprintw(view->scroll, "%s", split[i]); 197 while (iter && *iter)
198 {
199 GntTextSegment *seg = g_new0(GntTextSegment, 1);
200 seg->flags = fl;
201 seg->text = g_new0(char, len); /* XXX: MUST be improved */
202 g_utf8_strncpy(seg->text, iter, widget->priv.width - line->length - 1);
203 line->segments = g_list_append(line->segments, seg);
204
205 prev = g_utf8_strlen(seg->text, -1);
206 line->length += prev;
207 iter = g_utf8_offset_to_pointer(iter, prev);
208 if (line->length >= widget->priv.width - 1 && *iter)
209 {
210 line = g_new0(GntTextLine, 1);
211 view->list = g_list_prepend(g_list_first(view->list), line);
212 }
213 /*len -= prev;*/
214 }
215 }
216
142 g_strfreev(split); 217 g_strfreev(split);
218 view->list = list;
143 219
144 gnt_widget_draw(widget); 220 gnt_widget_draw(widget);
145 } 221 }
146 222
147 void gnt_text_view_scroll(GntTextView *view, int scroll) 223 void gnt_text_view_scroll(GntTextView *view, int scroll)
148 { 224 {
149 GntWidget *widget = GNT_WIDGET(view);
150 int height;
151
152 if (scroll == 0) 225 if (scroll == 0)
153 { 226 {
154 view->pos = view->lines - widget->priv.height + 1; 227 view->list = g_list_first(view->list);
155 } 228 }
156 else 229 else if (scroll > 0)
157 { 230 {
158 view->pos += scroll; 231 GList *list = g_list_nth_prev(view->list, scroll);
159 } 232 if (list == NULL)
160 233 list = g_list_first(view->list);
161 if (view->pos + (height = widget->priv.height) > view->lines) 234 view->list = list;
162 view->pos = view->lines - height + 1; 235 }
163 236 else if (scroll < 0)
164 if (view->pos < 0) 237 {
165 view->pos = 0; 238 GList *list = g_list_nth(view->list, -scroll);
166 239 if (list == NULL)
240 list = g_list_last(view->list);
241 view->list = list;
242 }
243
167 gnt_widget_draw(GNT_WIDGET(view)); 244 gnt_widget_draw(GNT_WIDGET(view));
168 } 245 }
169 246
170 void gnt_text_view_next_line(GntTextView *view) 247 void gnt_text_view_next_line(GntTextView *view)
171 { 248 {
172 wclrtoeol(view->scroll); 249 GntTextLine *line = g_new0(GntTextLine, 1);
173 gnt_text_view_append_text_with_flags(view, "\n", 0); 250 GList *list = view->list;
174 } 251
175 252 view->list = g_list_prepend(g_list_first(view->list), line);
253 view->list = list;
254 gnt_widget_draw(GNT_WIDGET(view));
255 }
256

mercurial