]> uap-core.de Git - note.git/commitdiff
refactor widget creation functions
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 3 Apr 2026 15:20:16 +0000 (17:20 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 3 Apr 2026 15:20:16 +0000 (17:20 +0200)
application/src/main.rs
ui-rs/src/ui/button.rs
ui-rs/src/ui/container.rs
ui-rs/src/ui/mod.rs
ui-rs/src/ui/widget.rs [new file with mode: 0644]

index 3f3e2ce4b8d1837b708b487fef09170cf37ff0b3..5ade6716eba364a91e21c50cc11c90d7e5b4536f 100644 (file)
@@ -12,12 +12,29 @@ struct App;
 impl ui::Application for App {
     fn on_startup(&self) {
         let mut obj = ui::window("note");
-        obj.button().label("Hello").build();
-        obj.hbox().build(|obj| {
-            obj.button().label("HButton 1").build();
-            obj.button().label("HButton 2").build();
-            obj.button().label("HButton 3").build();
+        obj.button(|b| {
+            b.label("Hello");
         });
+        obj.hbox_builder().build(|obj| {
+            obj.button(|b|{
+                b.label("HButton 1");
+            });
+            obj.button(|b|{
+                b.label("HButton 2");
+            });
+            obj.button(|b|{
+                b.label("HButton 3");
+            });
+        });
+
+        obj.hbox(|_b| {
+
+            },
+            |obj| {
+                obj.button(|b|{ b.label("HButton X1"); });
+                obj.button(|b|{ b.label("HButton X2"); });
+            });
+
         obj.show();
     }
 }
index 0180f16f09b6a631b0a74bd98e132ca917e120ce..c61fad0e47518d6844e274e9a5ec315af960ad88 100644 (file)
@@ -3,8 +3,9 @@
 
 use std::ffi::{c_char, c_int, c_void};
 use std::ffi::CString;
-use crate::ui::toolkit;
+use crate::ui::{toolkit};
 use crate::ui::ffi::*;
+use crate::ui::widget::widget_fn;
 
 extern "C" {
     fn ui_button_create(obj: *const UiObject, args: *const UiButtonArgs);
@@ -91,35 +92,43 @@ pub enum LabelType {
 pub type ToggleButtonCreate = fn(*const UiObject, *const UiToggleArgs);
 
 impl toolkit::UiObject {
-    pub fn button(&self) -> ButtonBuilder {
+    widget_fn!(button, button_builder, ButtonBuilder);
+    widget_fn!(togglebutton, togglebutton_builder, ToggleBuilder);
+    widget_fn!(checkbox, checkbox_builder, ToggleBuilder);
+    widget_fn!(switch, switch_builder, ToggleBuilder);
+    widget_fn!(radiobutton, radiobutton_builder, ToggleBuilder);
+
+    pub fn button_builder(&self) -> ButtonBuilder {
         unsafe {
             let args = ui_button_args_new();
             ButtonBuilder { args: args, obj: self.ptr }
         }
     }
 
-    pub fn togglebutton(&self) -> ToggleBuilder {
+    pub fn togglebutton_builder(&self) -> ToggleBuilder {
         unsafe {
             let args = ui_toggle_args_new();
             ToggleBuilder { args: args, obj: self.ptr, create: togglebutton_create }
         }
     }
 
-    pub fn checkbox(&self) -> ToggleBuilder {
+
+
+    pub fn checkbox_builder(&self) -> ToggleBuilder {
         unsafe {
             let args = ui_toggle_args_new();
             ToggleBuilder { args: args, obj: self.ptr, create: checkbox_create }
         }
     }
 
-    pub fn switch(&self) -> ToggleBuilder {
+    pub fn switch_builder(&self) -> ToggleBuilder {
         unsafe {
             let args = ui_toggle_args_new();
             ToggleBuilder { args: args, obj: self.ptr, create: switch_create }
         }
     }
 
-    pub fn radiobutton(&self) -> ToggleBuilder {
+    pub fn radiobutton_builder(&self) -> ToggleBuilder {
         unsafe {
             let args = ui_toggle_args_new();
             ToggleBuilder { args: args, obj: self.ptr, create: radiobutton_create }
@@ -168,104 +177,104 @@ impl Drop for ToggleBuilder {
 }
 
 impl ButtonBuilder {
-    pub fn build(self) {
+    pub fn build(&mut self) {
         unsafe {
             ui_button_create(self.obj, self.args);
         }
     }
 
-    pub fn fill(self, fill: bool) -> Self {
+    pub fn fill(&mut self, fill: bool) -> &mut Self {
         unsafe {
             ui_button_args_set_fill(self.args, if fill { 1 } else { 0 });
         }
         self
     }
 
-    pub fn hexpand(self, value: bool) -> Self {
+    pub fn hexpand(&mut self, value: bool) -> &mut Self {
         unsafe {
             ui_button_args_set_hexpand(self.args, if value { 1 } else { 0 });
         }
         self
     }
 
-    pub fn vexpand(self, value: bool) -> Self {
+    pub fn vexpand(&mut self, value: bool) -> &mut Self {
         unsafe {
             ui_button_args_set_vexpand(self.args, if value { 1 } else { 0 });
         }
         self
     }
 
-    pub fn hfill(self, value: bool) -> Self {
+    pub fn hfill(&mut self, value: bool) -> &mut Self {
         unsafe {
             ui_button_args_set_hfill(self.args, if value { 1 } else { 0 });
         }
         self
     }
 
-    pub fn vfill(self, value: bool) -> Self {
+    pub fn vfill(&mut self, value: bool) -> &mut Self {
         unsafe {
             ui_button_args_set_vfill(self.args, if value { 1 } else { 0 });
         }
         self
     }
 
-    pub fn override_defaults(self, value: bool) -> Self {
+    pub fn override_defaults(&mut self, value: bool) -> &mut Self {
         unsafe {
             ui_button_args_set_override_defaults(self.args, if value { 1 } else { 0 });
         }
         self
     }
 
-    pub fn margin(self, value: i32) -> Self {
+    pub fn margin(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_button_args_set_margin(self.args, value);
         }
         self
     }
 
-    pub fn margin_left(self, value: i32) -> Self {
+    pub fn margin_left(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_button_args_set_margin_left(self.args, value);
         }
         self
     }
 
-    pub fn margin_right(self, value: i32) -> Self {
+    pub fn margin_right(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_button_args_set_margin_right(self.args, value);
         }
         self
     }
 
-    pub fn margin_top(self, value: i32) -> Self {
+    pub fn margin_top(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_button_args_set_margin_top(self.args, value);
         }
         self
     }
 
-    pub fn margin_bottom(self, value: i32) -> Self {
+    pub fn margin_bottom(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_button_args_set_margin_bottom(self.args, value);
         }
         self
     }
 
-    pub fn colspan(self, value: i32) -> Self {
+    pub fn colspan(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_button_args_set_colspan(self.args, value);
         }
         self
     }
 
-    pub fn rowspan(self, value: i32) -> Self {
+    pub fn rowspan(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_button_args_set_rowspan(self.args, value);
         }
         self
     }
 
-    pub fn name(self, value: &str) -> Self {
+    pub fn name(&mut self, value: &str) -> &mut Self {
         let cstr = CString::new(value).unwrap();
         unsafe {
             ui_button_args_set_name(self.args, cstr.as_ptr());
@@ -273,7 +282,7 @@ impl ButtonBuilder {
         self
     }
 
-    pub fn style_class(self, value: &str) -> Self {
+    pub fn style_class(&mut self, value: &str) -> &mut Self {
         let cstr = CString::new(value).unwrap();
         unsafe {
             ui_button_args_set_style_class(self.args, cstr.as_ptr());
@@ -281,7 +290,7 @@ impl ButtonBuilder {
         self
     }
 
-    pub fn label(self, label: &str) -> Self {
+    pub fn label(&mut self, label: &str) -> &mut Self {
         let cstr = CString::new(label).unwrap();
         unsafe {
             ui_button_args_set_label(self.args, cstr.as_ptr());
@@ -289,7 +298,7 @@ impl ButtonBuilder {
         self
     }
 
-    pub fn icon(self, icon: &str) -> Self {
+    pub fn icon(&mut self, icon: &str) -> &mut Self {
         let cstr = CString::new(icon).unwrap();
         unsafe {
             ui_button_args_set_label(self.args, cstr.as_ptr());
@@ -297,7 +306,7 @@ impl ButtonBuilder {
         self
     }
 
-    pub fn tooltip(self, tooltip: &str) -> Self {
+    pub fn tooltip(&mut self, tooltip: &str) -> &mut Self {
         let cstr = CString::new(tooltip).unwrap();
         unsafe {
             ui_button_args_set_tooltip(self.args, cstr.as_ptr());
@@ -305,7 +314,7 @@ impl ButtonBuilder {
         self
     }
 
-    pub fn labeltype(self, ltype: LabelType) -> Self {
+    pub fn labeltype(&mut self, ltype: LabelType) -> &mut Self {
         let lt = ltype as i32;
         unsafe {
             ui_button_args_set_labeltype(self.args, lt);
@@ -317,102 +326,102 @@ impl ButtonBuilder {
 }
 
 impl ToggleBuilder {
-    pub fn build(self) {
+    pub fn build(&mut self) {
         (self.create)(self.obj, self.args)
     }
 
-    pub fn fill(self, fill: bool) -> Self {
+    pub fn fill(&mut self, fill: bool) -> &mut Self {
         unsafe {
             ui_toggle_args_set_fill(self.args, if fill { 1 } else { 0 });
         }
         self
     }
 
-    pub fn hexpand(self, value: bool) -> Self {
+    pub fn hexpand(&mut self, value: bool) -> &mut Self {
         unsafe {
             ui_toggle_args_set_hexpand(self.args, if value { 1 } else { 0 });
         }
         self
     }
 
-    pub fn vexpand(self, value: bool) -> Self {
+    pub fn vexpand(&mut self, value: bool) -> &mut Self {
         unsafe {
             ui_toggle_args_set_vexpand(self.args, if value { 1 } else { 0 });
         }
         self
     }
 
-    pub fn hfill(self, value: bool) -> Self {
+    pub fn hfill(&mut self, value: bool) -> &mut Self {
         unsafe {
             ui_toggle_args_set_hfill(self.args, if value { 1 } else { 0 });
         }
         self
     }
 
-    pub fn vfill(self, value: bool) -> Self {
+    pub fn vfill(&mut self, value: bool) -> &mut Self {
         unsafe {
             ui_toggle_args_set_vfill(self.args, if value { 1 } else { 0 });
         }
         self
     }
 
-    pub fn override_defaults(self, value: bool) -> Self {
+    pub fn override_defaults(&mut self, value: bool) -> &mut Self {
         unsafe {
             ui_toggle_args_set_override_defaults(self.args, if value { 1 } else { 0 });
         }
         self
     }
 
-    pub fn margin(self, value: i32) -> Self {
+    pub fn margin(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_toggle_args_set_margin(self.args, value);
         }
         self
     }
 
-    pub fn margin_left(self, value: i32) -> Self {
+    pub fn margin_left(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_toggle_args_set_margin_left(self.args, value);
         }
         self
     }
 
-    pub fn margin_right(self, value: i32) -> Self {
+    pub fn margin_right(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_toggle_args_set_margin_right(self.args, value);
         }
         self
     }
 
-    pub fn margin_top(self, value: i32) -> Self {
+    pub fn margin_top(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_toggle_args_set_margin_top(self.args, value);
         }
         self
     }
 
-    pub fn margin_bottom(self, value: i32) -> Self {
+    pub fn margin_bottom(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_toggle_args_set_margin_bottom(self.args, value);
         }
         self
     }
 
-    pub fn colspan(self, value: i32) -> Self {
+    pub fn colspan(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_toggle_args_set_colspan(self.args, value);
         }
         self
     }
 
-    pub fn rowspan(self, value: i32) -> Self {
+    pub fn rowspan(&mut self, value: i32) -> &mut Self {
         unsafe {
             ui_toggle_args_set_rowspan(self.args, value);
         }
         self
     }
 
-    pub fn name(self, value: &str) -> Self {
+    pub fn name(&mut self, value: &str) -> &mut Self {
         let cstr = CString::new(value).unwrap();
         unsafe {
             ui_toggle_args_set_name(self.args, cstr.as_ptr());
@@ -420,7 +429,7 @@ impl ToggleBuilder {
         self
     }
 
-    pub fn style_class(self, value: &str) -> Self {
+    pub fn style_class(&mut self, value: &str) -> &mut Self {
         let cstr = CString::new(value).unwrap();
         unsafe {
             ui_toggle_args_set_style_class(self.args, cstr.as_ptr());
@@ -428,7 +437,7 @@ impl ToggleBuilder {
         self
     }
 
-    pub fn label(self, label: &str) -> Self {
+    pub fn label(&mut self, label: &str) -> &mut Self {
         let cstr = CString::new(label).unwrap();
         unsafe {
             ui_toggle_args_set_label(self.args, cstr.as_ptr());
@@ -436,7 +445,7 @@ impl ToggleBuilder {
         self
     }
 
-    pub fn icon(self, icon: &str) -> Self {
+    pub fn icon(&mut self, icon: &str) -> &mut Self {
         let cstr = CString::new(icon).unwrap();
         unsafe {
             ui_toggle_args_set_label(self.args, cstr.as_ptr());
@@ -444,7 +453,7 @@ impl ToggleBuilder {
         self
     }
 
-    pub fn tooltip(self, tooltip: &str) -> Self {
+    pub fn tooltip(&mut self, tooltip: &str) -> &mut Self {
         let cstr = CString::new(tooltip).unwrap();
         unsafe {
             ui_toggle_args_set_tooltip(self.args, cstr.as_ptr());
@@ -452,7 +461,7 @@ impl ToggleBuilder {
         self
     }
 
-    pub fn labeltype(self, ltype: LabelType) -> Self {
+    pub fn labeltype(&mut self, ltype: LabelType) -> &mut Self {
         let lt = ltype as i32;
         unsafe {
             ui_toggle_args_set_labeltype(self.args, lt);
@@ -460,7 +469,7 @@ impl ToggleBuilder {
         self
     }
 
-    pub fn varname(self, varname: &str) -> Self {
+    pub fn varname(&mut self, varname: &str) -> &mut Self {
         let cstr = CString::new(varname).unwrap();
         unsafe {
             ui_toggle_args_set_varname(self.args, cstr.as_ptr());
@@ -468,11 +477,11 @@ impl ToggleBuilder {
         self
     }
 
-    pub fn value(self, value: &toolkit::UiInteger) {
+    pub fn value(&mut self, value: &toolkit::UiInteger) {
         unsafe {
             ui_toggle_args_set_value(self.args, value.ptr);
         }
     }
 
-    // TODO: value, callback, states
+    // TODO: callback, states
 }
\ No newline at end of file
index 4a0aec2b4e634b8d8b849e31fc91dc992b5e51f6..637901ab288fd379be8454a6959ddb074085b907 100644 (file)
@@ -5,6 +5,20 @@ use std::ffi::{c_char, c_int, c_void};
 use crate::ui::ffi::*;
 use crate::ui::{toolkit};
 
+macro_rules! container_fn {
+    ($fn_name:ident, $builder_fn:ident, $builder_ty:ident) => {
+        pub fn $fn_name<F, U>(&mut self, build: F, ui: U)
+        where
+            F: Fn(&mut $builder_ty),
+            U: FnOnce(&mut toolkit::UiObject)
+        {
+            let mut builder = self.$builder_fn();
+            build(&mut builder);
+            builder.build(ui);
+        }
+    };
+}
+
 extern "C" {
     fn ui_container_begin_close(obj: *mut UiObject);
     fn ui_container_finish(obj: *mut UiObject) -> c_int;
@@ -66,7 +80,10 @@ fn grid_create(obj: *mut UiObject, args: *const UiContainerArgs) {
 }
 
 impl toolkit::UiObject {
-    pub fn vbox(&mut self) -> ContainerBuilder
+    container_fn!(vbox, vbox_builder, ContainerBuilder);
+    container_fn!(hbox, hbox_builder, ContainerBuilder);
+
+    pub fn vbox_builder(&mut self) -> ContainerBuilder
     {
         unsafe {
             let args = ui_container_args_new();
@@ -78,7 +95,7 @@ impl toolkit::UiObject {
         }
     }
 
-    pub fn hbox(&mut self) -> ContainerBuilder
+    pub fn hbox_builder(&mut self) -> ContainerBuilder
     {
         unsafe {
             let args = ui_container_args_new();
@@ -90,7 +107,7 @@ impl toolkit::UiObject {
         }
     }
 
-    pub fn grid(&mut self) -> ContainerBuilder
+    pub fn grid_builder(&mut self) -> ContainerBuilder
     {
         unsafe {
             let args = ui_container_args_new();
@@ -104,7 +121,7 @@ impl toolkit::UiObject {
 }
 
 impl<'a> ContainerBuilder<'a> {
-    pub fn build<F>(self, create_ui: F)
+    pub fn build<F>(&mut self, create_ui: F)
     where F: FnOnce(&mut toolkit::UiObject) {
         (self.create)(self.obj.ptr, self.args);
         create_ui(self.obj);
index 0dba9938ac82b7b1fb3ecd87084c6169491f228d..b6b6f5e3ab698e298d185caef8366d77dbafb28e 100644 (file)
@@ -4,6 +4,7 @@ mod application;
 mod window;
 mod button;
 mod container;
+mod widget;
 
 pub use toolkit::*;
 pub use application::*;
diff --git a/ui-rs/src/ui/widget.rs b/ui-rs/src/ui/widget.rs
new file mode 100644 (file)
index 0000000..ca383d5
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Create a closure-based widget creation function
+ *
+ * Example: 
+ * pub fn button_builder(&self) -> ButtonBuilder { ... }
+ * widget_fn!(button, button_builder, ButtonBuilder);
+ *
+ * This creates a function
+ * pub fn button(&self, build: F)
+ *
+ * That can be used like:
+ * obj.button(|b| {
+ *     b.label("Hello");   
+ * }
+ */
+macro_rules! widget_fn {
+    ($fn_name:ident, $builder_fn:ident, $builder_ty:ident) => {
+        pub fn $fn_name<F>(&self, build: F)
+        where
+            F: Fn(&mut $builder_ty),
+        {
+            let mut builder = self.$builder_fn();
+            build(&mut builder);
+            builder.build();
+        }
+    };
+}
+
+pub(super) use widget_fn;
\ No newline at end of file