ui/gtk/text.c

changeset 103
6606616eca9f
parent 100
d2bd73d28ff1
child 108
77254bd6dccb
--- a/ui/gtk/text.c	Tue Feb 25 21:11:00 2025 +0100
+++ b/ui/gtk/text.c	Sat Apr 05 16:46:11 2025 +0200
@@ -62,6 +62,51 @@
     }
 }
 
+static void textarea_set_text_funcs(UiText *value) {
+    
+}
+
+#if GTK_MAJOR_VERSION == 2
+static void textarea_set_undomgr(GtkWidget *text_area, UiText *value) {
+    GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area));
+
+    if(!value->data2) {
+        value->data2 = ui_create_undomgr();
+    }
+
+    // register undo manager
+    g_signal_connect(
+            buf,
+            "insert-text",
+            G_CALLBACK(ui_textbuf_insert),
+            var);
+    g_signal_connect(
+            buf,
+            "delete-range",
+            G_CALLBACK(ui_textbuf_delete),
+            var); 
+    g_signal_connect(
+            buf,
+            "mark-set",
+            G_CALLBACK(selection_handler),
+            uitext);
+}
+#endif
+
+static GtkTextBuffer* create_textbuffer(UiTextArea *textarea) {
+    GtkTextBuffer *buf = gtk_text_buffer_new(NULL);
+    if(textarea) {
+        g_signal_connect(
+                buf,
+                "changed",
+                G_CALLBACK(ui_textbuf_changed),
+                textarea);
+    } else {
+        fprintf(stderr, "Error: create_textbuffer: textarea == NULL\n");
+    }
+    return buf;
+}
+
 UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs args) {
     UiObject* current = uic_current_obj(obj);
     UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_TEXT);
@@ -85,6 +130,8 @@
     uitext->onchange = args.onchange;
     uitext->onchangedata = args.onchangedata;
     
+    g_object_set_data(G_OBJECT(text_area), "ui_textarea", uitext);
+    
     g_signal_connect(
                 text_area,
                 "destroy",
@@ -114,13 +161,21 @@
     // bind value
     if(var) {
         UiText *value = var->value;
-        GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area));
-        
-        if(value->value.ptr) {
-            gtk_text_buffer_set_text(buf, value->value.ptr, -1);
-            value->value.free(value->value.ptr);
+        GtkTextBuffer *buf;
+        if(value->data1 && value->datatype == UI_TEXT_TYPE_BUFFER) {
+            buf = value->data1;
+        } else {
+            buf = create_textbuffer(uitext);
+            if(value->value.ptr) {
+                gtk_text_buffer_set_text(buf, value->value.ptr, -1);
+                value->value.free(value->value.ptr);
+            }
         }
-        
+        gtk_text_view_set_buffer(GTK_TEXT_VIEW(text_area), buf);
+        value->obj = text_area;
+        value->save = ui_textarea_save;
+        value->restore = ui_textarea_restore;
+        value->destroy = ui_textarea_text_destroy;
         value->get = ui_textarea_get;
         value->set = ui_textarea_set;
         value->getsubstr = ui_textarea_getsubstr;
@@ -130,35 +185,15 @@
         value->selection = ui_textarea_selection;
         value->length = ui_textarea_length;
         value->remove = ui_textarea_remove;
+        value->data1 = buf;
+        value->data2 = NULL;
+        value->datatype == UI_TEXT_TYPE_BUFFER;
         value->value.ptr = NULL;
         value->value.free = NULL;
-        value->obj = buf;
-        if(!value->undomgr) {
-            value->undomgr = ui_create_undomgr();
-        }
         
-        g_signal_connect(
-                buf,
-                "changed",
-                G_CALLBACK(ui_textbuf_changed),
-                uitext);
-        
-        // register undo manager
-        g_signal_connect(
-                buf,
-                "insert-text",
-                G_CALLBACK(ui_textbuf_insert),
-                var);
-        g_signal_connect(
-                buf,
-                "delete-range",
-                G_CALLBACK(ui_textbuf_delete),
-                var); 
-        g_signal_connect(
-                buf,
-                "mark-set",
-                G_CALLBACK(selection_handler),
-                uitext);
+#if GTK_MAJOR_VERSION == 2
+        textarea_set_undomgr(text_area, value);
+#endif
     }
     
     return scroll_area;
@@ -175,11 +210,29 @@
     return SCROLLEDWINDOW_GET_CHILD(textarea);
 }
 
+void ui_textarea_save(UiText *text) {
+    // NOOP
+}
+
+void ui_textarea_restore(UiText *text) {
+    GtkWidget *textarea = text->obj;
+    if(!text->data1) {
+        text->data1 = create_textbuffer(g_object_get_data(G_OBJECT(textarea), "ui_textarea"));
+        text->datatype = UI_TEXT_TYPE_BUFFER;
+    }
+    gtk_text_view_set_buffer(GTK_TEXT_VIEW(textarea), text->data1);
+}
+
+void ui_textarea_text_destroy(UiText *text) {
+    GtkTextBuffer *buf = text->data1;
+    g_object_unref(buf);
+}
+
 char* ui_textarea_get(UiText *text) {
     if(text->value.ptr) {
         text->value.free(text->value.ptr);
     }
-    GtkTextBuffer *buf = text->obj;
+    GtkTextBuffer *buf = text->data1;
     GtkTextIter start;
     GtkTextIter end;
     gtk_text_buffer_get_bounds(buf, &start, &end);
@@ -190,7 +243,7 @@
 }
 
 void ui_textarea_set(UiText *text, const char *str) {
-    gtk_text_buffer_set_text((GtkTextBuffer*)text->obj, str, -1);
+    gtk_text_buffer_set_text((GtkTextBuffer*)text->data1, str, -1);
     if(text->value.ptr) {
         text->value.free(text->value.ptr);
     }
@@ -202,11 +255,11 @@
     if(text->value.ptr) {
         text->value.free(text->value.ptr);
     }
-    GtkTextBuffer *buf = text->obj;
+    GtkTextBuffer *buf = text->data1;
     GtkTextIter ib;
     GtkTextIter ie;
-    gtk_text_buffer_get_iter_at_offset(text->obj, &ib, begin);
-    gtk_text_buffer_get_iter_at_offset(text->obj, &ie, end);
+    gtk_text_buffer_get_iter_at_offset(text->data1, &ib, begin);
+    gtk_text_buffer_get_iter_at_offset(text->data1, &ie, end);
     char *str = gtk_text_buffer_get_text(buf, &ib, &ie, FALSE);
     text->value.ptr = g_strdup(str);
     text->value.free = (ui_freefunc)g_free;
@@ -215,8 +268,8 @@
 
 void ui_textarea_insert(UiText *text, int pos, char *str) {
     GtkTextIter offset;
-    gtk_text_buffer_get_iter_at_offset(text->obj, &offset, pos);
-    gtk_text_buffer_insert(text->obj, &offset, str, -1);
+    gtk_text_buffer_get_iter_at_offset(text->data1, &offset, pos);
+    gtk_text_buffer_insert(text->data1, &offset, str, -1);
     if(text->value.ptr) {
         text->value.free(text->value.ptr);
     }
@@ -226,14 +279,14 @@
 
 void ui_textarea_setposition(UiText *text, int pos) {
     GtkTextIter iter;
-    gtk_text_buffer_get_iter_at_offset(text->obj, &iter, pos);
-    gtk_text_buffer_place_cursor(text->obj, &iter);
+    gtk_text_buffer_get_iter_at_offset(text->data1, &iter, pos);
+    gtk_text_buffer_place_cursor(text->data1, &iter);
 }
 
 int ui_textarea_position(UiText *text) {
     GtkTextIter begin;
     GtkTextIter end;
-    gtk_text_buffer_get_selection_bounds(text->obj, &begin, &end);
+    gtk_text_buffer_get_selection_bounds(text->data1, &begin, &end);
     text->pos = gtk_text_iter_get_offset(&begin);
     return text->pos;
 }
@@ -241,13 +294,13 @@
 void ui_textarea_selection(UiText *text, int *begin, int *end) {
     GtkTextIter b;
     GtkTextIter e;
-    gtk_text_buffer_get_selection_bounds(text->obj, &b, &e);
+    gtk_text_buffer_get_selection_bounds(text->data1, &b, &e);
     *begin = gtk_text_iter_get_offset(&b);
     *end = gtk_text_iter_get_offset(&e);
 }
 
 int ui_textarea_length(UiText *text) {
-    GtkTextBuffer *buf = text->obj;
+    GtkTextBuffer *buf = text->data1;
     GtkTextIter start;
     GtkTextIter end;
     gtk_text_buffer_get_bounds(buf, &start, &end);
@@ -255,7 +308,7 @@
 }
 
 void ui_textarea_remove(UiText *text, int begin, int end) {
-    GtkTextBuffer *buf = text->obj;
+    GtkTextBuffer *buf = text->data1;
     GtkTextIter ib;
     GtkTextIter ie;
     gtk_text_buffer_get_iter_at_offset(buf, &ib, begin);
@@ -278,6 +331,7 @@
     e.document = textarea->ctx->document;
     e.eventdata = value;
     e.intval = 0;
+    e.set = ui_get_setop();
     
     if(textarea->onchange) {
         textarea->onchange(&e, textarea->onchangedata);
@@ -299,10 +353,10 @@
 {
     UiVar *var = data;
     UiText *value = var->value;
-    if(!value->undomgr) {
-        value->undomgr = ui_create_undomgr();
+    if(!value->data2) {
+        value->data2 = ui_create_undomgr();
     }
-    UiUndoMgr *mgr = value->undomgr;
+    UiUndoMgr *mgr = value->data2;
     if(!mgr->event) {
         return;
     }
@@ -371,10 +425,10 @@
 {
     UiVar *var = data;
     UiText *value = var->value;
-    if(!value->undomgr) {
-        value->undomgr = ui_create_undomgr();
+    if(!value->data2) {
+        value->data2 = ui_create_undomgr();
     }
-    UiUndoMgr *mgr = value->undomgr;
+    UiUndoMgr *mgr = value->data2;
     if(!mgr->event) {
         return;
     }
@@ -469,7 +523,7 @@
 }
 
 void ui_text_undo(UiText *value) {
-    UiUndoMgr *mgr = value->undomgr;
+    UiUndoMgr *mgr = value->data2;
     
     if(mgr->cur) {
         UiTextBufOp *op = mgr->cur;
@@ -498,7 +552,7 @@
 }
 
 void ui_text_redo(UiText *value) {
-    UiUndoMgr *mgr = value->undomgr;
+    UiUndoMgr *mgr = value->data2;
     
     UiTextBufOp *elm = NULL;
     if(mgr->cur) {
@@ -638,6 +692,7 @@
     e.document = textfield->obj->ctx->document;
     e.eventdata = value;
     e.intval = 0;
+    e.set = ui_get_setop();
     
     if(textfield->onchange) {
         textfield->onchange(&e, textfield->onchangedata);
@@ -656,6 +711,7 @@
         e.document = textfield->obj->ctx->document;
         e.eventdata = NULL;
         e.intval = 0;
+        e.set = ui_get_setop();
         textfield->onactivate(&e, textfield->onactivatedata);
     }
 }
@@ -752,6 +808,7 @@
     evt.document = evt.obj->ctx->document;
     evt.eventdata = elm->path;
     evt.intval = event->value0;
+    evt.set = ui_get_setop();
     event->callback(&evt, event->userdata);
     free(path.ptr);
 }

mercurial