From a30a30b3b1c9454bb989005d31f5078251e3f76c Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Mon, 24 Aug 2026 21:17:34 +0200 Subject: [PATCH] add itemlist container --- ui-rs/src/ui/container.rs | 248 +++++++++++++++++++++++++++++++++++++- ui/common/args.c | 127 +++++++++++++++++++ ui/common/args.h | 30 +++++ ui/gtk/container.c | 2 + ui/qt/model.cpp | 2 +- ui/ui/container.h | 4 + 6 files changed, 411 insertions(+), 2 deletions(-) diff --git a/ui-rs/src/ui/container.rs b/ui-rs/src/ui/container.rs index 2ad6dcb..45b2c2e 100644 --- a/ui-rs/src/ui/container.rs +++ b/ui-rs/src/ui/container.rs @@ -31,8 +31,9 @@ use std::ffi::{c_char, c_int, c_void}; use std::ffi::CString; +use std::marker::PhantomData; use crate::ui::ffi::*; -use crate::ui::{toolkit, Button}; +use crate::ui::{ffi, getvalue_wrapper, toolkit, Button, GetValueWrapper}; use crate::ui::widget::Widget; #[macro_export] @@ -1317,6 +1318,220 @@ impl<'a, T> TabViewBuilder<'a, T> { } } +/* -------------------------------- ItemList Container -------------------------------- */ + +pub type CreateUiFunc = extern "C" fn(obj: *mut ffi::UiObject, row: c_int, elm: *mut c_void, userdata: *mut c_void); + +pub struct ItemListContainerBuilder<'a, T, C> { + args: *mut UiItemListContainerArgs, + obj: &'a mut toolkit::UiObject, + _marker: PhantomData +} + +impl<'a, T, C> ItemListContainerBuilder<'a, T, C> { + pub fn create(&mut self, create_ui: F) -> Container + where F: FnOnce(&mut toolkit::UiObject) { + let widget_ptr = unsafe { ui_itemlist_create(self.obj.ptr, self.args) }; + create_ui(self.obj); + unsafe { + ui_container_begin_close(self.obj.ptr); + ui_container_finish(self.obj.ptr); + } + Container { + ptr: widget_ptr, + } + } + + pub fn fill(&mut self, fill: bool) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_fill(self.args, fill as c_int); + } + self + } + + pub fn hexpand(&mut self, value: bool) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_hexpand(self.args, value as c_int); + } + self + } + + pub fn vexpand(&mut self, value: bool) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_vexpand(self.args, value as c_int); + } + self + } + + pub fn hfill(&mut self, value: bool) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_hfill(self.args, value as c_int); + } + self + } + + pub fn vfill(&mut self, value: bool) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_vfill(self.args, value as c_int); + } + self + } + + pub fn override_defaults(&mut self, value: bool) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_override_defaults(self.args, value as c_int); + } + self + } + + pub fn margin(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_margin(self.args, value); + } + self + } + + pub fn margin_left(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_margin_left(self.args, value); + } + self + } + + pub fn margin_right(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_margin_right(self.args, value); + } + self + } + + pub fn margin_top(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_margin_top(self.args, value); + } + self + } + + pub fn margin_bottom(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_margin_bottom(self.args, value); + } + self + } + + pub fn colspan(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_colspan(self.args, value); + } + self + } + + pub fn rowspan(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_rowspan(self.args, value); + } + self + } + + pub fn name(&mut self, value: &str) -> &mut Self { + let cstr = CString::new(value).unwrap(); + unsafe { + ui_itemlist_container_args_set_name(self.args, cstr.as_ptr()); + } + self + } + + pub fn style_class(&mut self, value: &str) -> &mut Self { + let cstr = CString::new(value).unwrap(); + unsafe { + ui_itemlist_container_args_set_style_class(self.args, cstr.as_ptr()); + } + self + } + + pub fn varname(&mut self, varname: &str) -> &mut Self { + let cstr = CString::new(varname).unwrap(); + unsafe { + ui_itemlist_container_args_set_varname(self.args, cstr.as_ptr()); + } + self + } + + pub fn value(&mut self, value: &toolkit::UiList) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_value(self.args, value.ptr); + } + self + } + + pub fn getvalue(&mut self, f: F) -> &mut Self + where F: Fn(&C, i32, i32) + 'static { + unsafe { + // TODO + } + self + } + + pub fn spacing(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_spacing(self.args, value); + } + self + } + + pub fn sub_margin(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_sub_margin(self.args, value); + } + self + } + + pub fn sub_spacing(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_sub_spacing(self.args, value); + } + self + } + + pub fn sub_columnspacing(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_sub_columnspacing(self.args, value); + } + self + } + + pub fn sub_rowspacing(&mut self, value: i32) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_sub_rowspacing(self.args, value); + } + self + } + + pub fn subcontainer_type(&mut self, subtype: SubContainer) -> &mut Self { + unsafe { + ui_itemlist_container_args_set_subcontainer(self.args, subtype as c_int); + } + self + } + + pub fn visibility_states>(&mut self, states: &[S]) -> &mut Self { + let states: Vec = states.iter().copied().map(Into::into).collect(); + unsafe { + ui_itemlist_container_args_set_visibility_states(self.args, states.as_ptr(), states.len() as c_int); + } + self + } +} + +impl<'a, T, C> Drop for ItemListContainerBuilder<'a, T, C> { + fn drop(&mut self) { + unsafe { + ui_itemlist_container_args_free(self.args); + } + } +} + + /* -------------------------------- C functions -------------------------------- */ unsafe extern "C" { @@ -1336,6 +1551,7 @@ unsafe extern "C" { fn ui_right_panel_create(obj: *mut UiObject, args: *const UiSidebarArgs) -> *mut c_void; fn ui_tabview_create(obj: *mut UiObject, args: *const UiTabViewArgs) -> *mut c_void; fn ui_tab_create(obj: *mut UiObject, label: *const c_char) -> *mut c_void; + fn ui_itemlist_create(obj: *mut UiObject, args: *const UiItemListContainerArgs) -> *mut c_void; fn ui_newline(obj: *mut UiObject); @@ -1453,4 +1669,34 @@ unsafe extern "C" { fn ui_tabview_args_set_value(args: *mut UiTabViewArgs, ivalue: *mut UiInteger); fn ui_tabview_args_set_visibility_states(args: *mut UiTabViewArgs, states: *const c_int, numstates: c_int); fn ui_tabview_args_free(args: *mut UiTabViewArgs); + + fn ui_itemlist_container_args_new() -> *mut UiItemListContainerArgs; + fn ui_itemlist_container_args_set_fill(args: *mut UiItemListContainerArgs, fill: c_int); + fn ui_itemlist_container_args_set_hexpand(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_vexpand(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_hfill(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_vfill(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_override_defaults(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_margin(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_margin_left(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_margin_right(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_margin_top(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_margin_bottom(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_colspan(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_rowspan(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_name(args: *mut UiItemListContainerArgs, name: *const c_char); + fn ui_itemlist_container_args_set_style_class(args: *mut UiItemListContainerArgs, classname: *const c_char); + fn ui_itemlist_container_args_set_spacing(args: *mut UiItemListContainerArgs, spacing: c_int); + fn ui_itemlist_container_args_set_sub_margin(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_sub_spacing(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_sub_rowspacing(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_sub_columnspacing(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_value(args: *mut UiItemListContainerArgs, value: *mut ffi::UiList); + fn ui_itemlist_container_args_set_varname(args: *mut UiItemListContainerArgs, varname: *const c_char); + fn ui_itemlist_container_args_set_create_ui(args: *mut UiItemListContainerArgs, callback: CreateUiFunc); + fn ui_itemlist_container_args_set_userdata(args: *mut UiItemListContainerArgs, data: *mut c_void); + fn ui_itemlist_container_args_set_visibility_states(args: *mut UiItemListContainerArgs, states: *const c_int, numstates: c_int); + fn ui_itemlist_container_args_set_container(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_set_subcontainer(args: *mut UiItemListContainerArgs, value: c_int); + fn ui_itemlist_container_args_free(args: *mut UiItemListContainerArgs); } diff --git a/ui/common/args.c b/ui/common/args.c index 4c950ff..822a7c9 100644 --- a/ui/common/args.c +++ b/ui/common/args.c @@ -1053,6 +1053,133 @@ void ui_tabview_args_free(UiTabViewArgs *args) { free(args); } +/* ------------------------- UiItemList ------------------------------*/ + +UiItemListContainerArgs* ui_itemlist_container_args_new(void) { + UiItemListContainerArgs *args = malloc(sizeof(UiItemListContainerArgs)); + memset(args, 0, sizeof(UiItemListContainerArgs)); + return args; +} + +void ui_itemlist_container_args_set_fill(UiItemListContainerArgs *args, UiBool fill) { + args->fill = fill; +} + +void ui_itemlist_container_args_set_hexpand(UiItemListContainerArgs *args, UiBool value) { + args->hexpand = value; +} + +void ui_itemlist_container_args_set_vexpand(UiItemListContainerArgs *args, UiBool value) { + args->vexpand = value; +} + +void ui_itemlist_container_args_set_hfill(UiItemListContainerArgs *args, UiBool value) { + args->hfill = value; +} + +void ui_itemlist_container_args_set_vfill(UiItemListContainerArgs *args, UiBool value) { + args->vfill = value; +} + +void ui_itemlist_container_args_set_override_defaults(UiItemListContainerArgs *args, UiBool value) { + args->override_defaults = value; +} + +void ui_itemlist_container_args_set_margin(UiItemListContainerArgs *args, int value) { + args->margin = value; +} + +void ui_itemlist_container_args_set_margin_left(UiItemListContainerArgs *args, int value) { + args->margin_left = value; +} + +void ui_itemlist_container_args_set_margin_right(UiItemListContainerArgs *args, int value) { + args->margin_right = value; +} + +void ui_itemlist_container_args_set_margin_top(UiItemListContainerArgs *args, int value) { + args->margin_top = value; +} + +void ui_itemlist_container_args_set_margin_bottom(UiItemListContainerArgs *args, int value) { + args->margin_bottom = value; +} + +void ui_itemlist_container_args_set_colspan(UiItemListContainerArgs *args, int colspan) { + args->colspan = colspan; +} + +void ui_itemlist_container_args_set_rowspan(UiItemListContainerArgs *args, int rowspan) { + args->rowspan = rowspan; +} + +void ui_itemlist_container_args_set_name(UiItemListContainerArgs *args, const char *name) { + args->name = strdup(name); +} + +void ui_itemlist_container_args_set_style_class(UiItemListContainerArgs *args, const char *classname) { + args->style_class = strdup(classname); +} + +void ui_itemlist_container_args_set_spacing(UiItemListContainerArgs *args, int value) { + args->spacing = value; +} + +void ui_itemlist_container_args_set_sub_margin(UiItemListContainerArgs *args, int value) { + args->sub_margin = value; +} + +void ui_itemlist_container_args_set_sub_spacing(UiItemListContainerArgs *args, int value) { + args->sub_spacing = value; +} + +void ui_itemlist_container_args_set_sub_columnspacing(UiItemListContainerArgs *args, int value) { + args->sub_columnspacing = value; +} + +void ui_itemlist_container_args_set_sub_rowspacing(UiItemListContainerArgs *args, int value) { + args->sub_rowspacing = value; +} + +void ui_itemlist_container_args_set_value(UiItemListContainerArgs *args, UiList *value) { + args->value = value; +} + +void ui_itemlist_container_args_set_varname(UiItemListContainerArgs *args, const char *varname) { + args->varname = strdup(varname); +} + +void ui_itemlist_container_args_set_create_ui(UiItemListContainerArgs *args, ui_create_ui_func callback) { + args->create_ui = callback; +} + +void ui_itemlist_container_args_set_userdata(UiItemListContainerArgs *args, void *userdata) { + args->userdata = userdata; +} + +void ui_itemlist_container_args_set_container(UiItemListContainerArgs *args, UiSubContainerType container_type) { + args->container = container_type; +} + +void ui_itemlist_container_args_set_subcontainer(UiItemListContainerArgs *args, UiSubContainerType container_type) { + args->subcontainer = container_type; +} + +void ui_itemlist_container_args_set_visibility_states(UiItemListContainerArgs *args, int *states, int numstates) { + args->visibility_states = calloc(numstates+1, sizeof(int)); + memcpy((void*)args->visibility_states, states, numstates * sizeof(int)); + ((int*)args->visibility_states)[numstates] = -1; +} + +void ui_itemlist_container_args_free(UiItemListContainerArgs *args) { + free((void*)args->name); + free((void*)args->style_class); + free((void*)args->varname); + free((void*)args->visibility_states); + free(args); +} + + /* ------------------------- UiWidgetArgs ----------------------------*/ diff --git a/ui/common/args.h b/ui/common/args.h index b400f51..ec13c64 100644 --- a/ui/common/args.h +++ b/ui/common/args.h @@ -268,6 +268,36 @@ UIEXPORT void ui_tabview_args_set_subcontainer(UiTabViewArgs *args, UiSubContain UIEXPORT void ui_tabview_args_set_visibility_states(UiTabViewArgs *args, int *states, int numstates); UIEXPORT void ui_tabview_args_free(UiTabViewArgs *args); +UIEXPORT UiItemListContainerArgs* ui_itemlist_container_args_new(void); +UIEXPORT void ui_itemlist_container_args_set_fill(UiItemListContainerArgs *args, UiBool fill); +UIEXPORT void ui_itemlist_container_args_set_hexpand(UiItemListContainerArgs *args, UiBool value); +UIEXPORT void ui_itemlist_container_args_set_vexpand(UiItemListContainerArgs *args, UiBool value); +UIEXPORT void ui_itemlist_container_args_set_hfill(UiItemListContainerArgs *args, UiBool value); +UIEXPORT void ui_itemlist_container_args_set_vfill(UiItemListContainerArgs *args, UiBool value); +UIEXPORT void ui_itemlist_container_args_set_override_defaults(UiItemListContainerArgs *args, UiBool value); +UIEXPORT void ui_itemlist_container_args_set_margin(UiItemListContainerArgs *args, int value); +UIEXPORT void ui_itemlist_container_args_set_margin_left(UiItemListContainerArgs *args, int value); +UIEXPORT void ui_itemlist_container_args_set_margin_right(UiItemListContainerArgs *args, int value); +UIEXPORT void ui_itemlist_container_args_set_margin_top(UiItemListContainerArgs *args, int value); +UIEXPORT void ui_itemlist_container_args_set_margin_bottom(UiItemListContainerArgs *args, int value); +UIEXPORT void ui_itemlist_container_args_set_colspan(UiItemListContainerArgs *args, int colspan); +UIEXPORT void ui_itemlist_container_args_set_rowspan(UiItemListContainerArgs *args, int rowspan); +UIEXPORT void ui_itemlist_container_args_set_name(UiItemListContainerArgs *args, const char *name); +UIEXPORT void ui_itemlist_container_args_set_style_class(UiItemListContainerArgs *args, const char *classname); +UIEXPORT void ui_itemlist_container_args_set_spacing(UiItemListContainerArgs *args, int value); +UIEXPORT void ui_itemlist_container_args_set_sub_margin(UiItemListContainerArgs *args, int value); +UIEXPORT void ui_itemlist_container_args_set_sub_spacing(UiItemListContainerArgs *args, int value); +UIEXPORT void ui_itemlist_container_args_set_sub_columnspacing(UiItemListContainerArgs *args, int value); +UIEXPORT void ui_itemlist_container_args_set_sub_rowspacing(UiItemListContainerArgs *args, int value); +UIEXPORT void ui_itemlist_container_args_set_value(UiItemListContainerArgs *args, UiList *value); +UIEXPORT void ui_itemlist_container_args_set_varname(UiItemListContainerArgs *args, const char *varname); +UIEXPORT void ui_itemlist_container_args_set_create_ui(UiItemListContainerArgs *args, ui_create_ui_func callback); +UIEXPORT void ui_itemlist_container_args_set_userdata(UiItemListContainerArgs *args, void *userdata); +UIEXPORT void ui_itemlist_container_args_set_container(UiItemListContainerArgs *args, UiSubContainerType container_type); +UIEXPORT void ui_itemlist_container_args_set_subcontainer(UiItemListContainerArgs *args, UiSubContainerType container_type); +UIEXPORT void ui_itemlist_container_args_set_visibility_states(UiItemListContainerArgs *args, int *states, int numstates); +UIEXPORT void ui_itemlist_container_args_free(UiItemListContainerArgs *args); + UIEXPORT UiWidgetArgs* ui_widget_args_new(void); UIEXPORT void ui_widget_args_set_fill(UiWidgetArgs *args, UiBool fill); UIEXPORT void ui_widget_args_set_hexpand(UiWidgetArgs *args, UiBool value); diff --git a/ui/gtk/container.c b/ui/gtk/container.c index 30960ff..5174dc6 100644 --- a/ui/gtk/container.c +++ b/ui/gtk/container.c @@ -1359,6 +1359,8 @@ UIWIDGET ui_itemlist_create(UiObject *obj, UiItemListContainerArgs *args) { G_CALLBACK(destroy_itemlist_container), container); + uic_widget_set_visibility_states(obj->ctx, box, args->visibility_states); + return box; } diff --git a/ui/qt/model.cpp b/ui/qt/model.cpp index c74c43f..be84b32 100644 --- a/ui/qt/model.cpp +++ b/ui/qt/model.cpp @@ -235,7 +235,7 @@ void TableModel::selectionChanged(const QItemSelection& selected, const QItemSel event.intval = sel.count; event.set = ui_get_setop(); - if(onactivate) { + if(sel.count > 0 && onactivate) { onactivate(&event, onactivatedata); } if(onselection) { diff --git a/ui/ui/container.h b/ui/ui/container.h index 187f221..0e8ee99 100644 --- a/ui/ui/container.h +++ b/ui/ui/container.h @@ -217,6 +217,8 @@ typedef struct UiSplitPaneArgs { const int *visibility_states; } UiSplitPaneArgs; +typedef void (*ui_create_ui_func)(UiObject *, int, void *, void *); + typedef struct UiItemListContainerArgs { UiBool fill; UiBool hexpand; @@ -264,6 +266,8 @@ typedef struct UiItemListContainerArgs { * item root container */ UiSubContainerType subcontainer; + + const int *visibility_states; } UiItemListContainerArgs; -- 2.52.0