# HG changeset patch # User Olaf Wintermann # Date 1756040307 -7200 # Node ID 6466b4f16e5ee91b98eb982d43a542c160980419 # Parent e9f655afc7ed15b08174749c3f821c2c4155f8d4 remove getvalue func from UiModel diff -r e9f655afc7ed -r 6466b4f16e5e application/main.c --- a/application/main.c Sun Aug 24 13:38:16 2025 +0200 +++ b/application/main.c Sun Aug 24 14:58:27 2025 +0200 @@ -627,8 +627,8 @@ ui_tab(obj, "Tab 1") { UiModel *model = ui_model(obj->ctx, UI_STRING, "col1", UI_INTEGER, "col2", UI_ICON, "col3", UI_ICON_TEXT, "col4", UI_INTEGER, "col5", -1); model->columnsize[0] = -1; - model->getvalue = table_getvalue; ui_table(obj, .model = model, .list = doc->list2, .colspan = 2, .fill = TRUE, .contextmenu = menubuilder, .multiselection = TRUE, .fill = TRUE, + .getvalue = table_getvalue, .onactivate = action_table_activate, .onactivatedata = "activate", .onselection = action_table_activate, .onselectiondata = "selection"); ui_hbox(obj, .fill = FALSE) { diff -r e9f655afc7ed -r 6466b4f16e5e ui/gtk/list.c --- a/ui/gtk/list.c Sun Aug 24 13:38:16 2025 +0200 +++ b/ui/gtk/list.c Sun Aug 24 14:58:27 2025 +0200 @@ -45,16 +45,16 @@ #include "dnd.h" -void* ui_strmodel_getvalue(void *elm, int column) { - return column == 0 ? elm : NULL; +static void* getvalue_wrapper(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { + ui_getvaluefunc getvalue = (ui_getvaluefunc)userdata; + return getvalue(elm, col); } -static void* model_getvalue(UiModel *model, UiList *list, void *elm, int row, int col, UiBool *freeResult) { - if(model->getvalue2) { - return model->getvalue2(list, elm, row, col, model->getvalue2data, freeResult); - } else if(model->getvalue) { - return model->getvalue(elm, col); - } +static void* str_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { + return elm; +} + +static void* null_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { return NULL; } @@ -75,6 +75,37 @@ } } +static UiListView* create_listview(UiObject *obj, UiListArgs *args) { + UiListView *tableview = malloc(sizeof(UiListView)); + memset(tableview, 0, sizeof(UiListView)); + tableview->obj = obj; + tableview->model = args->model; + tableview->onactivate = args->onactivate; + tableview->onactivatedata = args->onactivatedata; + tableview->onselection = args->onselection; + tableview->onselectiondata = args->onselectiondata; + tableview->ondragstart = args->ondragstart; + tableview->ondragstartdata = args->ondragstartdata; + tableview->ondragcomplete = args->ondragcomplete; + tableview->ondragcompletedata = args->ondragcompletedata; + tableview->ondrop = args->ondrop; + tableview->ondropdata = args->ondropdata; + tableview->selection.count = 0; + tableview->selection.rows = NULL; + + if(args->getvalue2) { + tableview->getvalue = args->getvalue2; + tableview->getvaluedata = args->getvalue2data; + } else if(args->getvalue) { + tableview->getvalue = getvalue_wrapper; + tableview->getvaluedata = (void*)args->getvalue; + } else { + tableview->getvalue = null_getvalue; + } + + return tableview; +} + #if GTK_CHECK_VERSION(4, 10, 0) @@ -132,16 +163,17 @@ } } -static void column_factory_bind( GtkListItemFactory *factory, GtkListItem *item, gpointer userdata) { +static void column_factory_bind(GtkListItemFactory *factory, GtkListItem *item, gpointer userdata) { UiColData *col = userdata; UiList *list = col->listview->var ? col->listview->var->value : NULL; + UiListView *listview = col->listview; ObjWrapper *obj = gtk_list_item_get_item(item); UiModel *model = col->listview->model; UiModelType type = model->types[col->model_column]; UiBool freevalue = FALSE; - void *data = model_getvalue(model, list, obj->data, obj->i, col->data_column, &freevalue); + void *data = listview->getvalue(list, obj->data, obj->i, col->data_column, listview->getvaluedata, &freevalue); GtkWidget *child = gtk_list_item_get_child(item); switch(type) { @@ -173,7 +205,7 @@ } case UI_ICON_TEXT_FREE: { - void *data2 = model_getvalue(model, list, obj->data, obj->i, col->data_column+1, &freevalue); + void *data2 = listview->getvalue(list, obj->data, obj->i, col->data_column+1, listview->getvaluedata, &freevalue); if(type == UI_ICON_TEXT_FREE) { freevalue = TRUE; } @@ -207,50 +239,25 @@ return selection_model; } -static UiListView* create_listview(UiObject *obj, UiListArgs *args) { - UiListView *tableview = malloc(sizeof(UiListView)); - memset(tableview, 0, sizeof(UiListView)); - tableview->obj = obj; - tableview->model = args->model; - tableview->onactivate = args->onactivate; - tableview->onactivatedata = args->onactivatedata; - tableview->onselection = args->onselection; - tableview->onselectiondata = args->onselectiondata; - tableview->ondragstart = args->ondragstart; - tableview->ondragstartdata = args->ondragstartdata; - tableview->ondragcomplete = args->ondragcomplete; - tableview->ondragcompletedata = args->ondragcompletedata; - tableview->ondrop = args->ondrop; - tableview->ondropdata = args->ondropdata; - tableview->selection.count = 0; - tableview->selection.rows = NULL; - return tableview; -} - UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) { UiObject* current = uic_current_obj(obj); // to simplify things and share code with ui_table_create, we also // use a UiModel for the listview UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); - if(args->getvalue2) { - model->getvalue2 = args->getvalue2; - model->getvalue2data = args->getvalue2data; - } else if(args->getvalue) { - model->getvalue = args->getvalue; - } else { - model->getvalue = ui_strmodel_getvalue; - } args->model = model; GListStore *ls = g_list_store_new(G_TYPE_OBJECT); UiListView *listview = create_listview(obj, args); + if(!args->getvalue && !args->getvalue2) { + listview->getvalue = str_getvalue; + } listview->columns = malloc(sizeof(UiColData)); listview->columns->listview = listview; listview->columns->data_column = 0; listview->columns->model_column = 0; - + GtkListItemFactory *factory = gtk_signal_list_item_factory_new(); g_signal_connect(factory, "setup", G_CALLBACK(column_factory_setup), listview->columns); g_signal_connect(factory, "bind", G_CALLBACK(column_factory_bind), listview->columns); @@ -283,7 +290,7 @@ ui_update_liststore(ls, list); } else if (args->static_elements && args->static_nelm > 0) { listview_copy_static_elements(listview, args->static_elements, args->static_nelm); - listview->model->getvalue = ui_strmodel_getvalue; // force strmodel + listview->getvalue = str_getvalue; // force string values ui_update_liststore_static(ls, listview->elements, listview->nelm); } @@ -323,19 +330,15 @@ // to simplify things and share code with ui_tableview_create, we also // use a UiModel for the listview UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); - if(args->getvalue2) { - model->getvalue2 = args->getvalue2; - model->getvalue2data = args->getvalue2data; - } else if(args->getvalue) { - model->getvalue = args->getvalue; - } else { - model->getvalue = ui_strmodel_getvalue; - } args->model = model; GListStore *ls = g_list_store_new(G_TYPE_OBJECT); UiListView *listview = create_listview(obj, args); + if(!args->getvalue && !args->getvalue2) { + listview->getvalue = str_getvalue; + } + listview->columns = malloc(sizeof(UiColData)); listview->columns->listview = listview; listview->columns->data_column = 0; @@ -373,7 +376,7 @@ ui_update_liststore(ls, list); } else if (args->static_elements && args->static_nelm > 0) { listview_copy_static_elements(listview, args->static_elements, args->static_nelm); - listview->model->getvalue = ui_strmodel_getvalue; // force strmodel + listview->getvalue = str_getvalue; // force string values ui_update_liststore_static(ls, listview->elements, listview->nelm); } @@ -704,12 +707,13 @@ #else -static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *model, UiList *list, void *elm, int row) { +static void update_list_row(UiListView *listview, GtkListStore *store, GtkTreeIter *iter, UiList *list, void *elm, int row) { + UiModel *model = listview->model; // set column values int c = 0; for(int i=0;icolumns;i++,c++) { UiBool freevalue = FALSE; - void *data = model_getvalue(model, list, elm, row, c, &freevalue); + void *data = listview->getvalue(list, elm, row, c, listview->getvaluedata, &freevalue); GValue value = G_VALUE_INIT; switch(model->types[i]) { @@ -774,7 +778,7 @@ c++; freevalue = FALSE; - char *str = model_getvalue(model, list, elm, row, c, &freevalue); + char *str = listview->getvalue(list, elm, row, c, listview->getvaluedata, &freevalue); g_value_init(&value, G_TYPE_STRING); g_value_set_string(&value, str); if(model->types[i] == UI_ICON_TEXT_FREE || freevalue) { @@ -788,7 +792,8 @@ } } -static GtkListStore* create_list_store(UiList *list, UiModel *model) { +static GtkListStore* create_list_store(UiListView *listview, UiList *list) { + UiModel *model = listview->model; int columns = model->columns; GType types[2*columns]; int c = 0; @@ -816,7 +821,7 @@ GtkTreeIter iter; gtk_list_store_insert (store, &iter, -1); - update_list_row(store, &iter, model, list, elm, i++); + update_list_row(listview, store, &iter, list, elm, i++); // next row elm = list->next(list); @@ -850,36 +855,29 @@ #endif UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); - if(args->getvalue2) { - model->getvalue2 = args->getvalue2; - model->getvalue2data = args->getvalue2data; - } else if(args->getvalue) { - model->getvalue = args->getvalue; - } else { - model->getvalue = ui_strmodel_getvalue; + + UiListView *listview = create_listview(obj, args); + if(!args->getvalue && !args->getvalue2) { + listview->getvalue = str_getvalue; } - - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); - - UiList *list = var ? var->value : NULL; - GtkListStore *listmodel = create_list_store(list, model); - gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel)); - g_object_unref(listmodel); - - UiListView *listview = malloc(sizeof(UiListView)); - memset(listview, 0, sizeof(UiListView)); - listview->obj = obj; - listview->widget = view; - listview->var = var; listview->model = model; - listview->selection.count = 0; - listview->selection.rows = NULL; g_signal_connect( view, "destroy", G_CALLBACK(ui_listview_destroy), listview); + UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); + + // init listview + listview->widget = view; + listview->var = var; + + UiList *list = var ? var->value : NULL; + GtkListStore *listmodel = create_list_store(listview, list); + gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel)); + g_object_unref(listmodel); + // bind var list->update = ui_listview_update; list->getselection = ui_listview_getselection; @@ -1015,36 +1013,23 @@ UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); - UiList *list = var ? var->value : NULL; - GtkListStore *listmodel = create_list_store(list, model); - gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel)); - g_object_unref(listmodel); - //g_signal_connect(view, "drag-begin", G_CALLBACK(drag_begin), NULL); //g_signal_connect(view, "drag-end", G_CALLBACK(drag_end), NULL); // add TreeView as observer to the UiList to update the TreeView if the // data changes - UiListView *tableview = malloc(sizeof(UiListView)); - memset(tableview, 0, sizeof(UiListView)); - tableview->obj = obj; - tableview->widget = view; - tableview->var = var; - tableview->model = model; - tableview->ondragstart = args->ondragstart; - tableview->ondragstartdata = args->ondragstartdata; - tableview->ondragcomplete = args->ondragcomplete; - tableview->ondragcompletedata = args->ondragcompletedata; - tableview->ondrop = args->ondrop; - tableview->ondropdata = args->ondropdata; - tableview->selection.count = 0; - tableview->selection.rows = NULL; + UiListView *tableview = create_listview(obj, args); g_signal_connect( view, "destroy", G_CALLBACK(ui_listview_destroy), tableview); + UiList *list = var ? var->value : NULL; + GtkListStore *listmodel = create_list_store(tableview, list); + gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(listmodel)); + g_object_unref(listmodel); + // bind var list->update = ui_listview_update; list->getselection = ui_listview_getselection; @@ -1121,7 +1106,7 @@ void ui_listview_update(UiList *list, int i) { UiListView *view = list->obj; if(i < 0) { - GtkListStore *store = create_list_store(list, view->model); + GtkListStore *store = create_list_store(view, list); gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(store)); g_object_unref(G_OBJECT(store)); } else { @@ -1129,7 +1114,7 @@ GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(view->widget)); GtkTreeIter iter; if(gtk_tree_model_iter_nth_child(store, &iter, NULL, i)) { - update_list_row(GTK_LIST_STORE(store), &iter, view->model, list, elm, i); + update_list_row(view, GTK_LIST_STORE(store), &iter, list, elm, i); } } } @@ -1159,46 +1144,43 @@ UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { UiObject* current = uic_current_obj(obj); - UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); - if(args->getvalue2) { - model->getvalue2 = args->getvalue2; - model->getvalue2data = args->getvalue2data; - } else if(args->getvalue) { - model->getvalue = args->getvalue; - } else { - model->getvalue = ui_strmodel_getvalue; - } + //GtkWidget *combobox = ui_create_combobox(obj, model, var, args->static_elements, args->static_nelm, args->onactivate, args->onactivatedata); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); + GtkWidget *combobox = gtk_combo_box_new(); - GtkWidget *combobox = ui_create_combobox(obj, model, var, args->static_elements, args->static_nelm, args->onactivate, args->onactivatedata); ui_set_name_and_style(combobox, args->name, args->style_class); ui_set_widget_groups(obj->ctx, combobox, args->groups); UI_APPLY_LAYOUT2(current, args); current->container->add(current->container, combobox); current->container->current = combobox; - return combobox; -} - -GtkWidget* ui_create_combobox(UiObject *obj, UiModel *model, UiVar *var, char **elm, size_t nelm, ui_callback f, void *udata) { - GtkWidget *combobox = gtk_combo_box_new(); - - UiListView *uicbox = malloc(sizeof(UiListView)); - memset(uicbox, 0, sizeof(UiListView)); - uicbox->obj = obj; - uicbox->widget = combobox; + + UiListView *listview = create_listview(obj, args); + listview->widget = combobox; + listview->model = ui_model(obj->ctx, UI_STRING, "", -1); + g_signal_connect( + combobox, + "destroy", + G_CALLBACK(ui_listview_destroy), + listview); + UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); UiList *list = var ? var->value : NULL; - GtkListStore *listmodel = create_list_store(list, model); - - if(!list && elm && nelm > 0) { - listview_copy_static_elements(uicbox, elm, nelm); - for(int i=0;ivar = var; + list->update = ui_combobox_modelupdate; + list->getselection = ui_combobox_getselection; + list->setselection = ui_combobox_setselection; + list->obj = listview; + list->update(list, -1); + } else if(args->static_nelm > 0) { + listview_copy_static_elements(listview, args->static_elements, args->static_nelm); + for(int i=0;istatic_nelm;i++) { GtkTreeIter iter; GValue value = G_VALUE_INIT; gtk_list_store_insert(listmodel, &iter, -1); g_value_init(&value, G_TYPE_STRING); - g_value_set_string(&value, uicbox->elements[i]); + g_value_set_string(&value, listview->elements[i]); gtk_list_store_set_value(listmodel, &iter, 0, &value); } } @@ -1208,23 +1190,6 @@ g_object_unref(listmodel); } - uicbox->var = var; - uicbox->model = model; - - g_signal_connect( - combobox, - "destroy", - G_CALLBACK(ui_combobox_destroy), - uicbox); - - // bind var - if(list) { - list->update = ui_combobox_modelupdate; - list->getselection = ui_combobox_getselection; - list->setselection = ui_combobox_setselection; - list->obj = uicbox; - } - GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE); gtk_cell_layout_set_attributes( @@ -1236,13 +1201,13 @@ gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0); // add callback - if(f) { + if(args->onactivate) { UiEventData *event = ui_malloc(obj->ctx, sizeof(UiEventData)); event->obj = obj; - event->userdata = udata; - event->callback = f; + event->userdata = args->onactivatedata; + event->callback = args->onactivate; event->value = 0; - event->customdata = uicbox; + event->customdata = listview; g_signal_connect( combobox, @@ -1277,7 +1242,7 @@ void ui_combobox_modelupdate(UiList *list, int i) { UiListView *view = list->obj; - GtkListStore *store = create_list_store(view->var->value, view->model); + GtkListStore *store = create_list_store(view, list); gtk_combo_box_set_model(GTK_COMBO_BOX(view->widget), GTK_TREE_MODEL(store)); g_object_unref(store); } @@ -1718,19 +1683,6 @@ free(v); } -void ui_combobox_destroy(GtkWidget *w, UiListView *v) { - if(v->var) { - ui_destroy_boundvar(v->obj->ctx, v->var); - } - if(v->elements) { - for(int i=0;inelm;i++) { - free(v->elements[i]); - } - free(v->elements); - } - free(v); -} - /* ------------------------------ Source List ------------------------------ */ diff -r e9f655afc7ed -r 6466b4f16e5e ui/gtk/list.h --- a/ui/gtk/list.h Sun Aug 24 13:38:16 2025 +0200 +++ b/ui/gtk/list.h Sun Aug 24 14:58:27 2025 +0200 @@ -45,6 +45,8 @@ GtkWidget *widget; UiVar *var; UiModel *model; + ui_getvaluefunc2 getvalue; + void *getvaluedata; char **elements; size_t nelm; #if GTK_CHECK_VERSION(4, 10, 0) diff -r e9f655afc7ed -r 6466b4f16e5e ui/ui/tree.h --- a/ui/ui/tree.h Sun Aug 24 13:38:16 2025 +0200 +++ b/ui/ui/tree.h Sun Aug 24 14:58:27 2025 +0200 @@ -76,25 +76,6 @@ * array of column size hints */ int *columnsize; - - /* - * void*(*ui_getvaluefunc)(void *elm, int col); - * - * function for translating model data to view data - * first argument is the pointer returned by UiList first|next|get - * second argument is the column index - * TODO: return - */ - ui_getvaluefunc getvalue; - - /* - * void*(*ui_getvaluefunc2)(UiList *list, void *elm, int row, int col, void *userdata) - * - * alternative for getvalue - */ - ui_getvaluefunc2 getvalue2; - - void *getvalue2data; }; struct UiListCallbacks {