]> uap-core.de Git - note.git/commitdiff
force a global type for app windows
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 24 Apr 2026 07:10:34 +0000 (09:10 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 24 Apr 2026 07:10:34 +0000 (09:10 +0200)
application/src/main.rs
ui-rs/src/ui/application.rs
ui-rs/src/ui/window.rs

index db83377af50d3247389cee9557d789fe29c5b8bf..bb42ca5f1dcd7c334afcc4e5d1fbc24b625a7b92 100644 (file)
@@ -5,7 +5,7 @@ fn main() {
     ui::app_init("note");
 
     let mut app = App;
-    ui::app_run(&mut app);
+    ui::app_run::<TestData>(&mut app);
 }
 
 struct App;
@@ -28,10 +28,10 @@ impl TestData {
     }
 }
 
-fn create_window() {
-    let testdata = TestData::default();
+fn create_window(app: &AppContext<TestData>) {
+    let testdata: TestData = Default::default();
 
-    let window = ui::window("note", testdata, |obj, data| {
+    let window = app.window("note", testdata, |obj, data| {
         let list = data.list.data();
         list.push(10);
         list.push(11);
@@ -66,8 +66,8 @@ fn create_window() {
     window.show();
 }
 
-impl ui::Application for App {
-    fn on_startup(&mut self) {
-        create_window();
+impl Application<TestData> for App {
+    fn on_startup(&mut self, app: &AppContext<TestData>) {
+        create_window(app);
     }
 }
index a3398421b9c18d5665ec92e771f849f93db9d8cb..7b40e91f525fbdd9f2d064aefb36686fc707611d 100644 (file)
@@ -1,12 +1,18 @@
 #[allow(unused_imports)]
 
 use std::ffi::{c_char, c_int, c_void, CString};
+use std::marker::PhantomData;
 use crate::ui::ffi::{UiCallback, UiEvent};
+use crate::ui::{UiActions, UiModel};
 
-pub trait Application {
-    fn on_startup(&mut self);
+pub trait Application<T: UiModel + UiActions> {
+    fn on_startup(&mut self, app: &AppContext<T>);
 
-    fn on_exit(&mut self) { }
+    fn on_exit(&mut self, _app: &AppContext<T>) { }
+}
+
+pub struct AppContext<T: UiModel + UiActions> {
+    _marker: PhantomData<T>,
 }
 
 
@@ -17,34 +23,40 @@ extern "C" {
     fn ui_onexit(callback: UiCallback, userdata: *mut c_void);
 }
 
-extern "C" fn app_startup(_event: *const UiEvent, data: *mut c_void) {
+extern "C" fn app_startup<T: UiModel + UiActions>(_event: *const UiEvent, data: *mut c_void) {
     unsafe {
-        let app_ptr = data as *mut AppWrapper;
-        let app_ref: &mut AppWrapper = &mut *app_ptr;
-        app_ref.app.on_startup();
+        let app_ptr = data as *mut AppWrapper<T>;
+        let app_ref: &mut AppWrapper<T> = &mut *app_ptr;
+        let ctx = AppContext::<T> {
+            _marker: PhantomData,
+        };
+        app_ref.app.on_startup(&ctx);
     }
 }
 
-extern "C" fn app_exit(_event: *const UiEvent, data: *mut c_void) {
+extern "C" fn app_exit<T: UiModel + UiActions>(_event: *const UiEvent, data: *mut c_void) {
     unsafe {
-        let app_ptr = data as *mut AppWrapper;
-        let app_ref: &mut AppWrapper = &mut *app_ptr;
-        app_ref.app.on_exit();
+        let app_ptr = data as *mut AppWrapper<T>;
+        let app_ref: &mut AppWrapper<T> = &mut *app_ptr;
+        let ctx = AppContext::<T> {
+            _marker: PhantomData,
+        };
+        app_ref.app.on_exit(&ctx);
     }
 }
 
-pub fn app_run(app: &mut dyn Application) {
+pub fn app_run<T: UiModel + UiActions>(app: &mut dyn Application<T>) {
     let mut wrapper = AppWrapper { app: app };
     unsafe {
-        let ptr: *mut AppWrapper = &mut wrapper;
+        let ptr: *mut AppWrapper<T> = &mut wrapper;
         let c_ptr: *mut c_void = ptr as *mut c_void;
-        ui_onstartup(Some(app_startup), c_ptr);
-        ui_onexit(Some(app_exit), c_ptr);
+        ui_onstartup(Some(app_startup::<T>), c_ptr);
+        ui_onexit(Some(app_exit::<T>), c_ptr);
         ui_main();
     }
 }
 
 #[repr(C)]
-struct AppWrapper<'a> {
-    app: &'a mut dyn Application,
+struct AppWrapper<'a, T> {
+    app: &'a mut dyn Application<T>,
 }
\ No newline at end of file
index d61df8aeef215659d9eb53ca9837c7428567b2ec..b00494a99e6ab4f4cf78a2cfa7ce9957f7f73022 100644 (file)
@@ -4,7 +4,7 @@
 use std::ffi::{c_char, c_int, c_void};
 use std::ffi::CString;
 use std::marker::PhantomData;
-use crate::ui::{toolkit, UiActions, UiModel};
+use crate::ui::{toolkit, AppContext, UiActions, UiModel};
 use crate::ui::ffi::{UiContext, UiDestructor, UiObject};
 
 extern "C" {
@@ -82,22 +82,24 @@ where F: FnOnce(&mut toolkit::UiObject<T>, &mut T) {
     obj
 }
 
-pub fn 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::Standard, data, create_ui)
-}
+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)
+    }
 
-pub fn sidebar_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::Sidebar, 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)
+    }
 
-pub fn splitview_window<T: UiModel + UiActions, F>(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)
+    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)
+    }
 }
 
 pub fn simple_window<T: UiModel + UiActions, F>(title: &str, data: T, create_ui: F) -> toolkit::UiObject<T>
@@ -105,4 +107,3 @@ where F: FnOnce(&mut toolkit::UiObject<T>, &mut T)
 {
     window_create(title, WindowType::Simple, data, create_ui)
 }
-