From: Olaf Wintermann Date: Tue, 19 May 2026 17:24:25 +0000 (+0200) Subject: add UiObjRef X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=5b97d0f6d12f369908a0560a9ac4128392b9d87c;p=note.git add UiObjRef --- diff --git a/application/src/window.rs b/application/src/window.rs index e3a8bf3..c95d98f 100644 --- a/application/src/window.rs +++ b/application/src/window.rs @@ -35,7 +35,6 @@ use crate::newnotebook::new_notebook_dialog; #[derive(UiModel)] pub struct MainWindow { - pub obj: Option>, pub backend: BackendHandle, #[bind] @@ -46,7 +45,6 @@ pub struct MainWindow { impl MainWindow { pub fn new(app: &App) -> MainWindow { MainWindow { - obj: None, backend: app.backend.clone(), notebooks: UiSourceList::default() } @@ -85,9 +83,8 @@ impl MainWindow { pub fn create_window(app: &App, ctx: &AppContext) -> UiObject { let windowdata: MainWindow = MainWindow::new(app); - let mut window = ctx.splitview_window("note", true, windowdata, |obj, data| { + let window = ctx.splitview_window("note", true, windowdata, |obj, data| { init_window_data(data, app); - data.obj = Some(obj.clone()); obj.sidebar_builder().create(|obj|{ obj.sourcelist(|b|{ @@ -130,10 +127,8 @@ pub fn create_window(app: &App, ctx: &AppContext) -> UiObject(&mut self, b: Box) -> *mut B { + pub fn reg_box(&self, b: Box) -> *mut B { let ptr = Box::into_raw(b); unsafe { ui_reg_destructor(self.ptr, ptr as *mut c_void, destroy_boxed::); @@ -196,6 +196,7 @@ impl UiDoc { impl UiObject { pub fn from_ptr(ptr: *mut ffi::UiObject) -> UiObject { + assert!(!ptr.is_null()); let ctx_ptr = unsafe { ui_object_get_context(ptr) }; unsafe { ui_object_ref(ptr); @@ -207,6 +208,10 @@ impl UiObject { } } + pub fn obj_ref(&self) -> UiObjRef { + UiObjRef::from_ptr(self.ptr) + } + pub fn window_data(&mut self, mut f: F) where F: FnMut(&mut T) { unsafe { @@ -268,6 +273,64 @@ impl Drop for UiObject { } } +pub struct UiObjRef { + ptr: Box<*mut ffi::UiObject>, + _data: PhantomData +} + +impl UiObjRef { + pub fn from_ptr(obj_ptr: *mut ffi::UiObject) -> UiObjRef { + let obj_ref = UiObjRef { ptr: Box::new(obj_ptr), _data: PhantomData }; + if !obj_ptr.is_null() { + let ctx = unsafe { ui_object_get_context(obj_ptr) }; + unsafe { + let xptr = &*obj_ref.ptr as *const *mut ffi::UiObject; + ui_reg_destructor(ctx, xptr as *mut c_void, ref_obj_destroyed); + } + } + obj_ref + } + + pub fn get_object(&self) -> Option> { + if self.ptr.is_null() { + None + } else { + Some(UiObject::from_ptr(*self.ptr)) + } + } +} + +impl Drop for UiObjRef { + fn drop(&mut self) { + unsafe { + let obj_ptr = *self.ptr; + + // only unregister if the object still exists + if !obj_ptr.is_null() { + let ctx = unsafe { ui_object_get_context(obj_ptr) }; + let xptr = &mut *self.ptr as *mut *mut ffi::UiObject; + ui_remove_destructor(ctx, xptr as *mut c_void); + } + } + } +} + +extern "C" fn ref_obj_destroyed(data: *mut c_void) { + unsafe { + let ptr_ptr = data as *mut *mut ffi::UiObject; + + if !ptr_ptr.is_null() { + *ptr_ptr = std::ptr::null_mut(); + } + } +} + +impl Clone for UiObjRef { + fn clone(&self) -> Self { + UiObjRef::from_ptr(*self.ptr) + } +} + pub struct UiText { pub ptr: *mut ffi::UiText } diff --git a/ui-rs/src/ui/window.rs b/ui-rs/src/ui/window.rs index 6751154..c98cf3a 100644 --- a/ui-rs/src/ui/window.rs +++ b/ui-rs/src/ui/window.rs @@ -49,7 +49,7 @@ impl toolkit::UiObject { } } - pub fn onclose(&mut self, f: F) + pub fn onclose(&self, f: F) where F: FnMut(&mut event::Event) + 'static { let wrapper = Box::new(EventWrapper { callback: Box::new(f) }); let ptr = self.ctx.reg_box(wrapper); @@ -58,19 +58,19 @@ impl toolkit::UiObject { } } - pub fn set_size(&mut self, width: u32, height: u32) { + pub fn set_size(&self, width: u32, height: u32) { unsafe { ui_window_size(self.ptr, width as c_int, height as c_int); } } - pub fn set_menubar_visible(&mut self, visible: bool) { + pub fn set_menubar_visible(&self, visible: bool) { unsafe { ui_window_menubar_set_visible(self.ptr, visible as c_int); } } - pub fn enable_fullscreen(&mut self, fullscreen: bool) { + pub fn enable_fullscreen(&self, fullscreen: bool) { unsafe { ui_window_fullscreen(self.ptr, fullscreen as c_int); } @@ -499,6 +499,7 @@ extern "C" { fn ui_object_set_onclose(obj: *const UiObject, onclose: UiCallback, data: *mut c_void); pub fn ui_reg_destructor(ctx: *mut UiContext, data: *mut c_void, destructor: UiDestructor); + pub fn ui_remove_destructor(ctx: *mut UiContext, data: *mut c_void); fn ui_dialog_args_new() -> *mut UiDialogArgs; fn ui_dialog_args_set_title(args: *mut UiDialogArgs, title: *const c_char);