]> uap-core.de Git - note.git/commitdiff
add dialog
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 8 May 2026 18:47:05 +0000 (20:47 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 8 May 2026 18:47:05 +0000 (20:47 +0200)
ui-rs/src/ui/event.rs
ui-rs/src/ui/ffi.rs
ui-rs/src/ui/window.rs

index 80659f8fd1d5abc56bfb0bf3a1adc757217a0cec..b39967f7530241983bc615c0b40c4d39a3974e87 100644 (file)
@@ -162,6 +162,13 @@ pub extern "C" fn event_wrapper<T>(e: *const ffi::UiEvent, data: *mut c_void) {
     }
 }
 
+pub extern "C" fn event_wrapper_oneshot<T>(e: *const ffi::UiEvent, data: *mut c_void) {
+    event_wrapper::<T>(e, data);
+    unsafe {
+        drop(Box::from_raw(data as *mut EventWrapper<T>));
+    }
+}
+
 pub struct ActionEventWrapper<T> {
     pub callback: Box<dyn FnMut(&mut T, &ActionEvent)>,
     pub target: *mut T
index c83306378a546dedb3a4a3e0b30ae5c9ed4e7cd7..58fbd2d2557b461ef71188f9cc7e9a2c01581bd8 100644 (file)
@@ -169,6 +169,11 @@ pub struct UiSourceListArgs {
     _private: [u8; 0],
 }
 
+#[repr(C)]
+pub struct UiDialogArgs {
+    _private: [u8; 0],
+}
+
 #[repr(C)]
 pub struct UiModel {
     _private: [u8; 0],
index 554b2e07210b3e0427d3a1e39a5298191dde0924..6bdd6fac4825c9b880bb584687db3528145f2c73 100644 (file)
 use std::ffi::{c_char, c_int, c_void};
 use std::ffi::CString;
 use std::marker::PhantomData;
-use crate::ui::{toolkit, AppContext, UiActions, UiModel};
-use crate::ui::ffi::{UiContext, UiDestructor, UiObject};
-
-extern "C" {
-    fn ui_window(title: *const c_char) -> *mut UiObject;
-    fn ui_sidebar_window(title: *const c_char) -> *mut UiObject;
-    fn ui_splitview_window(title: *const c_char, sidebar: c_int) -> *mut UiObject;
-    fn ui_simple_window(title: *const c_char) -> *mut UiObject;
-
-
-    fn ui_show(ui: *const UiObject);
-
-    pub fn ui_object_get_windowdata(obj: *const UiObject) -> *mut c_void;
-    pub fn ui_object_set_windowdata(obj: *mut UiObject, data: *mut c_void);
-    pub fn ui_object_get_context(obj: *const UiObject) -> *mut UiContext;
-
-    pub fn ui_reg_destructor(ctx: *mut UiContext, data: *mut c_void, destructor: UiDestructor);
-}
-
+use crate::ui::{event, ffi, toolkit, AppContext, EventWrapper, UiActions, UiModel};
+use crate::ui::ffi::{UiButtonArgs, UiCallback, UiContext, UiDestructor, UiDialogArgs, UiObject};
+use crate::ui::widget::widget_fn;
 
 impl<T> toolkit::UiObject<T> {
     pub fn show(&self) {
@@ -60,6 +44,8 @@ impl<T> toolkit::UiObject<T> {
     }
 }
 
+/* ---------------------------------- main windows ---------------------------------- */
+
 enum WindowType {
     Standard,
     SplitView(bool),
@@ -135,3 +121,147 @@ where F: FnOnce(&mut toolkit::UiObject<T>, &mut T)
 {
     window_create(title, WindowType::Simple, data, create_ui)
 }
+
+/* ----------------------------------   dialogs   ---------------------------------- */
+
+pub struct DialogBuilder<T> {
+    args: *mut UiDialogArgs,
+    parent: *mut ffi::UiObject,
+    _marker: PhantomData<T>
+}
+
+impl<T> Drop for DialogBuilder<T> {
+    fn drop(&mut self) {
+        unsafe {
+            ui_dialog_args_free(self.args);
+        }
+    }
+}
+
+impl<T> DialogBuilder<T>  {
+    pub fn create(&mut self) {
+        unsafe {
+            ui_dialog_create(self.parent, self.args);
+        }
+    }
+
+    pub fn title(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialog_args_set_title(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn content(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialog_args_set_content(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn button1_label(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialog_args_set_button1_label(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn button2_label(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialog_args_set_button2_label(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn closebutton_label(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialog_args_set_closebutton_label(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn input_value(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialog_args_set_input_value(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn input(&mut self, enable: bool) -> &mut Self {
+        unsafe {
+            ui_dialog_args_set_input(self.args, enable as c_int);
+        }
+        self
+    }
+
+    pub fn password(&mut self, enable: bool) -> &mut Self {
+        unsafe {
+            ui_dialog_args_set_password(self.args, enable as c_int);
+        }
+        self
+    }
+
+    pub fn result<F>(&mut self, f: F) -> &mut Self
+    where F: FnMut(&mut event::Event<T>) + 'static {
+        let wrapper = Box::new(EventWrapper { callback: Box::new(f) });
+        let ptr = Box::into_raw(wrapper);
+        unsafe {
+            ui_dialog_args_set_result(self.args, Some(event::event_wrapper::<T>));
+            ui_dialog_args_set_resultdata(self.args, ptr as *mut c_void);
+        }
+        self
+    }
+}
+
+impl<T> toolkit::UiObject<T> {
+    pub fn dialog_builder(&self) -> DialogBuilder<T> {
+        DialogBuilder {
+            args: unsafe { ui_dialog_args_new() },
+            parent: self.ptr,
+            _marker: PhantomData,
+        }
+    }
+
+    widget_fn!(dialog, dialog_builder, DialogBuilder);
+}
+
+
+/* ---------------------------------- C functions ---------------------------------- */
+
+extern "C" {
+    fn ui_window(title: *const c_char) -> *mut UiObject;
+    fn ui_sidebar_window(title: *const c_char) -> *mut UiObject;
+    fn ui_splitview_window(title: *const c_char, sidebar: c_int) -> *mut UiObject;
+    fn ui_simple_window(title: *const c_char) -> *mut UiObject;
+
+    fn ui_dialog_create(parent: *mut UiObject, args: *mut UiDialogArgs);
+    
+
+
+    fn ui_show(ui: *const UiObject);
+
+    pub fn ui_object_get_windowdata(obj: *const UiObject) -> *mut c_void;
+    pub fn ui_object_set_windowdata(obj: *mut UiObject, data: *mut c_void);
+    pub fn ui_object_get_context(obj: *const UiObject) -> *mut UiContext;
+
+    pub fn ui_reg_destructor(ctx: *mut UiContext, data: *mut c_void, destructor: UiDestructor);
+
+    fn ui_dialog_args_new() -> *mut UiDialogArgs;
+    fn ui_dialog_args_set_title(args: *mut UiDialogArgs, title: *const c_char);
+    fn ui_dialog_args_set_content(args: *mut UiDialogArgs, content: *const c_char);
+    fn ui_dialog_args_set_button1_label(args: *mut UiDialogArgs, label: *const c_char);
+    fn ui_dialog_args_set_button2_label(args: *mut UiDialogArgs, label: *const c_char);
+    fn ui_dialog_args_set_closebutton_label(args: *mut UiDialogArgs, label: *const c_char);
+    fn ui_dialog_args_set_input_value(args: *mut UiDialogArgs, value: *const c_char);
+    fn ui_dialog_args_set_input(args: *mut UiDialogArgs, input: c_int);
+    fn ui_dialog_args_set_password(args: *mut UiDialogArgs, password: c_int);
+    fn ui_dialog_args_set_result(args: *mut UiDialogArgs, callback: UiCallback);
+    fn ui_dialog_args_set_resultdata(args: *mut UiDialogArgs, data: *mut c_void);
+    fn ui_dialog_args_free(args: *mut UiDialogArgs);
+}