From f20b7eaf846d290db44ea0ad534ad68a206d7326 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sat, 4 Apr 2026 12:20:49 +0200 Subject: [PATCH] add frame containers --- ui-rs/src/ui/container.rs | 321 ++++++++++++++++++++++++++++++++++---- ui-rs/src/ui/ffi.rs | 30 ++++ 2 files changed, 320 insertions(+), 31 deletions(-) diff --git a/ui-rs/src/ui/container.rs b/ui-rs/src/ui/container.rs index a274afe..3423d4c 100644 --- a/ui-rs/src/ui/container.rs +++ b/ui-rs/src/ui/container.rs @@ -20,38 +20,15 @@ macro_rules! container_fn { }; } -extern "C" { - fn ui_container_begin_close(obj: *mut UiObject); - fn ui_container_finish(obj: *mut UiObject) -> c_int; - - fn ui_vbox_create(obj: *mut UiObject, args: *const UiContainerArgs) -> *mut c_void; - fn ui_hbox_create(obj: *mut UiObject, args: *const UiContainerArgs) -> *mut c_void; - fn ui_grid_create(obj: *mut UiObject, args: *const UiContainerArgs) -> *mut c_void; - +pub enum SubContainer { + VBox = 0, + HBox = 1, + Grid = 2, + NoSub = 3, +} - fn ui_container_args_new() -> *mut UiContainerArgs; - fn ui_container_args_set_fill(args: *mut UiContainerArgs, fill: c_int); - fn ui_container_args_set_hexpand(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_vexpand(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_hfill(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_vfill(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_override_defaults(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_margin(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_margin_left(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_margin_right(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_margin_top(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_margin_bottom(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_colspan(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_rowspan(args: *mut UiContainerArgs, value: c_int); - fn ui_container_args_set_name(args: *mut UiContainerArgs, name: *const c_char); - fn ui_container_args_set_style_class(args: *mut UiContainerArgs, classname: *const c_char); - fn ui_container_args_set_spacing(args: *mut UiContainerArgs, spacing: c_int); - fn ui_container_args_set_columnspacing(args: *mut UiContainerArgs, spacing: c_int); - fn ui_container_args_set_rowspacing(args: *mut UiContainerArgs, spacing: c_int); - fn ui_container_args_set_visibility_states(args: *mut UiContainerArgs, states: *const c_int, numstates: c_int); - fn ui_container_args_free(args: *mut UiContainerArgs); -} +/* -------------------------------- Box/Grid Container -------------------------------- */ pub type ContainerCreate = fn(*mut UiObject, *const UiContainerArgs); pub type CreateContainerUI = fn(obj: &toolkit::UiObject); @@ -83,6 +60,7 @@ fn grid_create(obj: *mut UiObject, args: *const UiContainerArgs) { impl toolkit::UiObject { container_fn!(vbox, vbox_builder, ContainerBuilder); container_fn!(hbox, hbox_builder, ContainerBuilder); + container_fn!(grid, grid_builder, ContainerBuilder); pub fn vbox_builder(&mut self) -> ContainerBuilder { @@ -267,4 +245,285 @@ impl<'a> Drop for ContainerBuilder<'a> { ui_container_args_free(self.args); } } -} \ No newline at end of file +} + +/* -------------------------------- Frame Container -------------------------------- */ + +pub type FrameCreate = fn(*mut UiObject, *const UiFrameArgs); + +pub struct FrameBuilder<'a> { + args: *mut UiFrameArgs, + obj: &'a mut toolkit::UiObject, + create: FrameCreate +} + +fn frame_create(obj: *mut UiObject, args: *const UiFrameArgs) { + unsafe { + ui_frame_create(obj, args); + } +} + +fn expander_create(obj: *mut UiObject, args: *const UiFrameArgs) { + unsafe { + ui_expander_create(obj, args); + } +} + +fn scrolledwindow_create(obj: *mut UiObject, args: *const UiFrameArgs) { + unsafe { + ui_scrolledwindow_create(obj, args); + } +} + +impl toolkit::UiObject { + container_fn!(frame, frame_builder, FrameBuilder); + container_fn!(expander, expander_builder, FrameBuilder); + container_fn!(scrolledwindow, scrolledwindow_builder, FrameBuilder); + + pub fn frame_builder(&mut self) -> FrameBuilder + { + unsafe { + let args = ui_frame_args_new(); + FrameBuilder { + args, + obj: self, + create: frame_create + } + } + } + + pub fn expander_builder(&mut self) -> FrameBuilder + { + unsafe { + let args = ui_frame_args_new(); + FrameBuilder { + args, + obj: self, + create: expander_create + } + } + } + + pub fn scrolledwindow_builder(&mut self) -> FrameBuilder + { + unsafe { + let args = ui_frame_args_new(); + FrameBuilder { + args, + obj: self, + create: scrolledwindow_create + } + } + } +} + +impl<'a> FrameBuilder<'a> { + pub fn create(&mut self, create_ui: F) + where F: FnOnce(&mut toolkit::UiObject) { + (self.create)(self.obj.ptr, self.args); + create_ui(self.obj); + unsafe { + ui_container_begin_close(self.obj.ptr); + ui_container_finish(self.obj.ptr); + } + } + + pub fn fill(&mut self, fill: bool) -> &mut Self { + unsafe { + ui_frame_args_set_fill(self.args, if fill { 1 } else { 0 }); + } + self + } + + pub fn hexpand(&mut self, value: bool) -> &mut Self { + unsafe { + ui_frame_args_set_hexpand(self.args, if value { 1 } else { 0 }); + } + self + } + + pub fn vexpand(&mut self, value: bool) -> &mut Self { + unsafe { + ui_frame_args_set_vexpand(self.args, if value { 1 } else { 0 }); + } + self + } + + pub fn hfill(&mut self, value: bool) -> &mut Self { + unsafe { + ui_frame_args_set_hfill(self.args, if value { 1 } else { 0 }); + } + self + } + + pub fn vfill(&mut self, value: bool) -> &mut Self { + unsafe { + ui_frame_args_set_vfill(self.args, if value { 1 } else { 0 }); + } + self + } + + pub fn override_defaults(&mut self, value: bool) -> &mut Self { + unsafe { + ui_frame_args_set_override_defaults(self.args, if value { 1 } else { 0 }); + } + self + } + + pub fn margin(&mut self, value: i32) -> &mut Self { + unsafe { + ui_frame_args_set_margin(self.args, value); + } + self + } + + pub fn margin_left(&mut self, value: i32) -> &mut Self { + unsafe { + ui_frame_args_set_margin_left(self.args, value); + } + self + } + + pub fn margin_right(&mut self, value: i32) -> &mut Self { + unsafe { + ui_frame_args_set_margin_right(self.args, value); + } + self + } + + pub fn margin_top(&mut self, value: i32) -> &mut Self { + unsafe { + ui_frame_args_set_margin_top(self.args, value); + } + self + } + + pub fn margin_bottom(&mut self, value: i32) -> &mut Self { + unsafe { + ui_frame_args_set_margin_bottom(self.args, value); + } + self + } + + pub fn colspan(&mut self, value: i32) -> &mut Self { + unsafe { + ui_frame_args_set_colspan(self.args, value); + } + self + } + + pub fn rowspan(&mut self, value: i32) -> &mut Self { + unsafe { + ui_frame_args_set_rowspan(self.args, value); + } + self + } + + pub fn name(&mut self, value: &str) -> &mut Self { + let cstr = CString::new(value).unwrap(); + unsafe { + ui_frame_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_frame_args_set_style_class(self.args, cstr.as_ptr()); + } + self + } + + pub fn spacing(&mut self, value: i32) -> &mut Self { + unsafe { + ui_frame_args_set_spacing(self.args, value); + } + self + } + + pub fn columnspacing(&mut self, value: i32) -> &mut Self { + unsafe { + ui_frame_args_set_columnspacing(self.args, value); + } + self + } + + pub fn rowspacing(&mut self, value: i32) -> &mut Self { + unsafe { + ui_frame_args_set_rowspacing(self.args, value); + } + self + } +} + +impl<'a> Drop for FrameBuilder<'a> { + fn drop(&mut self) { + unsafe { + ui_frame_args_free(self.args); + } + } +} + + +/* -------------------------------- C functions -------------------------------- */ + +extern "C" { + fn ui_container_begin_close(obj: *mut UiObject); + fn ui_container_finish(obj: *mut UiObject) -> c_int; + + fn ui_vbox_create(obj: *mut UiObject, args: *const UiContainerArgs) -> *mut c_void; + fn ui_hbox_create(obj: *mut UiObject, args: *const UiContainerArgs) -> *mut c_void; + fn ui_grid_create(obj: *mut UiObject, args: *const UiContainerArgs) -> *mut c_void; + fn ui_frame_create(obj: *mut UiObject, args: *const UiFrameArgs) -> *mut c_void; + fn ui_expander_create(obj: *mut UiObject, args: *const UiFrameArgs) -> *mut c_void; + fn ui_scrolledwindow_create(obj: *mut UiObject, args: *const UiFrameArgs) -> *mut c_void; + + + fn ui_container_args_new() -> *mut UiContainerArgs; + fn ui_container_args_set_fill(args: *mut UiContainerArgs, fill: c_int); + fn ui_container_args_set_hexpand(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_vexpand(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_hfill(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_vfill(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_override_defaults(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_margin(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_margin_left(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_margin_right(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_margin_top(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_margin_bottom(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_colspan(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_rowspan(args: *mut UiContainerArgs, value: c_int); + fn ui_container_args_set_name(args: *mut UiContainerArgs, name: *const c_char); + fn ui_container_args_set_style_class(args: *mut UiContainerArgs, classname: *const c_char); + fn ui_container_args_set_spacing(args: *mut UiContainerArgs, spacing: c_int); + fn ui_container_args_set_columnspacing(args: *mut UiContainerArgs, spacing: c_int); + fn ui_container_args_set_rowspacing(args: *mut UiContainerArgs, spacing: c_int); + fn ui_container_args_set_visibility_states(args: *mut UiContainerArgs, states: *const c_int, numstates: c_int); + fn ui_container_args_free(args: *mut UiContainerArgs); + + fn ui_frame_args_new() -> *mut UiFrameArgs; + fn ui_frame_args_set_fill(args: *mut UiFrameArgs, fill: c_int); + fn ui_frame_args_set_hexpand(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_vexpand(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_hfill(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_vfill(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_override_defaults(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_margin(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_margin_left(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_margin_right(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_margin_top(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_margin_bottom(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_colspan(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_rowspan(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_name(args: *mut UiFrameArgs, name: *const c_char); + fn ui_frame_args_set_style_class(args: *mut UiFrameArgs, classname: *const c_char); + fn ui_frame_args_set_spacing(args: *mut UiFrameArgs, spacing: c_int); + fn ui_frame_args_set_columnspacing(args: *mut UiFrameArgs, spacing: c_int); + fn ui_frame_args_set_rowspacing(args: *mut UiFrameArgs, spacing: c_int); + fn ui_frame_args_set_visibility_states(args: *mut UiFrameArgs, states: *const c_int, numstates: c_int); + fn ui_frame_args_set_label(args: *mut UiFrameArgs, name: *const c_char); + fn ui_frame_args_set_expanded(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_set_subcontainer(args: *mut UiFrameArgs, value: c_int); + fn ui_frame_args_free(args: *mut UiFrameArgs); +} diff --git a/ui-rs/src/ui/ffi.rs b/ui-rs/src/ui/ffi.rs index 939280a..624291c 100644 --- a/ui-rs/src/ui/ffi.rs +++ b/ui-rs/src/ui/ffi.rs @@ -55,6 +55,36 @@ pub struct UiContainerArgs { _private: [u8; 0], } +#[repr(C)] +pub struct UiFrameArgs { + _private: [u8; 0], +} + +#[repr(C)] +pub struct UiTabViewArgs { + _private: [u8; 0], +} + +#[repr(C)] +pub struct UiHeaderbarArgs { + _private: [u8; 0], +} + +#[repr(C)] +pub struct UiSidebarArgs { + _private: [u8; 0], +} + +#[repr(C)] +pub struct UiSplitPaneArgs { + _private: [u8; 0], +} + +#[repr(C)] +pub struct UiItemListContainerArgs { + _private: [u8; 0], +} + #[repr(C)] pub struct UiButtonArgs { _private: [u8; 0], -- 2.47.3