ui/gtk/text.c

changeset 140
c03c338a7dcf
parent 131
774b741984a2
child 141
cc2170ea05ad
equal deleted inserted replaced
139:dbde25a5bc53 140:c03c338a7dcf
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
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.h> 31 #include <string.h>
32 32
33 #include "text.h" 33 #include "text.h"
34 #include "container.h" 34 #include "container.h"
35 #include "../common/context.h" 35
36 #include "../common/document.h"
37 36
38 static void selection_handler( 37 static void selection_handler(
39 GtkTextBuffer *buf, 38 GtkTextBuffer *buf,
40 GtkTextIter *location, 39 GtkTextIter *location,
41 GtkTextMark *mark, 40 GtkTextMark *mark,
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(
269 GtkTextIter *location, 266 GtkTextIter *location,
270 char *text, 267 char *text,
271 int length, 268 int length,
272 void *data) 269 void *data)
273 { 270 {
274 UiText *value = data; 271 UiVar *var = data;
272 UiText *value = var->value;
273 if(!value->undomgr) {
274 value->undomgr = ui_create_undomgr();
275 }
275 UiUndoMgr *mgr = value->undomgr; 276 UiUndoMgr *mgr = value->undomgr;
276 if(!mgr->event) { 277 if(!mgr->event) {
277 return; 278 return;
278 } 279 }
279 280
330 GtkTextBuffer *textbuffer, 331 GtkTextBuffer *textbuffer,
331 GtkTextIter *start, 332 GtkTextIter *start,
332 GtkTextIter *end, 333 GtkTextIter *end,
333 void *data) 334 void *data)
334 { 335 {
335 UiText *value = data; 336 UiVar *var = data;
337 UiText *value = var->value;
338 if(!value->undomgr) {
339 value->undomgr = ui_create_undomgr();
340 }
336 UiUndoMgr *mgr = value->undomgr; 341 UiUndoMgr *mgr = value->undomgr;
337 if(!mgr->event) { 342 if(!mgr->event) {
338 return; 343 return;
339 } 344 }
340 345
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 }

mercurial