define sourcelist2 widget default tip

Thu, 10 Sep 2026 17:36:06 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 10 Sep 2026 17:36:06 +0200
changeset 1245
4163776eef49
parent 1244
a29b53f97d1a

define sourcelist2 widget

application/main.c file | annotate | diff | comparison | revisions
ui/gtk/list.c file | annotate | diff | comparison | revisions
ui/gtk/list.h file | annotate | diff | comparison | revisions
ui/gtk/tree.c file | annotate | diff | comparison | revisions
ui/gtk/tree.h file | annotate | diff | comparison | revisions
ui/ui/list.h file | annotate | diff | comparison | revisions
ui/ui/tree.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Wed Sep 09 18:57:52 2026 +0200
+++ b/application/main.c	Thu Sep 10 17:36:06 2026 +0200
@@ -575,6 +575,11 @@
     return node->name;
 }
 
+void sourcelist2_getvalue(UiList *list, void *elm, int index, UiSubListItem *item, void *userdata) {
+    TreeNode *node = elm;
+    item->label = node->name;
+}
+
 int tree_getdepth(UiList *list, void *elm, int row, void *userdata) {
     TreeNode *node = elm;
     return node->depth;
@@ -950,8 +955,10 @@
             ui_drawingarea(obj, .fill = TRUE, .draw = draw);
         }
         ui_tab(obj, "Tab 13") {
-            UiModel *model = ui_model(obj->ctx, UI_STRING, "test", -1);
-            ui_treeview(obj, .fill = TRUE, .model = model, .show_header = TRUE, .getvalue = tree_getvalue, .getdepth = tree_getdepth, .varname = "tree");
+            //UiModel *model = ui_model(obj->ctx, UI_STRING, "test", -1);
+            //ui_treeview(obj, .fill = TRUE, .model = model, .show_header = TRUE, .getvalue = tree_getvalue, .getdepth = tree_getdepth, .varname = "tree");
+            
+            ui_sourcelist2(obj, .fill = TRUE, .getvalue = sourcelist2_getvalue, .getdepth = tree_getdepth, .varname = "tree");
         }
     }
     
--- a/ui/gtk/list.c	Wed Sep 09 18:57:52 2026 +0200
+++ b/ui/gtk/list.c	Thu Sep 10 17:36:06 2026 +0200
@@ -40,6 +40,7 @@
 #include <cx/linked_list.h>
 
 #include "list.h"
+#include "tree.h"
 #include "button.h"
 #include "icon.h"
 #include "menu.h"
@@ -123,55 +124,18 @@
     return tableview;
 }
 
-static UiListView* create_treeview(UiObject *obj, UiTreeArgs *args) {
-    UiListView *treeview = malloc(sizeof(UiListView));
-    memset(treeview, 0, sizeof(UiListView));
-    treeview->obj = obj;
-    treeview->model = args->model;
-    treeview->multiselection = args->multiselection;
-    treeview->onactivate = args->onactivate;
-    treeview->onactivatedata = args->onactivatedata;
-    treeview->onactivate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
-    treeview->onselection = args->onselection;
-    treeview->onselectiondata = args->onselectiondata;
-    treeview->onselection_action = args->onselection_action ? strdup(args->onselection_action) : NULL;
-    treeview->ondragstart = args->ondragstart;
-    treeview->ondragstartdata = args->ondragstartdata;
-    treeview->ondragstart_action = args->ondragstart_action ? strdup(args->ondragstart_action) : NULL;
-    treeview->ondragcomplete = args->ondragcomplete;
-    treeview->ondragcompletedata = args->ondragcompletedata;
-    treeview->ondragcomplete_action = args->ondragcomplete_action ? strdup(args->ondragcomplete_action) : NULL;
-    treeview->ondrop = args->ondrop;
-    treeview->ondropdata = args->ondropdata;
-    treeview->ondrop_action = args->ondrop_action ? strdup(args->ondrop_action) : NULL;
-    treeview->selection.count = 0;
-    treeview->selection.rows = NULL;
-    treeview->current_row = -1;
-    
-#if GTK_CHECK_VERSION(4, 0, 0)
-    treeview->coldata.listview = treeview;
-    treeview->coldata.column = 0;
-#endif
-    
-    if(args->getvalue != NULL) {
-        treeview->getvalue = args->getvalue;
-        treeview->getvaluedata = args->getvaluedata;
-    } else {
-        args->getvalue = ui_null_getvalue;
-    }
-    
-    treeview->istreeview = TRUE;
-    treeview->getdepth = args->getdepth;
-    treeview->getdepthdata = args->getdepthdata;
-      
-    return treeview;
-}
-
 #if GTK_CHECK_VERSION(4, 10, 0)
 
 
 /* BEGIN GObject wrapper for generic pointers */
 
+typedef struct _ObjWrapper {
+    GObject parent_instance;
+    GListStore *children;
+    void *data;
+    int i;
+} ObjWrapper;
+
 typedef struct _ObjWrapperClass {
     GObjectClass parent_class;
 } ObjWrapperClass;
@@ -183,6 +147,7 @@
 }
 
 static void obj_wrapper_init(ObjWrapper *self) {
+    self->children = NULL;
     self->data = NULL;
 }
 
@@ -802,13 +767,12 @@
 
 UIWIDGET ui_treeview_create(UiObject *obj, UiTreeArgs *args) {
     GListStore *ls = g_list_store_new(G_TYPE_OBJECT);
-    //g_list_store_append(ls, v1);
     
     // create obj to store all relevant data we need for handling events
     // and list updates
-    UiListView *tableview = create_treeview(obj, args);
+    UiListView *treeview = ui_create_treeview(obj, args);
     
-    GtkSelectionModel *selection_model = create_selection_model(tableview, ls, args->multiselection);
+    GtkSelectionModel *selection_model = create_selection_model(treeview, ls, args->multiselection);
     GtkWidget *view = gtk_column_view_new(GTK_SELECTION_MODEL(selection_model));
     if(!args->show_header) {
         gtk_widget_set_visible(gtk_widget_get_first_child(view), FALSE);
@@ -817,15 +781,15 @@
     UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST);
     
     // init tableview
-    tableview->widget = view;
-    tableview->var = var;
-    tableview->liststore = ls;
-    tableview->selectionmodel = selection_model;
+    treeview->widget = view;
+    treeview->var = var;
+    treeview->liststore = ls;
+    treeview->selectionmodel = selection_model;
     g_signal_connect(
                 view,
                 "destroy",
                 G_CALLBACK(ui_listview_destroy),
-                tableview);
+                treeview);
     
     
     // create columns from UiModel
@@ -833,42 +797,42 @@
     int columns = 0;
     if(model) {
         columns = model->columns;
-        ui_model_add_observer(model, ui_listview_update_model, tableview);
+        ui_model_add_observer(model, ui_listview_update_model, treeview);
     }
     
-    tableview->columns = calloc(columns, sizeof(int));
-    tableview->numcolumns = columns;
+    treeview->columns = calloc(columns, sizeof(int));
+    treeview->numcolumns = columns;
     
-    tableview->bound_rows = cxHashMapCreate(NULL, CX_STORE_POINTERS, 128);
-    tableview->bound_rows->collection.simple_destructor = (cx_destructor_func)free;
+    treeview->bound_rows = cxHashMapCreate(NULL, CX_STORE_POINTERS, 128);
+    treeview->bound_rows->collection.simple_destructor = (cx_destructor_func)free;
     
     int addi = 0;
     for(int i=0;i<columns;i++) {
-        tableview->columns[i] = i+addi;
+        treeview->columns[i] = i+addi;
         
         if(model->types[i] == UI_ICON_TEXT || model->types[i] == UI_ICON_TEXT_FREE) {
             // icon+text has 2 data columns
             addi++;
         }
         
-        add_column(tableview, i);
+        add_column(treeview, i);
     }
     
     // bind listview to list
     if(var && var->value) {
         UiList *list = var->value;
         
-        list->obj = tableview;
+        list->obj = treeview;
         list->update = ui_listview_update2;
         list->getselection = ui_listview_getselection2;
         list->setselection = ui_listview_setselection2;
         
-        ui_update_liststore(ls, list);
+        ui_update_tree_liststore(ls, list);
     }
     
     // event handling
     if(args->onactivate || args->onactivate_action) {
-        g_signal_connect(view, "activate", G_CALLBACK(ui_columnview_activate), tableview);
+        g_signal_connect(view, "activate", G_CALLBACK(ui_columnview_activate), treeview);
     }
     if(args->contextmenu) {
         UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, view);
@@ -1066,6 +1030,10 @@
     }
 }
 
+void ui_update_tree_liststore(GListStore *liststore, UiList *list) {
+    
+}
+
 void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm) {
     g_list_store_remove_all(liststore);
     for(int i=0;i<nelm;i++) {
@@ -3068,3 +3036,147 @@
         data->callback(&event, data->userdata);
     }
 }
+
+/* ------------------------------ SourceList2 ------------------------------ */
+
+static void ui_destroy_sourcelist2(GtkWidget *w, UiListBox2 *v) {
+    cxListFree(v->rows);
+    free(v->onactivate_action);
+    free(v->onbuttonclick_action);
+    free(v);
+}
+
+UIWIDGET ui_sourcelist2_create(UiObject *obj, UiSourceList2Args *args) {
+#ifdef UI_GTK3
+    GtkWidget *listbox = g_object_new(ui_sidebar_list_box_get_type(), NULL);
+#else
+    GtkWidget *listbox = gtk_list_box_new();
+#endif
+    if(!args->style_class) {
+#if GTK_MAJOR_VERSION >= 4
+        WIDGET_ADD_CSS_CLASS(listbox, "navigation-sidebar");
+#else
+        WIDGET_ADD_CSS_CLASS(listbox, "sidebar");
+#endif
+    }
+    GtkWidget *scroll_area = SCROLLEDWINDOW_NEW();
+    SCROLLEDWINDOW_SET_CHILD(scroll_area, listbox);
+    
+    ui_set_name_and_style(listbox, args->name, args->style_class);
+    ui_set_widget_states(obj->ctx, listbox, args->states);
+    UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
+    UiLayout layout = UI_ARGS2LAYOUT(args);
+    ct->add(ct, scroll_area, &layout);
+    
+    UiListBox2 *uilistbox = malloc(sizeof(UiListBox2));
+    uilistbox->obj = obj;
+    uilistbox->listbox = GTK_LIST_BOX(listbox);
+    uilistbox->rows = cxArrayListCreate(NULL, CX_STORE_POINTERS, 64);
+    uilistbox->getvalue = args->getvalue;
+    uilistbox->getvaluedata = args->getvaluedata;
+    uilistbox->getdepth = args->getdepth;
+    uilistbox->getdepthdata = args->getdepthdata;
+    uilistbox->onactivate = args->onactivate;
+    uilistbox->onactivatedata = args->onactivatedata;
+    uilistbox->onactivate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
+    uilistbox->onbuttonclick = args->onbuttonclick;
+    uilistbox->onbuttonclickdata = args->onbuttonclickdata;
+    uilistbox->onbuttonclick_action = args->onbuttonclick_action ? strdup(args->onbuttonclick_action) : NULL;
+    
+    UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST);
+    uilistbox->var = var;
+    if(var) {
+        UiList *list = var->value;
+        list->update = ui_listbox2_update;
+        list->getselection = ui_listbox2_getselection;
+        list->setselection = ui_listbox2_setselection;
+        list->obj = uilistbox;
+        ui_listbox2_update(list, -1);
+    }
+    
+    // register uilistbox for both widgets, so it doesn't matter which
+    // widget is used later
+    g_object_set_data(G_OBJECT(scroll_area), "ui_listbox", uilistbox);
+    g_object_set_data(G_OBJECT(listbox), "ui_listbox", uilistbox);
+    
+    if(args->contextmenu) {
+        UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, listbox);
+        ui_widget_set_contextmenu(listbox, menu);
+    }
+    
+    // signals
+    g_signal_connect(
+                listbox,
+                "destroy",
+                G_CALLBACK(ui_destroy_sourcelist2),
+                uilistbox);
+    
+    if(args->onactivate) {
+        g_signal_connect(
+                listbox,
+                "row-activated",
+                G_CALLBACK(ui_listbox2_row_activate),
+                NULL);
+    }
+    
+    return scroll_area;
+}
+
+
+static int listbox2_update_item(UiListBox2 *listbox, GtkWidget *row, UiList *list, void *elm, int index) {
+    UiSubListItem item = { NULL, NULL, NULL, NULL, NULL, NULL };
+    if(listbox->getvalue) {
+        listbox->getvalue(list,elm, index, &item, listbox->getvaluedata);
+    }
+    
+    GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
+    
+    return 0;
+}
+
+static void listbox2_update_all(UiListBox2 *listbox) {
+    gtk_list_box_remove_all(listbox->listbox);
+    cxListClear(listbox->rows);
+    if(!listbox->var) {
+        return;
+    }
+    UiList *list = listbox->var->value;
+    if(!list) {
+        return;
+    }
+    
+    
+    int index = 0;
+    void *elm = list->first(list);
+    while(elm) {
+        GtkWidget *row = gtk_list_box_row_new();
+        cxListAdd(listbox->rows, row);
+        gtk_list_box_append(listbox->listbox, row);
+        int node_depth = listbox2_update_item(listbox, row, list, elm, index);
+        
+        elm = list->next(list);
+        index++;
+    }
+}
+
+void ui_listbox2_row_activate(GtkListBox *self, GtkListBoxRow *row, gpointer user_data) {
+    
+}
+
+
+void ui_listbox2_update(UiList *list, int i) {
+    UiListBox2 *listbox = list->obj;
+    if(i >= 0) {
+        // TODO
+    } else {
+        listbox2_update_all(listbox);
+    }
+}
+
+UiListSelection ui_listbox2_getselection(UiList *list) {
+    
+}
+
+void ui_listbox2_setselection(UiList *list, UiListSelection selection) {
+    
+}
--- a/ui/gtk/list.h	Wed Sep 09 18:57:52 2026 +0200
+++ b/ui/gtk/list.h	Thu Sep 10 17:36:06 2026 +0200
@@ -115,7 +115,8 @@
     char        *selection_action;
 } UiTreeEventData;
 
-typedef struct UiListBox UiListBox;
+typedef struct UiListBox   UiListBox;
+typedef struct UiListBox2  UiListBox2;
 
 typedef struct UiListBoxSubList {
     UiVar       *var;
@@ -144,11 +145,38 @@
     UiSubListEventData       current_eventdata;
 };
 
+struct UiListBox2 {
+    UiObject                     *obj;
+    GtkListBox                   *listbox;
+    UiVar                        *var;
+    CxList                       *rows;
+    ui_sourcelist_getvalue_func  getvalue;
+    void                         *getvaluedata;
+    ui_tree_getdepthfunc         getdepth;
+    void                         *getdepthdata;
+    
+    ui_callback                  onactivate;
+    void                         *onactivatedata;
+    char                         *onactivate_action;
+    ui_callback                  onbuttonclick;
+    void                         *onbuttonclickdata;
+    char                         *onbuttonclick_action;
+};
+
+typedef struct UiListBox2Row {
+    UiListBox2    *listbox;
+    CxList        *children; // type: int (index)
+    int           index;
+    int           depth;
+    int           expanded;
+} UiListBox2Row;
+
 void* ui_null_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult);
 
 #if GTK_CHECK_VERSION(4, 10, 0)
 
 void ui_update_liststore(GListStore *liststore, UiList *list);
+void ui_update_tree_liststore(GListStore *liststore, UiList *list);
 void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm);
 
 void ui_listview_update_model(UiModel *model, void *userdata, int insert_index, int delete_index);
@@ -214,17 +242,14 @@
 
 void ui_listbox_row_activate(GtkListBox *self, GtkListBoxRow *row, gpointer user_data);
 
-#if GTK_CHECK_VERSION(4, 10, 0)
+
+/* ------------------------------ SourceList2 ------------------------------ */
 
-typedef struct _ObjWrapper {
-    GObject parent_instance;
-    void *data;
-    int i;
-} ObjWrapper;
+void ui_listbox2_row_activate(GtkListBox *self, GtkListBoxRow *row, gpointer user_data);
 
-ObjWrapper* ui_gobj_wrapper_new(void* data, int i);
-
-#endif
+void ui_listbox2_update(UiList *list, int i);
+UiListSelection ui_listbox2_getselection(UiList *list);
+void ui_listbox2_setselection(UiList *list, UiListSelection selection);
         
 #ifdef	__cplusplus
 }
--- a/ui/gtk/tree.c	Wed Sep 09 18:57:52 2026 +0200
+++ b/ui/gtk/tree.c	Thu Sep 10 17:36:06 2026 +0200
@@ -32,4 +32,46 @@
 
 #include "../common/context.h"
 
-
+UiListView* ui_create_treeview(UiObject *obj, UiTreeArgs *args) {
+    UiListView *treeview = malloc(sizeof(UiListView));
+    memset(treeview, 0, sizeof(UiListView));
+    treeview->obj = obj;
+    treeview->model = args->model;
+    treeview->multiselection = args->multiselection;
+    treeview->onactivate = args->onactivate;
+    treeview->onactivatedata = args->onactivatedata;
+    treeview->onactivate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
+    treeview->onselection = args->onselection;
+    treeview->onselectiondata = args->onselectiondata;
+    treeview->onselection_action = args->onselection_action ? strdup(args->onselection_action) : NULL;
+    treeview->ondragstart = args->ondragstart;
+    treeview->ondragstartdata = args->ondragstartdata;
+    treeview->ondragstart_action = args->ondragstart_action ? strdup(args->ondragstart_action) : NULL;
+    treeview->ondragcomplete = args->ondragcomplete;
+    treeview->ondragcompletedata = args->ondragcompletedata;
+    treeview->ondragcomplete_action = args->ondragcomplete_action ? strdup(args->ondragcomplete_action) : NULL;
+    treeview->ondrop = args->ondrop;
+    treeview->ondropdata = args->ondropdata;
+    treeview->ondrop_action = args->ondrop_action ? strdup(args->ondrop_action) : NULL;
+    treeview->selection.count = 0;
+    treeview->selection.rows = NULL;
+    treeview->current_row = -1;
+    
+#if GTK_CHECK_VERSION(4, 0, 0)
+    treeview->coldata.listview = treeview;
+    treeview->coldata.column = 0;
+#endif
+    
+    if(args->getvalue != NULL) {
+        treeview->getvalue = args->getvalue;
+        treeview->getvaluedata = args->getvaluedata;
+    } else {
+        args->getvalue = ui_null_getvalue;
+    }
+    
+    treeview->istreeview = TRUE;
+    treeview->getdepth = args->getdepth;
+    treeview->getdepthdata = args->getdepthdata;
+      
+    return treeview;
+}
--- a/ui/gtk/tree.h	Wed Sep 09 18:57:52 2026 +0200
+++ b/ui/gtk/tree.h	Thu Sep 10 17:36:06 2026 +0200
@@ -30,46 +30,14 @@
 #define TREE_H
 
 #include "../ui/tree.h"
+#include "list.h"
 #include "toolkit.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-typedef struct UiTreeView UiTreeView;
-    
-struct UiTreeView {
-    UiObject *obj;
-    GtkWidget              *widget;
-    UiVar                  *var;
-    UiModel                *model;
-    UiBool                 multiselection;
-    ui_tree_getdepthfunc   getdepth;
-    void                   *getdepthdata;
-    ui_getvaluefunc2       getvalue;
-    void                   *getvaluedata;
-    
-    ui_callback            onactivate;
-    void                   *onactivatedata;
-    char                   *onactivate_action;
-    ui_callback            onselection;
-    void                   *onselectiondata;
-    char                   *onselection_action;
-    ui_callback            ondragstart;
-    void                   *ondragstartdata;
-    char                   *ondragstart_action;
-    ui_callback            ondragcomplete;
-    void                   *ondragcompletedata;
-    char                   *ondragcomplete_action;
-    ui_callback            ondrop;
-    void                   *ondropdata;
-    char                   *ondrop_action;
-};
-
-typedef struct UiTreeColData {
-    UiTreeView *treeview;
-    int column;
-} UiTreeColData;
+UiListView* ui_create_treeview(UiObject *obj, UiTreeArgs *args);
 
 
 #ifdef __cplusplus
--- a/ui/ui/list.h	Wed Sep 09 18:57:52 2026 +0200
+++ b/ui/ui/list.h	Thu Sep 10 17:36:06 2026 +0200
@@ -35,15 +35,16 @@
 extern "C" {
 #endif
 
-typedef struct UiModel          UiModel;
-typedef struct UiListCallbacks  UiListCallbacks;
-typedef struct UiListDnd        UiListDnd;
+typedef struct UiModel            UiModel;
+typedef struct UiListCallbacks    UiListCallbacks;
+typedef struct UiListDnd          UiListDnd;
 
-typedef struct UiListArgs       UiListArgs;
-typedef struct UiSourceListArgs UiSourceListArgs;
+typedef struct UiListArgs         UiListArgs;
+typedef struct UiSourceListArgs   UiSourceListArgs;
+typedef struct UiSourceList2Args  UiSourceList2Args;
 
-typedef struct UiSubList        UiSubList;
-typedef struct UiSubListItem    UiSubListItem;
+typedef struct UiSubList          UiSubList;
+typedef struct UiSubListItem      UiSubListItem;
 
 typedef enum UiModelType {
     UI_STRING = 0,
@@ -65,6 +66,8 @@
     UiModelType type;
 } UiCellValue;
 
+typedef int (*ui_tree_getdepthfunc)(UiList *list, void *elm, int row, void *userdata);
+
 typedef UiBool (*ui_list_savefunc)(UiList *list, int row, int col, UiCellValue *value, void *userdata);
 
 typedef void (*ui_model_update_func)(UiModel *model, void *userdata, int insert_index, int delete_index);
@@ -191,6 +194,8 @@
 
 typedef void (*ui_sublist_getvalue_func)(UiList *list, void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata);
 
+typedef void (*ui_sourcelist_getvalue_func)(UiList *list, void *elm, int index, UiSubListItem *item, void *userdata);
+
 struct UiSubList {
     UiList *value;
     const char *varname;
@@ -306,6 +311,70 @@
     const int *visibility_states;;
 };
 
+struct UiSourceList2Args {
+    UiBool fill;
+    UiBool hexpand;
+    UiBool vexpand;
+    UiBool hfill;
+    UiBool vfill;
+    UiBool override_defaults;
+    int margin;
+    int margin_left;
+    int margin_right;
+    int margin_top;
+    int margin_bottom;
+    int colspan;
+    int rowspan;
+    int width;
+    int height;
+    const char *name;
+    const char *style_class;
+    
+    UiList *list;
+    const char* varname;
+    
+    /*
+     * callback for each list item, that should fill all necessary
+     * UiSubListItem fields
+     */
+    ui_sourcelist_getvalue_func getvalue;
+    
+    /*
+     * getvalue func userdata
+     */
+    void *getvaluedata;
+    
+    /*
+     * callback for each list item, that determines the depth
+     * and indirectly the parent for the item
+     */
+    ui_tree_getdepthfunc getdepth;
+    
+    /*
+     * getdepth func userdata
+     */
+    void *getdepthdata;
+    
+    /*
+     * activated when a list item is selected
+     */
+    ui_callback onactivate;
+    void        *onactivatedata;
+    const char  *onactivate_action;
+    
+    /*
+     * activated, when the additional list item button is clicked
+     */
+    ui_callback onbuttonclick;
+    void        *onbuttonclickdata;
+    const char  *onbuttonclick_action;
+    
+    UiMenuBuilder *contextmenu;
+    
+    const int *states;  
+    const int *visibility_states;;
+};
+
 #define UI_SUBLIST(...) (UiSubList){ __VA_ARGS__ }
 #define UI_SUBLISTS(...) (UiSubList[]){ __VA_ARGS__, (UiSubList){NULL,NULL,NULL,0} }
 
@@ -334,6 +403,7 @@
 #define ui_dropdown(obj, ...) ui_dropdown_create(obj, &(UiListArgs) { __VA_ARGS__ } )
 #define ui_breadcrumbbar(obj, ...) ui_breadcrumbbar_create(obj, &(UiListArgs) { __VA_ARGS__ } )
 #define ui_sourcelist(obj, ...) ui_sourcelist_create(obj, &(UiSourceListArgs) { __VA_ARGS__ } )
+#define ui_sourcelist2(obj, ...) ui_sourcelist2_create(obj, &(UiSourceList2Args) { __VA_ARGS__ } )
 
 UIEXPORT UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args);
 UIEXPORT UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args);
@@ -346,6 +416,7 @@
 UIEXPORT int ui_dropdown_selection(UIWIDGET dropdown);
 
 UIEXPORT UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs *args);
+UIEXPORT UIWIDGET ui_sourcelist2_create(UiObject *obj, UiSourceList2Args *args);
 
 UIEXPORT void ui_sublist_item_set_icon(UiSubListItem *item, const char *icon);
 UIEXPORT void ui_sublist_item_set_label(UiSubListItem *item, const char *label);
--- a/ui/ui/tree.h	Wed Sep 09 18:57:52 2026 +0200
+++ b/ui/ui/tree.h	Thu Sep 10 17:36:06 2026 +0200
@@ -37,7 +37,6 @@
     
 typedef struct UiTreeArgs UiTreeArgs;
     
-typedef int (*ui_tree_getdepthfunc)(UiList *list, void *elm, int row, void *userdata);
 
 struct UiTreeArgs {
     UiBool fill;

mercurial