1 /* |
1 /* |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 * |
3 * |
4 * Copyright 2014 Olaf Wintermann. All rights reserved. |
4 * Copyright 2017 Olaf Wintermann. All rights reserved. |
5 * |
5 * |
6 * Redistribution and use in source and binary forms, with or without |
6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions are met: |
7 * modification, are permitted provided that the following conditions are met: |
8 * |
8 * |
9 * 1. Redistributions of source code must retain the above copyright |
9 * 1. Redistributions of source code must retain the above copyright |
55 } |
54 } |
56 textview->last_selection_state = sel; |
55 textview->last_selection_state = sel; |
57 } |
56 } |
58 } |
57 } |
59 |
58 |
60 UIWIDGET ui_textarea(UiObject *obj, UiText *value) { |
59 UIWIDGET ui_textarea_var(UiObject *obj, UiVar *var) { |
61 GtkWidget *text_area = gtk_text_view_new(); |
60 GtkWidget *text_area = gtk_text_view_new(); |
62 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_area), GTK_WRAP_WORD_CHAR); |
61 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_area), GTK_WRAP_WORD_CHAR); |
63 g_signal_connect( |
62 g_signal_connect( |
64 text_area, |
63 text_area, |
65 "realize", |
64 "realize", |
66 G_CALLBACK(ui_textarea_realize_event), |
65 G_CALLBACK(ui_textarea_realize_event), |
67 NULL); |
66 NULL); |
|
67 |
|
68 UiTextArea *uitext = malloc(sizeof(UiTextArea)); |
|
69 uitext->ctx = obj->ctx; |
|
70 uitext->var = var; |
|
71 uitext->last_selection_state = 0; |
|
72 |
68 g_signal_connect( |
73 g_signal_connect( |
69 text_area, |
74 text_area, |
70 "selection-clear-event", |
75 "destroy", |
71 G_CALLBACK(selection_handler), |
76 G_CALLBACK(ui_textarea_destroy), |
72 NULL); |
77 uitext); |
73 |
|
74 UiTextArea *uitext = ucx_mempool_malloc( |
|
75 obj->ctx->mempool, |
|
76 sizeof(UiTextArea)); |
|
77 uitext->ctx = obj->ctx; |
|
78 uitext->last_selection_state = 0; |
|
79 |
78 |
80 GtkWidget *scroll_area = gtk_scrolled_window_new (NULL, NULL); |
79 GtkWidget *scroll_area = gtk_scrolled_window_new (NULL, NULL); |
81 gtk_scrolled_window_set_policy( |
80 gtk_scrolled_window_set_policy( |
82 GTK_SCROLLED_WINDOW(scroll_area), |
81 GTK_SCROLLED_WINDOW(scroll_area), |
83 GTK_POLICY_AUTOMATIC, |
82 GTK_POLICY_AUTOMATIC, |
96 // add |
95 // add |
97 UiContainer *ct = uic_get_current_container(obj); |
96 UiContainer *ct = uic_get_current_container(obj); |
98 ct->add(ct, scroll_area, TRUE); |
97 ct->add(ct, scroll_area, TRUE); |
99 |
98 |
100 // bind value |
99 // bind value |
|
100 UiText *value = var->value; |
101 if(value) { |
101 if(value) { |
102 GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area)); |
102 GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area)); |
103 |
103 |
104 if(value->value) { |
104 if(value->value) { |
105 gtk_text_buffer_set_text(buf, value->value, -1); |
105 gtk_text_buffer_set_text(buf, value->value, -1); |
124 // register undo manager |
124 // register undo manager |
125 g_signal_connect( |
125 g_signal_connect( |
126 buf, |
126 buf, |
127 "insert-text", |
127 "insert-text", |
128 G_CALLBACK(ui_textbuf_insert), |
128 G_CALLBACK(ui_textbuf_insert), |
129 value); |
129 var); |
130 g_signal_connect( |
130 g_signal_connect( |
131 buf, |
131 buf, |
132 "delete-range", |
132 "delete-range", |
133 G_CALLBACK(ui_textbuf_delete), |
133 G_CALLBACK(ui_textbuf_delete), |
134 value); |
134 var); |
135 |
135 |
136 g_signal_connect( |
136 g_signal_connect( |
137 buf, |
137 buf, |
138 "mark-set", |
138 "mark-set", |
139 G_CALLBACK(selection_handler), |
139 G_CALLBACK(selection_handler), |
141 } |
141 } |
142 |
142 |
143 return scroll_area; |
143 return scroll_area; |
144 } |
144 } |
145 |
145 |
|
146 void ui_textarea_destroy(GtkWidget *object, UiTextArea *textarea) { |
|
147 ui_destroy_boundvar(textarea->ctx, textarea->var); |
|
148 free(textarea); |
|
149 } |
|
150 |
|
151 UIWIDGET ui_textarea(UiObject *obj, UiText *value) { |
|
152 UiVar *var = NULL; |
|
153 if(value) { |
|
154 var = malloc(sizeof(UiVar)); |
|
155 var->value = value; |
|
156 var->type = UI_VAR_SPECIAL; |
|
157 } |
|
158 return ui_textarea_var(obj, var); |
|
159 } |
|
160 |
146 UIWIDGET ui_textarea_nv(UiObject *obj, char *varname) { |
161 UIWIDGET ui_textarea_nv(UiObject *obj, char *varname) { |
147 UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_TEXT); |
162 UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_TEXT); |
148 if(var) { |
163 if(var) { |
149 UiText *value = var->value; |
164 return ui_textarea_var(obj, var); |
150 return ui_textarea(obj, value); |
|
151 } else { |
165 } else { |
152 // TODO: error |
166 // TODO: error |
153 } |
167 } |
154 return NULL; |
168 return NULL; |
155 } |
169 } |
166 text->value = str; |
180 text->value = str; |
167 return str; |
181 return str; |
168 } |
182 } |
169 |
183 |
170 void ui_textarea_set(UiText *text, char *str) { |
184 void ui_textarea_set(UiText *text, char *str) { |
|
185 gtk_text_buffer_set_text((GtkTextBuffer*)text->obj, str, -1); |
171 if(text->value) { |
186 if(text->value) { |
172 g_free(text->value); |
187 g_free(text->value); |
173 } |
188 } |
174 text->value = NULL; |
189 text->value = NULL; |
175 gtk_text_buffer_set_text((GtkTextBuffer*)text->obj, str, -1); |
|
176 } |
190 } |
177 |
191 |
178 char* ui_textarea_getsubstr(UiText *text, int begin, int end) { |
192 char* ui_textarea_getsubstr(UiText *text, int begin, int end) { |
179 if(text->value) { |
193 if(text->value) { |
180 g_free(text->value); |
194 g_free(text->value); |
240 |
254 |
241 void ui_textarea_realize_event(GtkWidget *widget, gpointer data) { |
255 void ui_textarea_realize_event(GtkWidget *widget, gpointer data) { |
242 gtk_widget_grab_focus(widget); |
256 gtk_widget_grab_focus(widget); |
243 } |
257 } |
244 |
258 |
245 void ui_text_set(UiText *text, char *str) { |
259 |
246 if(text->set) { |
|
247 text->set(text, str); |
|
248 } else { |
|
249 if(text->value) { |
|
250 g_free(text->value); |
|
251 } |
|
252 text->value = g_strdup(str); |
|
253 } |
|
254 } |
|
255 |
|
256 char* ui_text_get(UiText *text) { |
|
257 if(text->get) { |
|
258 return text->get(text); |
|
259 } else { |
|
260 return text->value; |
|
261 } |
|
262 } |
|
263 |
260 |
264 |
261 |
265 // undo manager functions |
262 // undo manager functions |
266 |
263 |
267 void ui_textbuf_insert( |
264 void ui_textbuf_insert( |
472 mgr->cur = elm; |
477 mgr->cur = elm; |
473 } |
478 } |
474 } |
479 } |
475 |
480 |
476 |
481 |
477 static UIWIDGET create_textfield(UiObject *obj, int width, UiBool frameless, UiBool password, UiString *value) { |
482 static UIWIDGET create_textfield_var(UiObject *obj, int width, UiBool frameless, UiBool password, UiVar *var) { |
478 GtkWidget *textfield = gtk_entry_new(); |
483 GtkWidget *textfield = gtk_entry_new(); |
|
484 |
|
485 UiTextField *uitext = malloc(sizeof(UiTextField)); |
|
486 uitext->ctx = obj->ctx; |
|
487 uitext->var = var; |
|
488 |
|
489 g_signal_connect( |
|
490 textfield, |
|
491 "destroy", |
|
492 G_CALLBACK(ui_textfield_destroy), |
|
493 uitext); |
|
494 |
479 if(width > 0) { |
495 if(width > 0) { |
480 gtk_entry_set_width_chars(GTK_ENTRY(textfield), width); |
496 gtk_entry_set_width_chars(GTK_ENTRY(textfield), width); |
481 } |
497 } |
482 if(frameless) { |
498 if(frameless) { |
483 // TODO: gtk2legacy workaroud |
499 // TODO: gtk2legacy workaroud |
488 } |
504 } |
489 |
505 |
490 UiContainer *ct = uic_get_current_container(obj); |
506 UiContainer *ct = uic_get_current_container(obj); |
491 ct->add(ct, textfield, FALSE); |
507 ct->add(ct, textfield, FALSE); |
492 |
508 |
493 if(value) { |
509 if(var) { |
|
510 UiString *value = var->value; |
494 if(value->value) { |
511 if(value->value) { |
495 gtk_entry_set_text(GTK_ENTRY(textfield), value->value); |
512 gtk_entry_set_text(GTK_ENTRY(textfield), value->value); |
496 g_free(value->value); |
513 g_free(value->value); |
497 // TODO: free value |
514 value->value = NULL; |
498 } |
515 } |
499 |
516 |
500 value->get = ui_textfield_get; |
517 value->get = ui_textfield_get; |
501 value->set = ui_textfield_set; |
518 value->set = ui_textfield_set; |
502 value->value = NULL; |
519 value->value = NULL; |
505 |
522 |
506 return textfield; |
523 return textfield; |
507 } |
524 } |
508 |
525 |
509 static UIWIDGET create_textfield_nv(UiObject *obj, int width, UiBool frameless, UiBool password, char *varname) { |
526 static UIWIDGET create_textfield_nv(UiObject *obj, int width, UiBool frameless, UiBool password, char *varname) { |
510 UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_STRING); |
527 UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_STRING); |
511 if(var) { |
528 if(var) { |
512 UiString *value = var->value; |
529 return create_textfield_var(obj, width, frameless, password, var); |
513 return create_textfield(obj, width, frameless, password, value); |
|
514 } else { |
530 } else { |
515 // TODO: error |
531 // TODO: error |
516 } |
532 } |
517 return NULL; |
533 return NULL; |
|
534 } |
|
535 |
|
536 static UIWIDGET create_textfield(UiObject *obj, int width, UiBool frameless, UiBool password, UiString *value) { |
|
537 UiVar *var = NULL; |
|
538 if(value) { |
|
539 var = malloc(sizeof(UiVar)); |
|
540 var->value = value; |
|
541 var->type = UI_VAR_SPECIAL; |
|
542 } |
|
543 return create_textfield_var(obj, width, frameless, password, var); |
|
544 } |
|
545 |
|
546 void ui_textfield_destroy(GtkWidget *object, UiTextField *textfield) { |
|
547 ui_destroy_boundvar(textfield->ctx, textfield->var); |
|
548 free(textfield); |
518 } |
549 } |
519 |
550 |
520 UIWIDGET ui_textfield(UiObject *obj, UiString *value) { |
551 UIWIDGET ui_textfield(UiObject *obj, UiString *value) { |
521 return create_textfield(obj, 0, FALSE, FALSE, value); |
552 return create_textfield(obj, 0, FALSE, FALSE, value); |
522 } |
553 } |