diff -r 7b3a3130be44 -r 64ded9f6a6c6 ui/gtk/list.c --- a/ui/gtk/list.c Mon Jan 06 22:22:55 2025 +0100 +++ b/ui/gtk/list.c Tue Feb 25 21:11:00 2025 +0100 @@ -388,6 +388,13 @@ GtkColumnViewColumn *column = gtk_column_view_column_new(model->titles[i], factory); gtk_column_view_column_set_resizable(column, true); gtk_column_view_append_column(GTK_COLUMN_VIEW(view), column); + + int size = model->columnsize[i]; + if(size > 0) { + gtk_column_view_column_set_fixed_width(column, size); + } else if(size < 0) { + gtk_column_view_column_set_expand(column, TRUE); + } } // bind listview to list @@ -447,13 +454,7 @@ } } -void ui_columnview_activate(void *ignore, guint position, gpointer userdata) { - UiListView *view = userdata; - listview_event(view->onactivate, view->onactivatedata, view); -} - -void ui_listview_selection_changed(GtkSelectionModel* self, guint position, guint n_items, gpointer userdata) { - UiListView *view = userdata; +static void listview_update_selection(UiListView *view) { free(view->selection.rows); view->selection.count = 0; view->selection.rows = NULL; @@ -476,7 +477,19 @@ } else { free(newselection); } +} +void ui_columnview_activate(void *ignore, guint position, gpointer userdata) { + UiListView *view = userdata; + if(view->selection.count == 0) { + listview_update_selection(view); + } + listview_event(view->onactivate, view->onactivatedata, view); +} + +void ui_listview_selection_changed(GtkSelectionModel* self, guint position, guint n_items, gpointer userdata) { + UiListView *view = userdata; + listview_update_selection(view); listview_event(view->onselection, view->onselectiondata, view); } @@ -513,7 +526,7 @@ void ui_listview_update2(UiList *list, int i) { UiListView *view = list->obj; - ui_update_liststore(view->liststore, view->var->value); + ui_update_liststore(view->liststore, list); } UiListSelection ui_listview_getselection2(UiList *list) { @@ -614,8 +627,8 @@ } case UI_INTEGER: { g_value_init(&value, G_TYPE_INT); - int *intptr = data; - g_value_set_int(&value, *intptr); + intptr_t intptr = (intptr_t)data; + g_value_set_int(&value, (int)intptr); break; } case UI_ICON: { @@ -1559,6 +1572,34 @@ } #endif + +static void add_sublist(UiListBox *uilistbox, CxList *sublists, UiSubList *sublist) { + UiListBoxSubList uisublist; + uisublist.var = uic_widget_var( + uilistbox->obj->ctx, + uilistbox->obj->ctx, + sublist->value, + sublist->varname, + UI_VAR_LIST); + uisublist.numitems = 0; + uisublist.header = sublist->header ? strdup(sublist->header) : NULL; + uisublist.separator = sublist->separator; + uisublist.widgets = cxLinkedListCreateSimple(CX_STORE_POINTERS); + uisublist.listbox = uilistbox; + uisublist.userdata = sublist->userdata; + uisublist.index = cxListSize(sublists); + + // bind UiList + UiListBoxSubList *sublist_ptr = cxListAt(uilistbox->sublists, cxListSize(sublists)-1); + UiList *list = uisublist.var->value; + if(list) { + list->obj = sublist_ptr; + list->update = ui_listbox_list_update; + } + + cxListAdd(sublists, &uisublist); +} + UIEXPORT UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs args) { UiObject* current = uic_current_obj(obj); @@ -1596,42 +1637,32 @@ uilistbox->sublists->collection.destructor_data = obj; uilistbox->first_row = NULL; - if(args.numsublists == 0 && args.sublists) { - args.numsublists = INT_MAX; - } - for(int i=0;i<args.numsublists;i++) { - UiSubList sublist = args.sublists[i]; - if(!sublist.varname && !sublist.value) { - break; + if(args.sublists) { + // static sublist initalization + if(args.numsublists == 0 && args.sublists) { + args.numsublists = INT_MAX; + } + for(int i=0;i<args.numsublists;i++) { + UiSubList sublist = args.sublists[i]; + if(!sublist.varname && !sublist.value) { + break; + } + + add_sublist(uilistbox, uilistbox->sublists, &sublist); } - UiListBoxSubList uisublist; - uisublist.var = uic_widget_var( - obj->ctx, - current->ctx, - sublist.value, - sublist.varname, - UI_VAR_LIST); - uisublist.numitems = 0; - uisublist.header = sublist.header ? strdup(sublist.header) : NULL; - uisublist.separator = sublist.separator; - uisublist.widgets = cxLinkedListCreateSimple(CX_STORE_POINTERS); - uisublist.listbox = uilistbox; - uisublist.userdata = sublist.userdata; - uisublist.index = i; - - cxListAdd(uilistbox->sublists, &uisublist); - - // bind UiList - UiListBoxSubList *sublist_ptr = cxListAt(uilistbox->sublists, cxListSize(uilistbox->sublists)-1); - UiList *list = uisublist.var->value; - if(list) { - list->obj = sublist_ptr; - list->update = ui_listbox_list_update; + // fill items + ui_listbox_update(uilistbox, 0, cxListSize(uilistbox->sublists)); + } else { + UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.dynamic_sublist, args.varname, UI_VAR_LIST); + if(var) { + UiList *list = var->value; + list->obj = uilistbox; + list->update = ui_listbox_dynamic_update; + + ui_listbox_dynamic_update(list, 0); } } - // fill items - ui_listbox_update(uilistbox, 0, cxListSize(uilistbox->sublists)); // register uilistbox for both widgets, so it doesn't matter which // widget is used later @@ -1656,6 +1687,35 @@ return scroll_area; } +void ui_listbox_dynamic_update(UiList *list, int x) { + UiListBox *uilistbox = list->obj; + + // unbind/free previous list vars + CxIterator i = cxListIterator(uilistbox->sublists); + cx_foreach(UiListBoxSubList *, s, i) { + if(s->var) { + UiList *sl = s->var->value; + sl->obj = NULL; + sl->update = NULL; + if(s->var->type == UI_VAR_SPECIAL) { + ui_free(s->var->from_ctx, s->var); + } + } + } + + cxListFree(uilistbox->sublists); + CxList *new_sublists = cxArrayListCreateSimple(sizeof(UiListBoxSubList), list->count(list)); + uilistbox->sublists = new_sublists; + + UiSubList *sublist = list->first(list); + while(sublist) { + add_sublist(uilistbox, new_sublists, sublist); + sublist = list->next(list); + } + + ui_listbox_update(uilistbox, 0, cxListSize(uilistbox->sublists)); +} + void ui_listbox_update(UiListBox *listbox, int from, int to) { CxIterator i = cxListIterator(listbox->sublists); size_t pos = 0; @@ -1777,11 +1837,19 @@ } UiListBoxSubList *sublist = data->customdata0; + UiSubListEventData eventdata; + eventdata.list = sublist->var->value; + eventdata.sublist_index = sublist->index; + eventdata.row_index = data->value0; + eventdata.sublist_userdata = sublist->userdata; + eventdata.row_data = ui_list_get(eventdata.list, eventdata.row_index); + eventdata.event_data = data->customdata2; + UiEvent event; event.obj = data->obj; event.window = event.obj->window; event.document = event.obj->ctx->document; - event.eventdata = data->customdata2; + event.eventdata = &eventdata; event.intval = data->value0; if(data->callback) {