add ui_combobox (Win32)

Tue, 25 Nov 2025 12:58:28 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 25 Nov 2025 12:58:28 +0100
changeset 936
d40a72210be8
parent 935
d95e8723545c
child 937
06e03c7e39db

add ui_combobox (Win32)

application/main.c file | annotate | diff | comparison | revisions
ui/win32/list.c file | annotate | diff | comparison | revisions
ui/win32/list.h file | annotate | diff | comparison | revisions
ui/win32/toolkit.c file | annotate | diff | comparison | revisions
--- a/application/main.c	Tue Nov 25 12:10:04 2025 +0100
+++ b/application/main.c	Tue Nov 25 12:58:28 2025 +0100
@@ -1225,13 +1225,15 @@
     ui_list_append(list, &person2);
 
     ui_grid(obj, .margin = 10, .columnspacing = 10, .rowspacing = 10, .fill = TRUE) {
-        UiModel *model = ui_model(obj->ctx, UI_STRING, "Name", UI_STRING, "Email", -1);
-        ui_table(obj, .fill = TRUE, .varname = "persons", .model = model, .getvalue = person_getvalue, .onselection = list_onselection);
-        ui_model_free(obj->ctx, model);
+        //UiModel *model = ui_model(obj->ctx, UI_STRING, "Name", UI_STRING, "Email", -1);
+        //ui_table(obj, .fill = TRUE, .varname = "persons", .model = model, .getvalue = person_getvalue, .onselection = list_onselection);
+        //ui_model_free(obj->ctx, model);
+        ui_combobox(obj, .varname = "persons", .getvalue = person_getvalue, .onactivate = list_onselection);
     }
 
 
 
+
 	ui_show(obj);
 }
 
--- a/ui/win32/list.c	Tue Nov 25 12:10:04 2025 +0100
+++ b/ui/win32/list.c	Tue Nov 25 12:58:28 2025 +0100
@@ -60,8 +60,8 @@
 /*
  * Creates an UiListView widget object and initializes it from the UiListArgs
  */
-static UiListView* create_listview_widget(UiObject *obj, HWND hwnd, UiListArgs *args, UiBool table) {
-    UiListView *listview = w32_widget_create(&listview_widget_class, hwnd, sizeof(UiListView));
+static UiListView* create_listview_widget(UiObject *obj, W32WidgetClass *widget_class, HWND hwnd, UiListArgs *args, UiBool table) {
+    UiListView *listview = w32_widget_create(widget_class, hwnd, sizeof(UiListView));
     listview->widget.hwnd = hwnd;
     listview->obj = obj;
     listview->preferred_width = args->width ? args->width : 300; // 300: default width/height
@@ -119,7 +119,7 @@
         LVS_EX_FULLROWSELECT //| LVS_EX_GRIDLINES
     );
 
-    UiListView *listview = create_listview_widget(obj, hwnd, args, table);
+    UiListView *listview = create_listview_widget(obj, &listview_widget_class, hwnd, args, table);
     ui_container_add(container, (W32Widget*)listview, &layout);
 
     // init list model
@@ -343,3 +343,111 @@
 UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) {
     return listview_create(obj, args, TRUE);
 }
+
+
+/* ------------------------------------ DropDown ------------------------------------*/
+
+static W32WidgetClass dropdown_widget_class = {
+    .eventproc = ui_dropdown_eventproc,
+    .enable = w32_widget_default_enable,
+    .show = w32_widget_default_show,
+    .get_preferred_size = ui_dropdown_get_preferred_size,
+    .destroy  = w32_widget_default_destroy
+};
+
+UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) {
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+    UiContainerPrivate *container = ui_obj_container(obj);
+    HWND parent = ui_container_get_parent(container);
+    UiLayout layout = UI_ARGS2LAYOUT(args);
+
+    HWND hwnd = CreateWindowEx(
+            WS_EX_CLIENTEDGE,
+            WC_COMBOBOX,
+            "",
+            WS_CHILD | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST,
+            0, 0, 100, 100,
+            parent,
+            (HMENU)1337,
+            hInstance,
+            NULL);
+    ui_win32_set_ui_font(hwnd);
+
+    UiListView *dropdown = create_listview_widget(obj, &dropdown_widget_class, hwnd, args, FALSE);
+    ui_container_add(container, (W32Widget*)dropdown, &layout);
+
+    // bind the dropdown to the provided UiList
+    if (dropdown->var) {
+        UiList *list = dropdown->var->value;
+        list->obj = dropdown;
+        list->update = ui_dropdown_update;
+        list->getselection = ui_dropdown_getselection;
+        list->setselection = ui_dropdown_setselection;
+
+        ui_dropdown_update(list, -1);
+    }
+
+
+    return (W32Widget*)dropdown;
+}
+
+void ui_dropdown_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+
+}
+
+W32Size ui_dropdown_get_preferred_size(W32Widget *widget) {
+    W32Size size;
+    size.width = 200;
+    size.height = 30;
+    return size;
+}
+
+static void dropdown_insert_item(UiList *list, int row, void *elm) {
+    UiListView *listview = (UiListView*)list->obj;
+    HWND hwnd = listview->widget.hwnd;
+
+    UiBool freeResult = FALSE;
+    char *str = listview->getvalue(list, elm, row, 0, listview->getvaluedata, &freeResult);
+    SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)str);
+
+    if (freeResult) {
+        free(str);
+    }
+}
+
+void ui_dropdown_update(UiList *list, int row) {
+    UiListView *listview = (UiListView*)list->obj;
+    HWND hwnd = listview->widget.hwnd;
+    if (row < 0) {
+        SendMessage(hwnd, CB_RESETCONTENT, 0, 0);
+
+        void *elm = list->first(list);
+        int row = 0;
+        while (elm) {
+            dropdown_insert_item(list, row, elm);
+            elm = list->next(list);
+            row++;
+        }
+    } else {
+        SendMessage(hwnd, CB_DELETESTRING, row, 0);
+        void *elm = list->get(list, row);
+        dropdown_insert_item(list, row, elm);
+    }
+}
+
+UiListSelection ui_dropdown_getselection(UiList *list) {
+    UiListSelection sel = { 0, NULL };
+    UiListView *listview = (UiListView*)list->obj;
+    int index = (int)SendMessage(listview->widget.hwnd, CB_GETCURSEL, 0, 0);
+    if (index >= 0) {
+        sel.rows = malloc(sizeof(int));
+        sel.rows[0] = index;
+        sel.count = 1;
+    }
+    return sel;
+}
+
+void ui_dropdown_setselection(UiList *list, UiListSelection selection) {
+    UiListView *listview = (UiListView*)list->obj;
+    SendMessage(listview->widget.hwnd, CB_SETCURSEL, 0, 0);
+}
--- a/ui/win32/list.h	Tue Nov 25 12:10:04 2025 +0100
+++ b/ui/win32/list.h	Tue Nov 25 12:58:28 2025 +0100
@@ -69,6 +69,13 @@
 UiListSelection ui_listview_getselection(UiList *list);
 void ui_listview_setselection(UiList *list, UiListSelection selection);
 
+void ui_dropdown_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+W32Size ui_dropdown_get_preferred_size(W32Widget *widget);
+
+void ui_dropdown_update(UiList *list, int row);
+UiListSelection ui_dropdown_getselection(UiList *list);
+void ui_dropdown_setselection(UiList *list, UiListSelection selection);
+
 #ifdef __cplusplus
 }
 #endif
--- a/ui/win32/toolkit.c	Tue Nov 25 12:10:04 2025 +0100
+++ b/ui/win32/toolkit.c	Tue Nov 25 12:58:28 2025 +0100
@@ -64,7 +64,7 @@
 
     INITCOMMONCONTROLSEX icex = {
         sizeof(icex),
-        ICC_WIN95_CLASSES | ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES | ICC_BAR_CLASSES | ICC_TAB_CLASSES
+        ICC_WIN95_CLASSES | ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES | ICC_BAR_CLASSES | ICC_TAB_CLASSES | ICC_STANDARD_CLASSES | ICC_USEREX_CLASSES
     };
     InitCommonControlsEx(&icex);
 

mercurial