--- a/ui/motif/list.c Sat Apr 05 17:57:04 2025 +0200 +++ b/ui/motif/list.c Sun Jul 20 22:04:39 2025 +0200 @@ -34,36 +34,61 @@ #include "list.h" #include "../common/object.h" -UIWIDGET ui_listview_create(UiObject* obj, UiListArgs args) { +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); + } + return NULL; +} +*/ + +UIWIDGET ui_listview_create(UiObject* obj, UiListArgs *args) { Arg xargs[16]; int n = 0; UiContainerPrivate *ctn = ui_obj_container(obj); UI_APPLY_LAYOUT(ctn->layout, args); - if(args.multiselection) { + if(args->multiselection) { XtSetArg(xargs[n], XmNselectionPolicy, XmEXTENDED_SELECT); n++; } else { XtSetArg(xargs[n], XmNselectionPolicy, XmSINGLE_SELECT); n++; } - char *name = args.name ? (char*)args.name : "listview"; + char *name = args->name ? (char*)args->name : "listview"; Widget parent = ctn->prepare(ctn, xargs, &n); Widget widget = XmCreateScrolledList(parent, name, xargs, n); XtManageChild(widget); - UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.list, args.varname, UI_VAR_LIST); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); UiListView *listview = malloc(sizeof(UiListView)); memset(listview, 0, sizeof(UiListView)); listview->obj = obj; listview->widget = widget; - listview->getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue; + if(args->getvalue2) { + listview->getvalue = args->getvalue2; + listview->getvaluedata = args->getvalue2data; + } else if(args->getvalue) { + listview->getvalue = getvalue_wrapper; + listview->getvaluedata = args->getvalue; + } else { + listview->getvalue = getvalue_wrapper; + listview->getvaluedata = ui_strmodel_getvalue; + } listview->var = var; - listview->onactivate = args.onactivate; - listview->onactivatedata = args.onactivatedata; - listview->onselection = args.onselection; - listview->onselectiondata = args.onselectiondata; + listview->onactivate = args->onactivate; + listview->onactivatedata = args->onactivatedata; + listview->onselection = args->onselection; + listview->onselectiondata = args->onselectiondata; if(var) { UiList *list = var->value; @@ -109,6 +134,7 @@ event.window = obj->window; event.document = obj->ctx->document; event.eventdata = &sel; + event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION; event.intval = sel.count > 0 ? sel.rows[0] : -1; callback(&event, userdata); } @@ -139,13 +165,17 @@ } } -static XmStringTable create_stringlist(UiList *list, ui_getvaluefunc getvalue, int *count) { +static XmStringTable create_stringlist(UiList *list, ui_getvaluefunc2 getvalue, void *getvaluedata, int *count) { int num = list->count(list); XmStringTable items = (XmStringTable)XtMalloc(num * sizeof(XmString)); void *data = list->first(list); for(int i=0;i<num;i++) { - char *s = getvalue(data, 0); + UiBool freevalue = FALSE; + char *s = getvalue(list, data, i, 0, getvaluedata, &freevalue); items[i] = XmStringCreateLocalized(s ? s : ""); + if(freevalue) { + free(s); + } data = list->next(list); } @@ -160,6 +190,7 @@ XmStringTable items = create_stringlist( list, listview->getvalue, + listview->getvaluedata, &count); XtVaSetValues( @@ -206,18 +237,20 @@ UiListView *listview, XmComboBoxCallbackStruct *cb) { - UiListSelection sel = { 0, NULL }; - if(cb->item_position > 0) { - sel.count = 1; - sel.rows = malloc(sizeof(int)); - sel.rows[0] = cb->item_position-1; + int index = cb->item_position; + void *elm = NULL; + if(listview->var) { + UiList *list = listview->var->value; + elm = ui_list_get(list, index); } + UiEvent event; event.obj = listview->obj; event.window = event.obj->window; event.document = event.obj->ctx->document; - event.eventdata = &sel; - event.intval = 0; + event.eventdata = elm; + event.eventdatatype = UI_EVENT_DATA_LIST_ELM; + event.intval = index; if(listview->onactivate) { listview->onactivate(&event, listview->onactivatedata); } @@ -226,30 +259,39 @@ } } -UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs args) { +UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs *args) { Arg xargs[16]; int n = 0; UiContainerPrivate *ctn = ui_obj_container(obj); UI_APPLY_LAYOUT(ctn->layout, args); - char *name = args.name ? (char*)args.name : "dropdown"; + char *name = args->name ? (char*)args->name : "dropdown"; Widget parent = ctn->prepare(ctn, xargs, &n); Widget widget = XmCreateDropDownList(parent, name, xargs, n); XtManageChild(widget); - UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.list, args.varname, UI_VAR_LIST); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); UiListView *listview = malloc(sizeof(UiListView)); memset(listview, 0, sizeof(UiListView)); listview->obj = obj; listview->widget = widget; - listview->getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue; + if(args->getvalue2) { + listview->getvalue = args->getvalue2; + listview->getvaluedata = args->getvalue2data; + } else if(args->getvalue) { + listview->getvalue = getvalue_wrapper; + listview->getvaluedata = args->getvalue; + } else { + listview->getvalue = getvalue_wrapper; + listview->getvaluedata = ui_strmodel_getvalue; + } listview->var = var; - listview->onactivate = args.onactivate; - listview->onactivatedata = args.onactivatedata; - listview->onselection = args.onselection; - listview->onselectiondata = args.onselectiondata; + listview->onactivate = args->onactivate; + listview->onactivatedata = args->onactivatedata; + listview->onselection = args->onselection; + listview->onselectiondata = args->onselectiondata; if(var) { UiList *list = var->value;