implement table/listview actions for gtk3

Sun, 07 Jun 2026 13:11:09 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 07 Jun 2026 13:11:09 +0200
changeset 1179
2f4c73ff962f
parent 1177
e5e5c1779294
child 1180
9f3b4129631f

implement table/listview actions for gtk3

application/main.c file | annotate | diff | comparison | revisions
ui/gtk/list.c file | annotate | diff | comparison | revisions
ui/gtk/list.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Sat Jun 06 18:47:45 2026 +0200
+++ b/application/main.c	Sun Jun 07 13:11:09 2026 +0200
@@ -309,6 +309,14 @@
     ui_show(obj);
 }
 
+void action_table_activate(UiEvent *event, void *data) {
+    printf("action: table activate\n");
+}
+
+void action_table_selection(UiEvent *event, void *data) {
+    printf("action: table selection\n");
+}
+
 static void mydoc_action_save(UiEvent *event, void *data) {
     printf("mydoc action save\n");
     
@@ -318,6 +326,9 @@
 MyDocument* create_doc(void) {
     MyDocument *doc = ui_document_new(sizeof(MyDocument));
     UiContext *docctx = ui_document_context(doc);
+    ui_add_action(docctx, "table_activate", action_table_activate, NULL);
+    ui_add_action(docctx, "table_selection", action_table_selection, NULL);
+    
     ui_add_action(docctx, "save", mydoc_action_save, NULL);
     doc->submenulist = ui_list_new(docctx, "sub_menulist");
     ui_list_append(doc->submenulist, "Sub Menu List Item 1");
@@ -470,7 +481,7 @@
     }
 }
 
-void action_table_activate(UiEvent *event, void *userdata) {
+void table_activate(UiEvent *event, void *userdata) {
     char *s = userdata;
     printf("table event: %s\n", s);
     UiListSelection *sel = event->eventdata;
@@ -762,8 +773,8 @@
             doc->model = model;
             ui_table(obj, .model = model, .list = doc->list2, .colspan = 2, .fill = TRUE, .contextmenu = menubuilder, .multiselection = TRUE, .fill = TRUE,
                     .getvalue = table_getvalue, .getstyle = table_getstyle, .onsave = list_save,
-                    .onactivate = action_table_activate, .onactivatedata = "activate",
-                    .onselection = action_table_activate, .onselectiondata = "selection");
+                    .onactivate = table_activate, .onactivatedata = "activate", .onactivate_action = "table_activate",
+                    .onselection = table_activate, .onselectiondata = "selection", .onselection_action = "table_selection");
             ui_hbox(obj, .fill = FALSE, .columnspacing = 4) {
                 ui_textfield(obj, .value = doc->list_input);
                 ui_button(obj, .label = "Update List Item 1", .onclick = action_update_list);
--- a/ui/gtk/list.c	Sat Jun 06 18:47:45 2026 +0200
+++ b/ui/gtk/list.c	Sun Jun 07 13:11:09 2026 +0200
@@ -1259,6 +1259,11 @@
     return store;
 }
 
+static void ui_destroy_tree_eventdata(GtkWidget *object, UiTreeEventData *data) {
+    free(data->activate_action);
+    free(data->selection_action);
+    free(data);
+}
 
 UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) {
     // create treeview
@@ -1316,22 +1321,23 @@
     event->obj = obj;
     event->activate = args->onactivate;
     event->activatedata = args->onactivatedata;
+    event->activate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
     event->selection = args->onselection;
     event->selectiondata = args->onselectiondata;
+    event->selection_action = args->onselection_action ? strdup(args->onselection_action) : NULL;
     g_signal_connect(
             view,
             "destroy",
-            G_CALLBACK(ui_destroy_userdata),
+            G_CALLBACK(ui_destroy_tree_eventdata),
             event);
-    
-    if(args->onactivate) {
+    if(args->onactivate || args->onactivate_action) {
         g_signal_connect(
                 view,
                 "row-activated",
                 G_CALLBACK(ui_listview_activate_event),
                 event);
     }
-    if(args->onselection) {
+    if(args->onselection || args->onselection_action) {
         GtkTreeSelection *selection = gtk_tree_view_get_selection(
                 GTK_TREE_VIEW(view));
         g_signal_connect(
@@ -1543,20 +1549,27 @@
     list->obj = tableview;
     
     // add callback
-    UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData));
+    UiTreeEventData *event = malloc(sizeof(UiTreeEventData));
     event->obj = obj;
     event->activate = args->onactivate;
+    event->activatedata = args->onactivatedata;
+    event->activate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
     event->selection = args->onselection;
-    event->activatedata = args->onactivatedata;
     event->selectiondata = args->onselectiondata;
-    if(args->onactivate) {
+    event->selection_action = args->onselection_action ? strdup(args->onselection_action) : NULL;
+    g_signal_connect(
+            view,
+            "destroy",
+            G_CALLBACK(ui_destroy_tree_eventdata),
+            event);
+    if(args->onactivate || args->onactivate_action) {
         g_signal_connect(
                 view,
                 "row-activated",
                 G_CALLBACK(ui_listview_activate_event),
                 event);
     }
-    if(args->onselection) {
+    if(args->onselection || args->onselection_action) {
         GtkTreeSelection *selection = gtk_tree_view_get_selection(
                 GTK_TREE_VIEW(view));
         g_signal_connect(
@@ -1565,8 +1578,6 @@
                 G_CALLBACK(ui_listview_selection_event),
                 event);
     }
-    // TODO: destroy callback
-    
     
     if(args->ondragstart) {
         ui_listview_add_dnd(tableview, args);
@@ -1800,11 +1811,15 @@
     e.eventdata = &selection;
     e.intval = selection.count > 0 ? selection.rows[0] : -1;
     e.set = ui_get_setop();
-    event->activate(&e, event->activatedata);
     
-    if(selection.count > 0) {
-        free(selection.rows);
+    if(event->activate) {
+        event->activate(&e, event->activatedata);
     }
+    if(event->activate_action) {
+        uic_action_callback(&e, event->activate_action);
+    }
+    
+    free(selection.rows);
 }
 
 void ui_listview_selection_event(
@@ -1824,11 +1839,14 @@
     e.eventdata = &selection;
     e.intval = selection.count > 0 ? selection.rows[0] : -1;
     e.set = ui_get_setop();
-    event->selection(&e, event->selectiondata);
+    if(event->selection) {
+        event->selection(&e, event->selectiondata);
+    }
+    if(event->selection_action) {
+        uic_action_callback(&e, event->selection_action);
+    }
     
-    if(selection.count > 0) {
-        free(selection.rows);
-    }
+    free(selection.rows);
 }
 
 UiListSelection ui_listview_get_selection(
--- a/ui/gtk/list.h	Sat Jun 06 18:47:45 2026 +0200
+++ b/ui/gtk/list.h	Sun Jun 07 13:11:09 2026 +0200
@@ -106,6 +106,8 @@
     ui_callback selection;
     void        *activatedata;
     void        *selectiondata;
+    char        *activate_action;
+    char        *selection_action;
 } UiTreeEventData;
 
 typedef struct UiListBox UiListBox;

mercurial