]> uap-core.de Git - note.git/commitdiff
add dialogwindow main
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 16 May 2026 14:09:13 +0000 (16:09 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 16 May 2026 14:09:13 +0000 (16:09 +0200)
application/src/window.rs
ui-rs/src/ui/ffi.rs
ui-rs/src/ui/toolkit.rs
ui-rs/src/ui/window.rs

index e32fee984b0576295e2eac86cedb8a279efcb5ed..3e3fe1449b3dfc8cdef8c8dbacb44d65dd157d2c 100644 (file)
@@ -41,6 +41,21 @@ pub struct MainWindow {
 impl MainWindow {
     #[action]
     pub fn new_notebook(&mut self, _event: &ActionEvent) {
+        println!("new notebook");
+    }
+
+    #[action]
+    pub fn new_note(&mut self, _event: &ActionEvent) {
+
+    }
+
+    #[action]
+    pub fn go_back(&mut self, _event: &ActionEvent) {
+
+    }
+
+    #[action]
+    pub fn go_forward(&mut self, _event: &ActionEvent) {
 
     }
 }
index baae61064859e96029d7b27059a0b44ce12895e2..bac96bcf0771784ce26e58dbaecd033c045752cb 100644 (file)
@@ -177,6 +177,11 @@ pub struct UiDialogArgs {
     _private: [u8; 0],
 }
 
+#[repr(C)]
+pub struct UiDialogWindowArgs {
+    _private: [u8; 0],
+}
+
 #[repr(C)]
 pub struct UiModel {
     _private: [u8; 0],
index 1923f299e0d535aa906f8451579e62f6e341c6c1..3edc5ff07a61601767f683bf67da34e91c991930 100644 (file)
@@ -109,7 +109,7 @@ impl UiContext {
     }
 }
 
-extern "C" fn destroy_boxed<T>(data: *mut c_void) {
+pub extern "C" fn destroy_boxed<T>(data: *mut c_void) {
     if data.is_null() {
         return;
     }
index fe933e3e50aa186a60284ceb20750809d06f151c..f84d3812e65f03177fe40fff2e9eec4f51d42ae6 100644 (file)
@@ -32,8 +32,8 @@
 use std::ffi::{c_char, c_int, c_void};
 use std::ffi::{c_uint, CString};
 use std::marker::PhantomData;
-use crate::ui::{event, event_wrapper_oneshot, ffi, toolkit, ui_object_ref, ui_update_action_bindings, AppContext, EventWrapper, NoAppData, UiActions, UiModel};
-use crate::ui::ffi::{UiButtonArgs, UiCallback, UiContext, UiDestructor, UiDialogArgs, UiObject};
+use crate::ui::{destroy_boxed, event, event_wrapper_oneshot, ffi, toolkit, ui_object_ref, ui_update_action_bindings, AppContext, EventWrapper, NoAppData, UiActions, UiModel};
+use crate::ui::ffi::{UiButtonArgs, UiCallback, UiContext, UiDestructor, UiDialogArgs, UiDialogWindowArgs, UiObject};
 use crate::ui::widget::widget_fn;
 
 impl<T> toolkit::UiObject<T> {
@@ -68,10 +68,11 @@ enum WindowType {
     Standard,
     SplitView(bool),
     Sidebar,
-    Simple
+    Simple,
+    DialogWindow
 }
 
-fn window_create<T: UiModel + UiActions, F>(title: &str, kind: WindowType, data: T, create_ui: F) -> toolkit::UiObject<T>
+fn window_create<T: UiModel + UiActions, F>(parent: *mut ffi::UiObject, title: &str, kind: WindowType, args: *mut UiDialogWindowArgs, data: T, create_ui: F) -> toolkit::UiObject<T>
 where F: FnOnce(&mut toolkit::UiObject<T>, &mut T) {
     // create the window
     let objptr = unsafe {
@@ -80,7 +81,8 @@ where F: FnOnce(&mut toolkit::UiObject<T>, &mut T) {
             WindowType::SplitView(val) => ui_splitview_window(str.as_ptr(), val as c_int),
             WindowType::Sidebar => ui_sidebar_window(str.as_ptr()),
             WindowType::Standard => ui_window(str.as_ptr()),
-            WindowType::Simple => ui_simple_window(str.as_ptr())
+            WindowType::Simple => ui_simple_window(str.as_ptr()),
+            WindowType::DialogWindow => ui_dialog_window_create(parent, args)
         }
     };
     // because we use additional reference counting in the Rust UiObject wrapper,
@@ -127,26 +129,26 @@ impl<T: UiModel + UiActions> AppContext<T> {
     pub fn window<F>(&self, title: &str, data: T, create_ui: F) -> toolkit::UiObject<T>
     where F: FnOnce(&mut toolkit::UiObject<T>, &mut T)
     {
-        window_create(title, WindowType::Standard, data, create_ui)
+        window_create(std::ptr::null_mut(), title, WindowType::Standard, std::ptr::null_mut(), data, create_ui)
     }
 
     pub fn sidebar_window<F>(&self, title: &str, data: T, create_ui: F) -> toolkit::UiObject<T>
     where F: FnOnce(&mut toolkit::UiObject<T>, &mut T)
     {
-        window_create(title, WindowType::Sidebar, data, create_ui)
+        window_create(std::ptr::null_mut(), title, WindowType::Sidebar, std::ptr::null_mut(), data, create_ui)
     }
 
     pub fn splitview_window<F>(&self, title: &str, sidebar: bool, data: T, create_ui: F) -> toolkit::UiObject<T>
     where F: FnOnce(&mut toolkit::UiObject<T>, &mut T)
     {
-        window_create(title, WindowType::SplitView(sidebar), data, create_ui)
+        window_create(std::ptr::null_mut(), title, WindowType::SplitView(sidebar), std::ptr::null_mut(), data, create_ui)
     }
 }
 
 pub fn simple_window<T: UiModel + UiActions, F>(title: &str, data: T, create_ui: F) -> toolkit::UiObject<T>
 where F: FnOnce(&mut toolkit::UiObject<T>, &mut T)
 {
-    window_create(title, WindowType::Simple, data, create_ui)
+    window_create(std::ptr::null_mut(), title, WindowType::Simple, std::ptr::null_mut(), data, create_ui)
 }
 
 /* ----------------------------------   dialogs   ---------------------------------- */
@@ -246,6 +248,135 @@ impl<T> DialogBuilder<T>  {
     }
 }
 
+
+pub struct DialogWindowBuilder<T> {
+    args: *mut UiDialogWindowArgs,
+    parent: *mut ffi::UiObject,
+    onclick: Option<Box<EventWrapper<T>>>,
+    _marker: PhantomData<T>
+}
+
+impl<T> Drop for DialogWindowBuilder<T> {
+    fn drop(&mut self) {
+        unsafe {
+            ui_dialogwindow_args_free(self.args);
+        }
+    }
+}
+
+impl<T: UiModel + UiActions> DialogWindowBuilder<T> {
+    pub fn create<F>(&mut self, data: T, create_ui: F) -> toolkit::UiObject<T>
+    where F: FnOnce(&mut toolkit::UiObject<T>, &mut T) {
+        let ptr = if let Some(onclick) = self.onclick.take() {
+            let ptr = Box::into_raw(onclick);
+            unsafe {
+                ui_dialogwindow_args_set_onclick(self.args, Some(event::event_wrapper::<T>));
+                ui_dialogwindow_args_set_onclickdata(self.args, ptr as *mut c_void);
+            }
+            ptr
+        } else {
+            std::ptr::null_mut()
+        };
+        let obj = window_create(self.parent, "", WindowType::DialogWindow, self.args, data, create_ui);
+        if !ptr.is_null() {
+            unsafe {
+                ui_reg_destructor(obj.ctx.ptr, ptr as *mut c_void, destroy_boxed::<EventWrapper<T>>);
+            }
+        }
+        self.onclick = None;
+        obj
+    }
+
+    pub fn modal(&mut self, val: bool) -> &mut Self {
+        unsafe {
+            ui_dialogwindow_args_set_modal(self.args, if val { 1 } else { 2 });
+        }
+        self
+    }
+
+    pub fn titlebar_buttons(&mut self, val: bool) -> &mut Self {
+        unsafe {
+            ui_dialogwindow_args_set_titlebar_buttons(self.args, if val { 1 } else { 2 });
+        }
+        self
+    }
+
+    pub fn show_closebutton(&mut self, val: bool) -> &mut Self {
+        unsafe {
+            ui_dialogwindow_args_set_show_closebutton(self.args, if val { 1 } else { 2 });
+        }
+        self
+    }
+
+    pub fn title(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialogwindow_args_set_title(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn lbutton1(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialogwindow_args_set_lbutton1(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn lbutton2(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialogwindow_args_set_lbutton2(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn rbutton3(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialogwindow_args_set_rbutton3(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn rbutton4(&mut self, val: &str) -> &mut Self {
+        let cstr = CString::new(val).unwrap();
+        unsafe {
+            ui_dialogwindow_args_set_rbutton4(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn default_button(&mut self, button: i32) -> &mut Self {
+        unsafe {
+            ui_dialogwindow_args_set_default_button(self.args, button);
+        }
+        self
+    }
+
+    pub fn width(&mut self, val: i32) -> &mut Self {
+        unsafe {
+            ui_dialogwindow_args_set_width(self.args, val);
+        }
+        self
+    }
+
+    pub fn height(&mut self, val: i32) -> &mut Self {
+        unsafe {
+            ui_dialogwindow_args_set_height(self.args, val);
+        }
+        self
+    }
+
+    pub fn onclick<F>(&mut self, f: F) -> &mut Self
+    where F: FnMut(&mut event::Event<T>) + 'static  {
+        self.onclick = Some(Box::new(EventWrapper { callback: Box::new(f) }));
+        self
+    }
+}
+
+
 impl<T> toolkit::UiObject<T> {
     pub fn dialog_builder(&self) -> DialogBuilder<T> {
         DialogBuilder {
@@ -264,6 +395,17 @@ impl<T> toolkit::UiObject<T> {
         builder.create();
     }
 
+    pub fn dialogwindow_builder<D>(&self) -> DialogWindowBuilder<D> {
+        unsafe {
+            DialogWindowBuilder {
+                args: ui_dialogwindow_args_new(),
+                parent: self.ptr,
+                onclick: None,
+                _marker: PhantomData,
+            }
+        }
+    }
+
     pub fn openfile_dialog<F>(&mut self, multiselect: bool, callback: F)
     where F: FnMut(&mut event::Event<T>) + 'static {
         openfile_dialog(self, multiselect as c_uint, callback);
@@ -326,6 +468,7 @@ extern "C" {
     fn ui_simple_window(title: *const c_char) -> *mut UiObject;
 
     fn ui_dialog_create(parent: *mut UiObject, args: *mut UiDialogArgs);
+    fn ui_dialog_window_create(parent: *mut UiObject, args: *mut UiDialogWindowArgs) -> *mut UiObject;
 
     fn ui_window_size(obj: *mut UiObject, width: c_int, height: c_int);
     fn ui_window_menubar_set_visible(obj: *mut UiObject, visible: c_int) -> c_int;
@@ -353,6 +496,26 @@ extern "C" {
     fn ui_dialog_args_set_resultdata(args: *mut UiDialogArgs, data: *mut c_void);
     fn ui_dialog_args_free(args: *mut UiDialogArgs);
 
+    fn ui_dialogwindow_args_new() -> *mut UiDialogWindowArgs;
+    fn ui_dialogwindow_args_set_modal(args: *mut ffi::UiDialogWindowArgs, value: c_int);
+    fn ui_dialogwindow_args_set_titlebar_buttons(args: *mut ffi::UiDialogWindowArgs, value: c_int);
+    fn ui_dialogwindow_args_set_show_closebutton(args: *mut ffi::UiDialogWindowArgs, value: c_int);
+    fn ui_dialogwindow_args_set_title(args: *mut ffi::UiDialogWindowArgs, title: *const c_char);
+    fn ui_dialogwindow_args_set_lbutton1(args: *mut ffi::UiDialogWindowArgs, label: *const c_char);
+    fn ui_dialogwindow_args_set_lbutton2(args: *mut ffi::UiDialogWindowArgs, label: *const c_char);
+    fn ui_dialogwindow_args_set_rbutton3(args: *mut ffi::UiDialogWindowArgs, label: *const c_char);
+    fn ui_dialogwindow_args_set_rbutton4(args: *mut ffi::UiDialogWindowArgs, label: *const c_char);
+    fn ui_dialogwindow_args_set_lbutton1_states(args: *mut ffi::UiDialogWindowArgs, states: *const c_int, numstates: c_int);
+    fn ui_dialogwindow_args_set_lbutton2_states(args: *mut ffi::UiDialogWindowArgs, states: *const c_int, numstates: c_int);
+    fn ui_dialogwindow_args_set_rbutton3_states(args: *mut ffi::UiDialogWindowArgs, states: *const c_int, numstates: c_int);
+    fn ui_dialogwindow_args_set_rbutton4_states(args: *mut ffi::UiDialogWindowArgs, states: *const c_int, numstates: c_int);
+    fn ui_dialogwindow_args_set_default_button(args: *mut ffi::UiDialogWindowArgs, button: c_int);
+    fn ui_dialogwindow_args_set_width(args: *mut ffi::UiDialogWindowArgs, width: c_int);
+    fn ui_dialogwindow_args_set_height(args: *mut ffi::UiDialogWindowArgs, height: c_int);
+    fn ui_dialogwindow_args_set_onclick(args: *mut ffi::UiDialogWindowArgs, cb: UiCallback);
+    fn ui_dialogwindow_args_set_onclickdata(args: *mut ffi::UiDialogWindowArgs, data: *mut c_void);
+    fn ui_dialogwindow_args_free(args: *mut ffi::UiDialogWindowArgs);
+
     fn ui_openfiledialog(obj: *mut ffi::UiObject, mode: c_uint, callback: UiCallback, data: *mut c_void);
     fn ui_savefiledialog(obj: *mut ffi::UiObject, name: *const c_char, callback: UiCallback, data: *mut c_void);
 }