From: Olaf Wintermann Date: Fri, 8 May 2026 18:47:05 +0000 (+0200) Subject: add dialog X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=40652f07fea1612efa0c3325bb68e17d65ce4f7d;p=note.git add dialog --- diff --git a/ui-rs/src/ui/event.rs b/ui-rs/src/ui/event.rs index 80659f8..b39967f 100644 --- a/ui-rs/src/ui/event.rs +++ b/ui-rs/src/ui/event.rs @@ -162,6 +162,13 @@ pub extern "C" fn event_wrapper(e: *const ffi::UiEvent, data: *mut c_void) { } } +pub extern "C" fn event_wrapper_oneshot(e: *const ffi::UiEvent, data: *mut c_void) { + event_wrapper::(e, data); + unsafe { + drop(Box::from_raw(data as *mut EventWrapper)); + } +} + pub struct ActionEventWrapper { pub callback: Box, pub target: *mut T diff --git a/ui-rs/src/ui/ffi.rs b/ui-rs/src/ui/ffi.rs index c833063..58fbd2d 100644 --- a/ui-rs/src/ui/ffi.rs +++ b/ui-rs/src/ui/ffi.rs @@ -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], diff --git a/ui-rs/src/ui/window.rs b/ui-rs/src/ui/window.rs index 554b2e0..6bdd6fa 100644 --- a/ui-rs/src/ui/window.rs +++ b/ui-rs/src/ui/window.rs @@ -32,25 +32,9 @@ 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 toolkit::UiObject { pub fn show(&self) { @@ -60,6 +44,8 @@ impl toolkit::UiObject { } } +/* ---------------------------------- main windows ---------------------------------- */ + enum WindowType { Standard, SplitView(bool), @@ -135,3 +121,147 @@ where F: FnOnce(&mut toolkit::UiObject, &mut T) { window_create(title, WindowType::Simple, data, create_ui) } + +/* ---------------------------------- dialogs ---------------------------------- */ + +pub struct DialogBuilder { + args: *mut UiDialogArgs, + parent: *mut ffi::UiObject, + _marker: PhantomData +} + +impl Drop for DialogBuilder { + fn drop(&mut self) { + unsafe { + ui_dialog_args_free(self.args); + } + } +} + +impl DialogBuilder { + 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(&mut self, f: F) -> &mut Self + where F: FnMut(&mut event::Event) + '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::)); + ui_dialog_args_set_resultdata(self.args, ptr as *mut c_void); + } + self + } +} + +impl toolkit::UiObject { + pub fn dialog_builder(&self) -> DialogBuilder { + 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); +}