Sun, 07 Jun 2026 13:11:09 +0200
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(