]> uap-core.de Git - note.git/commitdiff
add UiObjProxy
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Wed, 20 May 2026 18:01:09 +0000 (20:01 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Wed, 20 May 2026 18:01:09 +0000 (20:01 +0200)
ui-rs/src/ui/toolkit.rs
ui/common/wrapper.c
ui/common/wrapper.h
ui/ui/toolkit.h

index 0fc6609840cf0c3c674096cf3192c4f541959483..bf9b5680a881f11cb421038c79f1a9550f71d006 100644 (file)
@@ -33,6 +33,8 @@ use crate::ui::{action_event_wrapper, event, ffi, ui_object_get_context, ui_obje
 
 use std::marker::PhantomData;
 use std::mem;
+use std::ptr::null_mut;
+use std::sync::{Arc, Mutex};
 use crate::ui::ffi::{UiCallback, UiThreadFunc};
 
 pub struct UiContext {
@@ -181,17 +183,6 @@ impl<T: UiModel + UiActions> UiDoc<T> {
             ui_add_action(self.ctx.ptr, cstr.as_ptr(), Some(action_event_wrapper::<T>), ptr as *mut c_void);
         }
     }
-
-    pub fn call_mainthread<F>(&self, mut f: F)
-    where F: FnMut(&mut T) + 'static {
-        let doc = self.clone();
-        call_mainthread(move || {
-            let data = unsafe { doc.get_data_ptr() };
-            unsafe {
-                f(&mut *data);
-            }
-        });
-    }
 }
 
 impl<T> UiObject<T> {
@@ -212,8 +203,12 @@ impl<T> UiObject<T> {
         UiObjRef::from_ptr(self.ptr)
     }
 
-    pub fn window_data<F>(&mut self, mut f: F)
-    where F: FnMut(&mut T) {
+    pub fn obj_proxy(&self) -> UiObjProxy<T> {
+        UiObjProxy::from_ptr(self.ptr)
+    }
+
+    pub fn window_data<F>(&mut self, f: F)
+    where F: FnOnce(&mut T) {
         unsafe {
             let wdata_ptr: *mut T = ui_object_get_windowdata(self.ptr).cast();
             if !wdata_ptr.is_null() {
@@ -222,16 +217,6 @@ impl<T> UiObject<T> {
         }
     }
 
-    pub fn call_mainthread<F>(&self, mut f: F)
-    where F: FnMut(&mut T) + 'static {
-        let mut obj = self.clone();
-        call_mainthread(move || {
-            obj.window_data(|wdata| {
-                f(wdata);
-            });
-        });
-    }
-
     pub fn call_action(&self, action: &str) {
         self.ctx.call_action(action);
     }
@@ -331,6 +316,49 @@ impl<T> Clone for UiObjRef<T> {
     }
 }
 
+impl<T> Default for UiObjRef<T> {
+    fn default() -> Self {
+        UiObjRef::from_ptr(std::ptr::null_mut())
+    }
+}
+
+
+pub struct UiObjProxy<T> {
+    ptr: *mut ffi::UiObject,
+    _data: PhantomData<T>
+}
+
+unsafe impl<T> Send for UiObjProxy<T> {}
+
+impl<T> UiObjProxy<T> {
+    fn from_ptr(ptr: *mut ffi::UiObject) -> UiObjProxy<T> {
+        unsafe {
+            ui_object_ref(ptr);
+        }
+        UiObjProxy { ptr: ptr, _data: PhantomData }
+    }
+
+    pub fn call_mainthread<F>(self, f: F)
+    where F: FnOnce(&mut T) + Send + 'static {
+        call_mainthread(|| {
+            let mut obj: UiObject<T> = UiObject::from_ptr(self.ptr);
+            obj.window_data(|wdata| {
+                f(wdata);
+            });
+            drop(self);
+        });
+    }
+}
+
+impl<T> Drop for UiObjProxy<T> {
+    fn drop(&mut self) {
+        unsafe {
+            ui_mainthread_object_unref(self.ptr);
+        }
+    }
+}
+
+
 pub struct UiText {
     pub ptr: *mut ffi::UiText
 }
@@ -602,6 +630,12 @@ impl<T> UiList<T> {
         }
     }
 
+    pub fn selected_index(&self) -> i32 {
+        unsafe {
+            ui_list_getselection(self.ptr)
+        }
+    }
+
     pub fn set_selection(&mut self, sel: &Vec<i32>) {
         unsafe {
             ui_list_set_selected_indices(self.ptr, sel.as_ptr(), sel.len() as c_int);
@@ -809,7 +843,7 @@ pub unsafe fn ui_list_get<'a, T>(list: *const ffi::UiList, index: usize) -> Opti
 /* ----------------------------------- Event Loop ---------------------------------- */
 
 pub fn call_mainthread<F>(f: F)
-where F: FnOnce() {
+where F: FnOnce() + Send {
     let b = Box::new(f);
     let ptr = Box::into_raw(b);
     unsafe {
@@ -918,6 +952,9 @@ extern "C" {
     pub fn ui_object_ref(obj: *mut ffi::UiObject);
     pub fn ui_object_unref(obj: *mut ffi::UiObject);
 
+    fn ui_mainthread_object_unref(obj: *mut ffi::UiObject);
+    fn ui_mainthread_document_unref(doc: *mut c_void);
+
     fn ui_list_new(ctx: *mut ffi::UiContext, name: *const c_char) -> *mut ffi::UiList;
     fn ui_list_new2(ctx: *mut ffi::UiContext, name: *const c_char, init: UiListInitFunc, userdata: *mut c_void) -> *mut ffi::UiList;
     fn ui_list_class_set_first(list: *mut ffi::UiList, func: UiListFirstFunc);
index 8a891459a5644605ede51969e032a088d8b24ea3..b457e201a98c586c5398d2cb2132e8cd492e72ee 100644 (file)
@@ -50,6 +50,22 @@ void ui_object_set_onclose(UiObject *obj, ui_callback callback, void *userdata)
     obj->onclosedata = userdata;
 }
 
+static int obj_unref(void *ptr) {
+    ui_object_unref(ptr);
+}
+
+void ui_mainthread_object_unref(UiObject *obj) {
+    ui_call_mainthread(obj_unref, obj);
+}
+
+static int doc_unref(void *ptr) {
+    ui_document_unref(ptr);
+}
+
+void ui_mainthread_document_unref(void *doc) {
+    ui_call_mainthread(doc_unref, doc);
+}
+
 
 /* ---------------------------- UiList ---------------------------- */
 
index 1c94d53012a2a27f02eed4db68e9dc36d8092f4f..ddfce62b64eae74107b364987427ca65163cc0e4 100644 (file)
@@ -41,6 +41,9 @@ UIEXPORT void* ui_object_get_windowdata(UiObject *obj);
 UIEXPORT void ui_object_set_windowdata(UiObject *obj, void *windowdata);
 UIEXPORT void ui_object_set_onclose(UiObject *obj, ui_callback callback, void *userdata);
 
+UIEXPORT void ui_mainthread_object_unref(UiObject *obj);
+UIEXPORT void ui_mainthread_document_unref(void *doc);
+
 UIEXPORT void* ui_list_get_data(UiList *list);
 UIEXPORT void* ui_list_get_iter(UiList *list);
 UIEXPORT void ui_list_set_iter(UiList *list, void *iter);
index 7f7ede9f291a4ff00283fb625c68d427ee3c67e4..7f09f9007d48222b69a93be58ad24d3bb7f2a70b 100644 (file)
@@ -596,6 +596,7 @@ UIEXPORT void  ui_free(UiContext *ctx, void *ptr);
 UIEXPORT void* ui_realloc(UiContext *ctx, void *ptr, size_t size);
 UIEXPORT char* ui_strdup(UiContext *ctx, const char *str);
 UIEXPORT void  ui_reg_destructor(UiContext *ctx, void *data, ui_destructor_func destr);
+UIEXPORT void  ui_remove_destructor(UiContext *ctx, void *data);
 UIEXPORT void  ui_set_destructor(void *mem, ui_destructor_func destr);
 
 // types