#[derive(UiModel)]
pub struct MainWindow {
- pub obj: Option<UiObject<MainWindow>>,
pub backend: BackendHandle,
#[bind]
impl MainWindow {
pub fn new(app: &App) -> MainWindow {
MainWindow {
- obj: None,
backend: app.backend.clone(),
notebooks: UiSourceList::default()
}
pub fn create_window(app: &App, ctx: &AppContext<MainWindow>) -> UiObject<MainWindow> {
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|{
});
window.show();
- window.onclose(|event| {
- println!("window closing");
- event.data.obj = None;
- });
+ //window.onclose(|event| {
+ //});
window
}
#![allow(dead_code)]
use std::ffi::{c_char, c_int, c_void, CStr, CString};
-use crate::ui::{action_event_wrapper, event, ffi, ui_object_get_context, ui_object_get_windowdata, ui_reg_destructor, ActionEventWrapper, EventWrapper, SubList};
+use crate::ui::{action_event_wrapper, event, ffi, ui_object_get_context, ui_object_get_windowdata, ui_reg_destructor, ui_remove_destructor, ActionEventWrapper, Event, EventWrapper, SubList};
use std::marker::PhantomData;
use std::mem;
}
}
- pub fn reg_box<B>(&mut self, b: Box<B>) -> *mut B {
+ pub fn reg_box<B>(&self, b: Box<B>) -> *mut B {
let ptr = Box::into_raw(b);
unsafe {
ui_reg_destructor(self.ptr, ptr as *mut c_void, destroy_boxed::<B>);
impl<T> UiObject<T> {
pub fn from_ptr(ptr: *mut ffi::UiObject) -> UiObject<T> {
+ assert!(!ptr.is_null());
let ctx_ptr = unsafe { ui_object_get_context(ptr) };
unsafe {
ui_object_ref(ptr);
}
}
+ pub fn obj_ref(&self) -> UiObjRef<T> {
+ UiObjRef::from_ptr(self.ptr)
+ }
+
pub fn window_data<F>(&mut self, mut f: F)
where F: FnMut(&mut T) {
unsafe {
}
}
+pub struct UiObjRef<T> {
+ ptr: Box<*mut ffi::UiObject>,
+ _data: PhantomData<T>
+}
+
+impl<T> UiObjRef<T> {
+ pub fn from_ptr(obj_ptr: *mut ffi::UiObject) -> UiObjRef<T> {
+ 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<UiObject<T>> {
+ if self.ptr.is_null() {
+ None
+ } else {
+ Some(UiObject::from_ptr(*self.ptr))
+ }
+ }
+}
+
+impl<T> Drop for UiObjRef<T> {
+ 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<T> Clone for UiObjRef<T> {
+ fn clone(&self) -> Self {
+ UiObjRef::from_ptr(*self.ptr)
+ }
+}
+
pub struct UiText {
pub ptr: *mut ffi::UiText
}
}
}
- pub fn onclose<F>(&mut self, f: F)
+ 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 ptr = self.ctx.reg_box(wrapper);
}
}
- 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);
}
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);