use std::ffi::{c_char, c_int, c_void};
use std::ffi::{c_uint, CString};
use std::marker::PhantomData;
-use crate::ui::{event, event_wrapper_oneshot, ffi, toolkit, ui_object_ref, ui_update_action_bindings, AppContext, EventWrapper, NoAppData, UiActions, UiModel};
-use crate::ui::ffi::{UiButtonArgs, UiCallback, UiContext, UiDestructor, UiDialogArgs, UiObject};
+use crate::ui::{destroy_boxed, event, event_wrapper_oneshot, ffi, toolkit, ui_object_ref, ui_update_action_bindings, AppContext, EventWrapper, NoAppData, UiActions, UiModel};
+use crate::ui::ffi::{UiButtonArgs, UiCallback, UiContext, UiDestructor, UiDialogArgs, UiDialogWindowArgs, UiObject};
use crate::ui::widget::widget_fn;
impl<T> toolkit::UiObject<T> {
Standard,
SplitView(bool),
Sidebar,
- Simple
+ Simple,
+ DialogWindow
}
-fn window_create<T: UiModel + UiActions, F>(title: &str, kind: WindowType, data: T, create_ui: F) -> toolkit::UiObject<T>
+fn window_create<T: UiModel + UiActions, F>(parent: *mut ffi::UiObject, title: &str, kind: WindowType, args: *mut UiDialogWindowArgs, data: T, create_ui: F) -> toolkit::UiObject<T>
where F: FnOnce(&mut toolkit::UiObject<T>, &mut T) {
// create the window
let objptr = unsafe {
WindowType::SplitView(val) => ui_splitview_window(str.as_ptr(), val as c_int),
WindowType::Sidebar => ui_sidebar_window(str.as_ptr()),
WindowType::Standard => ui_window(str.as_ptr()),
- WindowType::Simple => ui_simple_window(str.as_ptr())
+ WindowType::Simple => ui_simple_window(str.as_ptr()),
+ WindowType::DialogWindow => ui_dialog_window_create(parent, args)
}
};
// because we use additional reference counting in the Rust UiObject wrapper,
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)
+ window_create(std::ptr::null_mut(), title, WindowType::Standard, std::ptr::null_mut(), 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)
+ window_create(std::ptr::null_mut(), title, WindowType::Sidebar, std::ptr::null_mut(), 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)
+ window_create(std::ptr::null_mut(), title, WindowType::SplitView(sidebar), std::ptr::null_mut(), data, create_ui)
}
}
pub fn simple_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::Simple, data, create_ui)
+ window_create(std::ptr::null_mut(), title, WindowType::Simple, std::ptr::null_mut(), data, create_ui)
}
/* ---------------------------------- dialogs ---------------------------------- */
}
}
+
+pub struct DialogWindowBuilder<T> {
+ args: *mut UiDialogWindowArgs,
+ parent: *mut ffi::UiObject,
+ onclick: Option<Box<EventWrapper<T>>>,
+ _marker: PhantomData<T>
+}
+
+impl<T> Drop for DialogWindowBuilder<T> {
+ fn drop(&mut self) {
+ unsafe {
+ ui_dialogwindow_args_free(self.args);
+ }
+ }
+}
+
+impl<T: UiModel + UiActions> DialogWindowBuilder<T> {
+ pub fn create<F>(&mut self, data: T, create_ui: F) -> toolkit::UiObject<T>
+ where F: FnOnce(&mut toolkit::UiObject<T>, &mut T) {
+ let ptr = if let Some(onclick) = self.onclick.take() {
+ let ptr = Box::into_raw(onclick);
+ unsafe {
+ ui_dialogwindow_args_set_onclick(self.args, Some(event::event_wrapper::<T>));
+ ui_dialogwindow_args_set_onclickdata(self.args, ptr as *mut c_void);
+ }
+ ptr
+ } else {
+ std::ptr::null_mut()
+ };
+ let obj = window_create(self.parent, "", WindowType::DialogWindow, self.args, data, create_ui);
+ if !ptr.is_null() {
+ unsafe {
+ ui_reg_destructor(obj.ctx.ptr, ptr as *mut c_void, destroy_boxed::<EventWrapper<T>>);
+ }
+ }
+ self.onclick = None;
+ obj
+ }
+
+ pub fn modal(&mut self, val: bool) -> &mut Self {
+ unsafe {
+ ui_dialogwindow_args_set_modal(self.args, if val { 1 } else { 2 });
+ }
+ self
+ }
+
+ pub fn titlebar_buttons(&mut self, val: bool) -> &mut Self {
+ unsafe {
+ ui_dialogwindow_args_set_titlebar_buttons(self.args, if val { 1 } else { 2 });
+ }
+ self
+ }
+
+ pub fn show_closebutton(&mut self, val: bool) -> &mut Self {
+ unsafe {
+ ui_dialogwindow_args_set_show_closebutton(self.args, if val { 1 } else { 2 });
+ }
+ self
+ }
+
+ pub fn title(&mut self, val: &str) -> &mut Self {
+ let cstr = CString::new(val).unwrap();
+ unsafe {
+ ui_dialogwindow_args_set_title(self.args, cstr.as_ptr());
+ }
+ self
+ }
+
+ pub fn lbutton1(&mut self, val: &str) -> &mut Self {
+ let cstr = CString::new(val).unwrap();
+ unsafe {
+ ui_dialogwindow_args_set_lbutton1(self.args, cstr.as_ptr());
+ }
+ self
+ }
+
+ pub fn lbutton2(&mut self, val: &str) -> &mut Self {
+ let cstr = CString::new(val).unwrap();
+ unsafe {
+ ui_dialogwindow_args_set_lbutton2(self.args, cstr.as_ptr());
+ }
+ self
+ }
+
+ pub fn rbutton3(&mut self, val: &str) -> &mut Self {
+ let cstr = CString::new(val).unwrap();
+ unsafe {
+ ui_dialogwindow_args_set_rbutton3(self.args, cstr.as_ptr());
+ }
+ self
+ }
+
+ pub fn rbutton4(&mut self, val: &str) -> &mut Self {
+ let cstr = CString::new(val).unwrap();
+ unsafe {
+ ui_dialogwindow_args_set_rbutton4(self.args, cstr.as_ptr());
+ }
+ self
+ }
+
+ pub fn default_button(&mut self, button: i32) -> &mut Self {
+ unsafe {
+ ui_dialogwindow_args_set_default_button(self.args, button);
+ }
+ self
+ }
+
+ pub fn width(&mut self, val: i32) -> &mut Self {
+ unsafe {
+ ui_dialogwindow_args_set_width(self.args, val);
+ }
+ self
+ }
+
+ pub fn height(&mut self, val: i32) -> &mut Self {
+ unsafe {
+ ui_dialogwindow_args_set_height(self.args, val);
+ }
+ self
+ }
+
+ 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
+ }
+}
+
+
impl<T> toolkit::UiObject<T> {
pub fn dialog_builder(&self) -> DialogBuilder<T> {
DialogBuilder {
builder.create();
}
+ pub fn dialogwindow_builder<D>(&self) -> DialogWindowBuilder<D> {
+ unsafe {
+ DialogWindowBuilder {
+ args: ui_dialogwindow_args_new(),
+ parent: self.ptr,
+ onclick: None,
+ _marker: PhantomData,
+ }
+ }
+ }
+
pub fn openfile_dialog<F>(&mut self, multiselect: bool, callback: F)
where F: FnMut(&mut event::Event<T>) + 'static {
openfile_dialog(self, multiselect as c_uint, callback);
fn ui_simple_window(title: *const c_char) -> *mut UiObject;
fn ui_dialog_create(parent: *mut UiObject, args: *mut UiDialogArgs);
+ fn ui_dialog_window_create(parent: *mut UiObject, args: *mut UiDialogWindowArgs) -> *mut UiObject;
fn ui_window_size(obj: *mut UiObject, width: c_int, height: c_int);
fn ui_window_menubar_set_visible(obj: *mut UiObject, visible: c_int) -> c_int;
fn ui_dialog_args_set_resultdata(args: *mut UiDialogArgs, data: *mut c_void);
fn ui_dialog_args_free(args: *mut UiDialogArgs);
+ fn ui_dialogwindow_args_new() -> *mut UiDialogWindowArgs;
+ fn ui_dialogwindow_args_set_modal(args: *mut ffi::UiDialogWindowArgs, value: c_int);
+ fn ui_dialogwindow_args_set_titlebar_buttons(args: *mut ffi::UiDialogWindowArgs, value: c_int);
+ fn ui_dialogwindow_args_set_show_closebutton(args: *mut ffi::UiDialogWindowArgs, value: c_int);
+ fn ui_dialogwindow_args_set_title(args: *mut ffi::UiDialogWindowArgs, title: *const c_char);
+ fn ui_dialogwindow_args_set_lbutton1(args: *mut ffi::UiDialogWindowArgs, label: *const c_char);
+ fn ui_dialogwindow_args_set_lbutton2(args: *mut ffi::UiDialogWindowArgs, label: *const c_char);
+ fn ui_dialogwindow_args_set_rbutton3(args: *mut ffi::UiDialogWindowArgs, label: *const c_char);
+ fn ui_dialogwindow_args_set_rbutton4(args: *mut ffi::UiDialogWindowArgs, label: *const c_char);
+ fn ui_dialogwindow_args_set_lbutton1_states(args: *mut ffi::UiDialogWindowArgs, states: *const c_int, numstates: c_int);
+ fn ui_dialogwindow_args_set_lbutton2_states(args: *mut ffi::UiDialogWindowArgs, states: *const c_int, numstates: c_int);
+ fn ui_dialogwindow_args_set_rbutton3_states(args: *mut ffi::UiDialogWindowArgs, states: *const c_int, numstates: c_int);
+ fn ui_dialogwindow_args_set_rbutton4_states(args: *mut ffi::UiDialogWindowArgs, states: *const c_int, numstates: c_int);
+ fn ui_dialogwindow_args_set_default_button(args: *mut ffi::UiDialogWindowArgs, button: c_int);
+ fn ui_dialogwindow_args_set_width(args: *mut ffi::UiDialogWindowArgs, width: c_int);
+ fn ui_dialogwindow_args_set_height(args: *mut ffi::UiDialogWindowArgs, height: c_int);
+ fn ui_dialogwindow_args_set_onclick(args: *mut ffi::UiDialogWindowArgs, cb: UiCallback);
+ fn ui_dialogwindow_args_set_onclickdata(args: *mut ffi::UiDialogWindowArgs, data: *mut c_void);
+ fn ui_dialogwindow_args_free(args: *mut ffi::UiDialogWindowArgs);
+
fn ui_openfiledialog(obj: *mut ffi::UiObject, mode: c_uint, callback: UiCallback, data: *mut c_void);
fn ui_savefiledialog(obj: *mut ffi::UiObject, name: *const c_char, callback: UiCallback, data: *mut c_void);
}