| 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 |