| 60 } |
60 } |
| 61 textview->last_selection_state = sel; |
61 textview->last_selection_state = sel; |
| 62 } |
62 } |
| 63 } |
63 } |
| 64 |
64 |
| |
65 static void textarea_set_text_funcs(UiText *value) { |
| |
66 |
| |
67 } |
| |
68 |
| |
69 #if GTK_MAJOR_VERSION == 2 |
| |
70 static void textarea_set_undomgr(GtkWidget *text_area, UiText *value) { |
| |
71 GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area)); |
| |
72 |
| |
73 if(!value->data2) { |
| |
74 value->data2 = ui_create_undomgr(); |
| |
75 } |
| |
76 |
| |
77 // register undo manager |
| |
78 g_signal_connect( |
| |
79 buf, |
| |
80 "insert-text", |
| |
81 G_CALLBACK(ui_textbuf_insert), |
| |
82 var); |
| |
83 g_signal_connect( |
| |
84 buf, |
| |
85 "delete-range", |
| |
86 G_CALLBACK(ui_textbuf_delete), |
| |
87 var); |
| |
88 g_signal_connect( |
| |
89 buf, |
| |
90 "mark-set", |
| |
91 G_CALLBACK(selection_handler), |
| |
92 uitext); |
| |
93 } |
| |
94 #endif |
| |
95 |
| |
96 static GtkTextBuffer* create_textbuffer(UiTextArea *textarea) { |
| |
97 GtkTextBuffer *buf = gtk_text_buffer_new(NULL); |
| |
98 if(textarea) { |
| |
99 g_signal_connect( |
| |
100 buf, |
| |
101 "changed", |
| |
102 G_CALLBACK(ui_textbuf_changed), |
| |
103 textarea); |
| |
104 } else { |
| |
105 fprintf(stderr, "Error: create_textbuffer: textarea == NULL\n"); |
| |
106 } |
| |
107 return buf; |
| |
108 } |
| |
109 |
| 65 UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs args) { |
110 UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs args) { |
| 66 UiObject* current = uic_current_obj(obj); |
111 UiObject* current = uic_current_obj(obj); |
| 67 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_TEXT); |
112 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_TEXT); |
| 68 |
113 |
| 69 GtkWidget *text_area = gtk_text_view_new(); |
114 GtkWidget *text_area = gtk_text_view_new(); |
| 112 current->container->add(current->container, scroll_area, TRUE); |
159 current->container->add(current->container, scroll_area, TRUE); |
| 113 |
160 |
| 114 // bind value |
161 // bind value |
| 115 if(var) { |
162 if(var) { |
| 116 UiText *value = var->value; |
163 UiText *value = var->value; |
| 117 GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area)); |
164 GtkTextBuffer *buf; |
| 118 |
165 if(value->data1 && value->datatype == UI_TEXT_TYPE_BUFFER) { |
| 119 if(value->value.ptr) { |
166 buf = value->data1; |
| 120 gtk_text_buffer_set_text(buf, value->value.ptr, -1); |
167 } else { |
| 121 value->value.free(value->value.ptr); |
168 buf = create_textbuffer(uitext); |
| 122 } |
169 if(value->value.ptr) { |
| 123 |
170 gtk_text_buffer_set_text(buf, value->value.ptr, -1); |
| |
171 value->value.free(value->value.ptr); |
| |
172 } |
| |
173 } |
| |
174 gtk_text_view_set_buffer(GTK_TEXT_VIEW(text_area), buf); |
| |
175 value->obj = text_area; |
| |
176 value->save = ui_textarea_save; |
| |
177 value->restore = ui_textarea_restore; |
| |
178 value->destroy = ui_textarea_text_destroy; |
| 124 value->get = ui_textarea_get; |
179 value->get = ui_textarea_get; |
| 125 value->set = ui_textarea_set; |
180 value->set = ui_textarea_set; |
| 126 value->getsubstr = ui_textarea_getsubstr; |
181 value->getsubstr = ui_textarea_getsubstr; |
| 127 value->insert = ui_textarea_insert; |
182 value->insert = ui_textarea_insert; |
| 128 value->setposition = ui_textarea_setposition; |
183 value->setposition = ui_textarea_setposition; |
| 129 value->position = ui_textarea_position; |
184 value->position = ui_textarea_position; |
| 130 value->selection = ui_textarea_selection; |
185 value->selection = ui_textarea_selection; |
| 131 value->length = ui_textarea_length; |
186 value->length = ui_textarea_length; |
| 132 value->remove = ui_textarea_remove; |
187 value->remove = ui_textarea_remove; |
| |
188 value->data1 = buf; |
| |
189 value->data2 = NULL; |
| |
190 value->datatype == UI_TEXT_TYPE_BUFFER; |
| 133 value->value.ptr = NULL; |
191 value->value.ptr = NULL; |
| 134 value->value.free = NULL; |
192 value->value.free = NULL; |
| 135 value->obj = buf; |
|
| 136 if(!value->undomgr) { |
|
| 137 value->undomgr = ui_create_undomgr(); |
|
| 138 } |
|
| 139 |
193 |
| 140 g_signal_connect( |
194 #if GTK_MAJOR_VERSION == 2 |
| 141 buf, |
195 textarea_set_undomgr(text_area, value); |
| 142 "changed", |
196 #endif |
| 143 G_CALLBACK(ui_textbuf_changed), |
|
| 144 uitext); |
|
| 145 |
|
| 146 // register undo manager |
|
| 147 g_signal_connect( |
|
| 148 buf, |
|
| 149 "insert-text", |
|
| 150 G_CALLBACK(ui_textbuf_insert), |
|
| 151 var); |
|
| 152 g_signal_connect( |
|
| 153 buf, |
|
| 154 "delete-range", |
|
| 155 G_CALLBACK(ui_textbuf_delete), |
|
| 156 var); |
|
| 157 g_signal_connect( |
|
| 158 buf, |
|
| 159 "mark-set", |
|
| 160 G_CALLBACK(selection_handler), |
|
| 161 uitext); |
|
| 162 } |
197 } |
| 163 |
198 |
| 164 return scroll_area; |
199 return scroll_area; |
| 165 } |
200 } |
| 166 |
201 |
| 173 |
208 |
| 174 UIWIDGET ui_textarea_gettextwidget(UIWIDGET textarea) { |
209 UIWIDGET ui_textarea_gettextwidget(UIWIDGET textarea) { |
| 175 return SCROLLEDWINDOW_GET_CHILD(textarea); |
210 return SCROLLEDWINDOW_GET_CHILD(textarea); |
| 176 } |
211 } |
| 177 |
212 |
| |
213 void ui_textarea_save(UiText *text) { |
| |
214 // NOOP |
| |
215 } |
| |
216 |
| |
217 void ui_textarea_restore(UiText *text) { |
| |
218 GtkWidget *textarea = text->obj; |
| |
219 if(!text->data1) { |
| |
220 text->data1 = create_textbuffer(g_object_get_data(G_OBJECT(textarea), "ui_textarea")); |
| |
221 text->datatype = UI_TEXT_TYPE_BUFFER; |
| |
222 } |
| |
223 gtk_text_view_set_buffer(GTK_TEXT_VIEW(textarea), text->data1); |
| |
224 } |
| |
225 |
| |
226 void ui_textarea_text_destroy(UiText *text) { |
| |
227 GtkTextBuffer *buf = text->data1; |
| |
228 g_object_unref(buf); |
| |
229 } |
| |
230 |
| 178 char* ui_textarea_get(UiText *text) { |
231 char* ui_textarea_get(UiText *text) { |
| 179 if(text->value.ptr) { |
232 if(text->value.ptr) { |
| 180 text->value.free(text->value.ptr); |
233 text->value.free(text->value.ptr); |
| 181 } |
234 } |
| 182 GtkTextBuffer *buf = text->obj; |
235 GtkTextBuffer *buf = text->data1; |
| 183 GtkTextIter start; |
236 GtkTextIter start; |
| 184 GtkTextIter end; |
237 GtkTextIter end; |
| 185 gtk_text_buffer_get_bounds(buf, &start, &end); |
238 gtk_text_buffer_get_bounds(buf, &start, &end); |
| 186 char *str = gtk_text_buffer_get_text(buf, &start, &end, FALSE); |
239 char *str = gtk_text_buffer_get_text(buf, &start, &end, FALSE); |
| 187 text->value.ptr = g_strdup(str); |
240 text->value.ptr = g_strdup(str); |
| 188 text->value.free = (ui_freefunc)g_free; |
241 text->value.free = (ui_freefunc)g_free; |
| 189 return str; |
242 return str; |
| 190 } |
243 } |
| 191 |
244 |
| 192 void ui_textarea_set(UiText *text, const char *str) { |
245 void ui_textarea_set(UiText *text, const char *str) { |
| 193 gtk_text_buffer_set_text((GtkTextBuffer*)text->obj, str, -1); |
246 gtk_text_buffer_set_text((GtkTextBuffer*)text->data1, str, -1); |
| 194 if(text->value.ptr) { |
247 if(text->value.ptr) { |
| 195 text->value.free(text->value.ptr); |
248 text->value.free(text->value.ptr); |
| 196 } |
249 } |
| 197 text->value.ptr = NULL; |
250 text->value.ptr = NULL; |
| 198 text->value.free = NULL; |
251 text->value.free = NULL; |
| 200 |
253 |
| 201 char* ui_textarea_getsubstr(UiText *text, int begin, int end) { |
254 char* ui_textarea_getsubstr(UiText *text, int begin, int end) { |
| 202 if(text->value.ptr) { |
255 if(text->value.ptr) { |
| 203 text->value.free(text->value.ptr); |
256 text->value.free(text->value.ptr); |
| 204 } |
257 } |
| 205 GtkTextBuffer *buf = text->obj; |
258 GtkTextBuffer *buf = text->data1; |
| 206 GtkTextIter ib; |
259 GtkTextIter ib; |
| 207 GtkTextIter ie; |
260 GtkTextIter ie; |
| 208 gtk_text_buffer_get_iter_at_offset(text->obj, &ib, begin); |
261 gtk_text_buffer_get_iter_at_offset(text->data1, &ib, begin); |
| 209 gtk_text_buffer_get_iter_at_offset(text->obj, &ie, end); |
262 gtk_text_buffer_get_iter_at_offset(text->data1, &ie, end); |
| 210 char *str = gtk_text_buffer_get_text(buf, &ib, &ie, FALSE); |
263 char *str = gtk_text_buffer_get_text(buf, &ib, &ie, FALSE); |
| 211 text->value.ptr = g_strdup(str); |
264 text->value.ptr = g_strdup(str); |
| 212 text->value.free = (ui_freefunc)g_free; |
265 text->value.free = (ui_freefunc)g_free; |
| 213 return str; |
266 return str; |
| 214 } |
267 } |
| 215 |
268 |
| 216 void ui_textarea_insert(UiText *text, int pos, char *str) { |
269 void ui_textarea_insert(UiText *text, int pos, char *str) { |
| 217 GtkTextIter offset; |
270 GtkTextIter offset; |
| 218 gtk_text_buffer_get_iter_at_offset(text->obj, &offset, pos); |
271 gtk_text_buffer_get_iter_at_offset(text->data1, &offset, pos); |
| 219 gtk_text_buffer_insert(text->obj, &offset, str, -1); |
272 gtk_text_buffer_insert(text->data1, &offset, str, -1); |
| 220 if(text->value.ptr) { |
273 if(text->value.ptr) { |
| 221 text->value.free(text->value.ptr); |
274 text->value.free(text->value.ptr); |
| 222 } |
275 } |
| 223 text->value.ptr = NULL; |
276 text->value.ptr = NULL; |
| 224 text->value.free = NULL; |
277 text->value.free = NULL; |
| 225 } |
278 } |
| 226 |
279 |
| 227 void ui_textarea_setposition(UiText *text, int pos) { |
280 void ui_textarea_setposition(UiText *text, int pos) { |
| 228 GtkTextIter iter; |
281 GtkTextIter iter; |
| 229 gtk_text_buffer_get_iter_at_offset(text->obj, &iter, pos); |
282 gtk_text_buffer_get_iter_at_offset(text->data1, &iter, pos); |
| 230 gtk_text_buffer_place_cursor(text->obj, &iter); |
283 gtk_text_buffer_place_cursor(text->data1, &iter); |
| 231 } |
284 } |
| 232 |
285 |
| 233 int ui_textarea_position(UiText *text) { |
286 int ui_textarea_position(UiText *text) { |
| 234 GtkTextIter begin; |
287 GtkTextIter begin; |
| 235 GtkTextIter end; |
288 GtkTextIter end; |
| 236 gtk_text_buffer_get_selection_bounds(text->obj, &begin, &end); |
289 gtk_text_buffer_get_selection_bounds(text->data1, &begin, &end); |
| 237 text->pos = gtk_text_iter_get_offset(&begin); |
290 text->pos = gtk_text_iter_get_offset(&begin); |
| 238 return text->pos; |
291 return text->pos; |
| 239 } |
292 } |
| 240 |
293 |
| 241 void ui_textarea_selection(UiText *text, int *begin, int *end) { |
294 void ui_textarea_selection(UiText *text, int *begin, int *end) { |
| 242 GtkTextIter b; |
295 GtkTextIter b; |
| 243 GtkTextIter e; |
296 GtkTextIter e; |
| 244 gtk_text_buffer_get_selection_bounds(text->obj, &b, &e); |
297 gtk_text_buffer_get_selection_bounds(text->data1, &b, &e); |
| 245 *begin = gtk_text_iter_get_offset(&b); |
298 *begin = gtk_text_iter_get_offset(&b); |
| 246 *end = gtk_text_iter_get_offset(&e); |
299 *end = gtk_text_iter_get_offset(&e); |
| 247 } |
300 } |
| 248 |
301 |
| 249 int ui_textarea_length(UiText *text) { |
302 int ui_textarea_length(UiText *text) { |
| 250 GtkTextBuffer *buf = text->obj; |
303 GtkTextBuffer *buf = text->data1; |
| 251 GtkTextIter start; |
304 GtkTextIter start; |
| 252 GtkTextIter end; |
305 GtkTextIter end; |
| 253 gtk_text_buffer_get_bounds(buf, &start, &end); |
306 gtk_text_buffer_get_bounds(buf, &start, &end); |
| 254 return gtk_text_iter_get_offset(&end); |
307 return gtk_text_iter_get_offset(&end); |
| 255 } |
308 } |
| 256 |
309 |
| 257 void ui_textarea_remove(UiText *text, int begin, int end) { |
310 void ui_textarea_remove(UiText *text, int begin, int end) { |
| 258 GtkTextBuffer *buf = text->obj; |
311 GtkTextBuffer *buf = text->data1; |
| 259 GtkTextIter ib; |
312 GtkTextIter ib; |
| 260 GtkTextIter ie; |
313 GtkTextIter ie; |
| 261 gtk_text_buffer_get_iter_at_offset(buf, &ib, begin); |
314 gtk_text_buffer_get_iter_at_offset(buf, &ib, begin); |
| 262 gtk_text_buffer_get_iter_at_offset(buf, &ie, end); |
315 gtk_text_buffer_get_iter_at_offset(buf, &ie, end); |
| 263 gtk_text_buffer_delete(buf, &ib, &ie); |
316 gtk_text_buffer_delete(buf, &ib, &ie); |