]> uap-core.de Git - note.git/commitdiff
change onshot event callbacks to FnOnce
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 1 Aug 2026 10:31:03 +0000 (12:31 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 1 Aug 2026 10:31:03 +0000 (12:31 +0200)
ui-rs/src/ui/button.rs
ui-rs/src/ui/event.rs
ui-rs/src/ui/window.rs

index 62c1daf4cd669840e61429b8cde9d8841d28278f..7a90549477e2d24fc2be1e162d86602b76452863 100644 (file)
@@ -383,7 +383,7 @@ impl<'a, T> ButtonBuilder<'a, T> {
 
     pub fn onclick<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 wrapper = Box::new(EventWrapper::new(f) );
         let ptr = self.obj.ctx.reg_box(wrapper);
         unsafe {
             ui_button_args_set_onclick(self.args, Some(event::event_wrapper::<T>));
@@ -575,7 +575,7 @@ impl<'a, T> ToggleBuilder<'a, T> {
 
     pub fn onchange<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 wrapper = Box::new(EventWrapper::new(f) );
         let ptr = self.obj.ctx.reg_box(wrapper);
         unsafe {
             ui_toggle_args_set_onchange(self.args, Some(event::event_wrapper::<T>));
@@ -760,7 +760,7 @@ impl<'a, T> LinkButtonBuilder<'a, T> {
 
     pub fn onclick<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 wrapper = Box::new(EventWrapper::new(f) );
         let ptr = self.obj.ctx.reg_box(wrapper);
         unsafe {
             ui_linkbutton_args_set_onclick(self.args, Some(event::event_wrapper::<T>));
index 506f496d05cda22cf2092aa3c4d92a5d779f4467..139e7f545d4b986c8e5dd335f8e2f8f8e202313a 100644 (file)
@@ -226,14 +226,24 @@ fn get_event_type<'a>(data: &'a mut EventTypeData) -> EventType<'a> {
     }
 }
 
+pub enum EventWrapperCallback<T> {
+    Once(Option<Box<dyn FnOnce(&mut Event<T>)>>),
+    Mut(Box<dyn FnMut(&mut Event<T>)>)
+}
+
 pub struct EventWrapper<T> {
-    pub callback: Box<dyn FnMut(&mut Event<T>)>
+    pub callback: EventWrapperCallback<T>
 }
 
 impl<T> EventWrapper<T> {
     pub fn new<F>(f: F) -> EventWrapper<T>
     where F: FnMut(&mut event::Event<T>) + 'static {
-        EventWrapper { callback: Box::new(f) }
+        EventWrapper { callback: EventWrapperCallback::Mut(Box::new(f)) }
+    }
+
+    pub fn new_once<F>(f: F) -> EventWrapper<T>
+    where F: FnOnce(&mut event::Event<T>) + 'static {
+        EventWrapper { callback: EventWrapperCallback::Once(Some(Box::new(f))) }
     }
 }
 
@@ -261,8 +271,18 @@ pub extern "C" fn event_wrapper<T>(e: *const ffi::UiEvent, data: *mut c_void) {
             intval: ev_int,
             set: ev_set
         };
-
-        (wrapper.callback)(&mut event);
+        
+        
+        match wrapper.callback {
+            EventWrapperCallback::Once(ref mut cb) => {
+                if let Some(cb) = cb.take() {
+                    cb(&mut event);
+                }
+            },
+            EventWrapperCallback::Mut(ref mut cb) => {
+                cb(&mut event);
+            }
+        }
     }
 }
 
index aba6bc7c3a7792fea243ca3146aa6665102e39e5..5ad52d9e61c67d4d33716a6d340463e20b0cf12e 100644 (file)
@@ -75,7 +75,7 @@ impl<T> toolkit::UiObject<T> {
 
     pub fn onclose<F>(&self, f: F)
     where F: FnMut(&mut event::Event<T>) + 'static {
-        let wrapper = Box::new(EventWrapper { callback: Box::new(f) });
+        let wrapper = Box::new(EventWrapper::new(f));
         let ptr = self.ctx.reg_box(wrapper);
         unsafe {
             ui_object_set_onclose(self.ptr, Some(event::event_wrapper::<T>), ptr.cast());
@@ -294,8 +294,8 @@ impl<T> DialogBuilder<T>  {
     }
 
     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) });
+    where F: FnOnce(&mut event::Event<T>) + 'static {
+        let wrapper = Box::new(EventWrapper::new_once(f) );
         let ptr = Box::into_raw(wrapper);
         unsafe {
             ui_dialog_args_set_result(self.args, Some(event::event_wrapper::<T>));
@@ -428,7 +428,7 @@ impl<T: UiModel + UiActions> DialogWindowBuilder<T> {
 
     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.onclick = Some(Box::new(EventWrapper::new(f) ));
         self
     }
 }
@@ -479,8 +479,8 @@ pub fn dialog() -> DialogBuilder<NoAppData> {
 }
 
 fn openfile_dialog<T, F>(obj: &toolkit::UiObject<T>, mode: c_uint, f: F)
-where F: FnMut(&mut event::Event<T>) + 'static {
-    let b: Box<EventWrapper<T>> = Box::new(EventWrapper { callback: Box::new(f) });
+where F: FnOnce(&mut event::Event<T>) + 'static {
+    let b: Box<EventWrapper<T>> = Box::new(EventWrapper::new_once(f));
     let ptr = Box::into_raw(b);
     unsafe {
         ui_openfiledialog(obj.ptr, mode, Some(event_wrapper_oneshot::<T>), ptr as *mut c_void);
@@ -488,9 +488,9 @@ where F: FnMut(&mut event::Event<T>) + 'static {
 }
 
 fn savefile_dialog<T, F>(obj: &toolkit::UiObject<T>, name: &str, f: F)
-where F: FnMut(&mut event::Event<T>) + 'static {
+where F: FnOnce(&mut event::Event<T>) + 'static {
     let cstr = CString::new(name).unwrap();
-    let b: Box<EventWrapper<T>> = Box::new(EventWrapper { callback: Box::new(f) });
+    let b: Box<EventWrapper<T>> = Box::new(EventWrapper::new_once(f));
     let ptr = Box::into_raw(b);
     unsafe {
         ui_savefiledialog(obj.ptr, cstr.as_ptr(), Some(event_wrapper_oneshot::<T>), ptr as *mut c_void);