--- a/ui/gtk/list.c Wed Dec 17 22:36:41 2025 +0100 +++ b/ui/gtk/list.c Sat Dec 27 22:47:56 2025 +0100 @@ -822,20 +822,19 @@ view->selection.count = 0; view->selection.rows = NULL; - CX_ARRAY_DECLARE(int, newselection); - cx_array_initialize(newselection, 8); - size_t nitems = g_list_model_get_n_items(G_LIST_MODEL(view->liststore)); + int *newselection = calloc(nitems, sizeof(int)); + int selection_size = 0; for(size_t i=0;i<nitems;i++) { if(gtk_selection_model_is_selected(view->selectionmodel, i)) { int s = (int)i; - cx_array_simple_add(newselection, s); + newselection[selection_size++] = s; } } - if(newselection_size > 0) { - view->selection.count = newselection_size; + if(selection_size > 0) { + view->selection.count = selection_size; view->selection.rows = newselection; } else { free(newselection); @@ -1109,6 +1108,23 @@ } break; } + case UI_STRING_EDITABLE: { + g_value_init(&value, G_TYPE_STRING); + g_value_set_string(&value, data); + if(freevalue) { + free(data); + } + break; + } + case UI_BOOL_EDITABLE: { + g_value_init(&value, G_TYPE_BOOLEAN); + intptr_t b = (intptr_t)data; + g_value_set_boolean(&value, b != 0 ? TRUE : FALSE); + if(freevalue) { + free(data); + } + break; + } } gtk_list_store_set_value(store, iter, c, &value); @@ -1182,6 +1198,8 @@ types[c] = G_TYPE_OBJECT; types[++c] = G_TYPE_STRING; } + case UI_STRING_EDITABLE: types[c] = G_TYPE_STRING; break; + case UI_BOOL_EDITABLE: types[c] = G_TYPE_BOOLEAN; break; } } int s = 0; @@ -1340,6 +1358,23 @@ gtk_combo_box_set_active(GTK_COMBO_BOX(dropdown), index); } +static void table_cell_toggled( + GtkCellRendererToggle *renderer, + gchar *path, + gpointer user_data) +{ + printf("cell toggled\n"); +} + +static void table_cell_edited( + GtkCellRendererText *renderer, + gchar *path, + gchar *new_text, + gpointer user_data) +{ + printf("cell edited\n"); +} + UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) { // create treeview GtkWidget *view = gtk_tree_view_new(); @@ -1398,8 +1433,20 @@ "pixbuf", i + addi, NULL); + } else if (model->types[i] == UI_BOOL_EDITABLE) { + GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new(); + column = gtk_tree_view_column_new_with_attributes( + model->titles[i], + renderer, + "active", + i + addi, + NULL); + g_signal_connect(renderer, "toggled", G_CALLBACK(table_cell_toggled), NULL); } else { GtkCellRenderer *textrenderer = gtk_cell_renderer_text_new(); + if(model->types[i] == UI_STRING_EDITABLE) { + g_object_set(textrenderer, "editable", TRUE, NULL); + } column = gtk_tree_view_column_new_with_attributes( model->titles[i], textrenderer, @@ -1560,7 +1607,7 @@ UiListSelection ui_listview_getselection(UiList *list) { UiListView *view = list->obj; - UiListSelection selection = ui_listview_selection( + UiListSelection selection = ui_listview_get_selection( gtk_tree_view_get_selection(GTK_TREE_VIEW(view->widget)), NULL); return selection; @@ -1713,7 +1760,7 @@ GtkTreeViewColumn *column, UiTreeEventData *event) { - UiListSelection selection = ui_listview_selection( + UiListSelection selection = ui_listview_get_selection( gtk_tree_view_get_selection(treeview), event); @@ -1735,7 +1782,7 @@ GtkTreeSelection *treeselection, UiTreeEventData *event) { - UiListSelection selection = ui_listview_selection(treeselection, event); + UiListSelection selection = ui_listview_get_selection(treeselection, event); UiEvent e; e.obj = event->obj; @@ -1751,7 +1798,7 @@ } } -UiListSelection ui_listview_selection( +UiListSelection ui_listview_get_selection( GtkTreeSelection *selection, UiTreeEventData *event) { @@ -2215,7 +2262,7 @@ uisublist.numitems = 0; uisublist.header = sublist->header ? strdup(sublist->header) : NULL; uisublist.separator = sublist->separator; - uisublist.widgets = cxLinkedListCreateSimple(CX_STORE_POINTERS); + uisublist.widgets = cxLinkedListCreate(NULL, CX_STORE_POINTERS); uisublist.listbox = uilistbox; uisublist.userdata = sublist->userdata; uisublist.index = cxListSize(sublists); @@ -2266,7 +2313,7 @@ uilistbox->onactivatedata = args->onactivatedata; uilistbox->onbuttonclick = args->onbuttonclick; uilistbox->onbuttonclickdata = args->onbuttonclickdata; - uilistbox->sublists = cxArrayListCreateSimple(sizeof(UiListBoxSubList), 4); + uilistbox->sublists = cxArrayListCreate(NULL, sizeof(UiListBoxSubList), 4); uilistbox->sublists->collection.advanced_destructor = (cx_destructor_func2)sublist_destroy; uilistbox->sublists->collection.destructor_data = obj; uilistbox->first_row = NULL; @@ -2354,7 +2401,7 @@ } cxListFree(uilistbox->sublists); - CxList *new_sublists = cxArrayListCreateSimple(sizeof(UiListBoxSubList), list->count(list)); + CxList *new_sublists = cxArrayListCreate(NULL, sizeof(UiListBoxSubList), list->count(list)); uilistbox->sublists = new_sublists; UiSubList *sublist = list->first(list);