($fn_name:ident, $builder_fn:ident, $builder_ty:ident) => {
pub fn $fn_name<F, U>(&mut self, build: F, ui: U)
where
- F: Fn(&mut $builder_ty),
- U: FnOnce(&mut toolkit::UiObject)
+ F: Fn(&mut $builder_ty<'_, T>),
+ U: FnOnce(&mut toolkit::UiObject<T>)
{
let mut builder = self.$builder_fn();
build(&mut builder);
/* -------------------------------- Box/Grid Container -------------------------------- */
pub type ContainerCreate = fn(*mut UiObject, *const UiContainerArgs);
-pub type CreateContainerUI = fn(obj: &toolkit::UiObject);
+pub type CreateContainerUI<T> = fn(obj: &toolkit::UiObject<T>);
-pub struct ContainerBuilder<'a> {
+pub struct ContainerBuilder<'a, T> {
args: *mut UiContainerArgs,
- obj: &'a mut toolkit::UiObject,
+ obj: &'a mut toolkit::UiObject<T>,
create: ContainerCreate
}
}
}
-impl toolkit::UiObject {
+impl<T> toolkit::UiObject<T> {
container_fn!(vbox, vbox_builder, ContainerBuilder);
container_fn!(hbox, hbox_builder, ContainerBuilder);
container_fn!(grid, grid_builder, ContainerBuilder);
- pub fn vbox_builder(&mut self) -> ContainerBuilder<'_>
+ pub fn vbox_builder(&mut self) -> ContainerBuilder<'_, T>
{
unsafe {
let args = ui_container_args_new();
}
}
- pub fn hbox_builder(&mut self) -> ContainerBuilder<'_>
+ pub fn hbox_builder(&mut self) -> ContainerBuilder<'_, T>
{
unsafe {
let args = ui_container_args_new();
}
}
- pub fn grid_builder(&mut self) -> ContainerBuilder<'_>
+ pub fn grid_builder(&mut self) -> ContainerBuilder<'_, T>
{
unsafe {
let args = ui_container_args_new();
}
pub fn grid_row<F>(&mut self, create_ui: F)
- where F: FnOnce(&mut toolkit::UiObject) {
+ where F: FnOnce(&mut toolkit::UiObject<T>) {
create_ui(self);
unsafe {
ui_newline(self.ptr);
}
}
-impl<'a> ContainerBuilder<'a> {
+impl<'a, T> ContainerBuilder<'a, T> {
pub fn create<F>(&mut self, create_ui: F)
- where F: FnOnce(&mut toolkit::UiObject) {
+ where F: FnOnce(&mut toolkit::UiObject<T>) {
(self.create)(self.obj.ptr, self.args);
create_ui(self.obj);
unsafe {
}
}
-impl<'a> Drop for ContainerBuilder<'a> {
+impl<'a, T> Drop for ContainerBuilder<'a, T> {
fn drop(&mut self) {
unsafe {
ui_container_args_free(self.args);
pub type FrameCreate = fn(*mut UiObject, *const UiFrameArgs);
-pub struct FrameBuilder<'a> {
+pub struct FrameBuilder<'a, T> {
args: *mut UiFrameArgs,
- obj: &'a mut toolkit::UiObject,
+ obj: &'a mut toolkit::UiObject<T>,
create: FrameCreate
}
}
}
-impl toolkit::UiObject {
+impl<T> toolkit::UiObject<T> {
container_fn!(frame, frame_builder, FrameBuilder);
container_fn!(expander, expander_builder, FrameBuilder);
container_fn!(scrolledwindow, scrolledwindow_builder, FrameBuilder);
- pub fn frame_builder(&mut self) -> FrameBuilder<'_>
+ pub fn frame_builder(&mut self) -> FrameBuilder<'_, T>
{
unsafe {
let args = ui_frame_args_new();
}
}
- pub fn expander_builder(&mut self) -> FrameBuilder<'_>
+ pub fn expander_builder(&mut self) -> FrameBuilder<'_, T>
{
unsafe {
let args = ui_frame_args_new();
}
}
- pub fn scrolledwindow_builder(&mut self) -> FrameBuilder<'_>
+ pub fn scrolledwindow_builder(&mut self) -> FrameBuilder<'_, T>
{
unsafe {
let args = ui_frame_args_new();
}
}
-impl<'a> FrameBuilder<'a> {
+impl<'a, T> FrameBuilder<'a, T> {
pub fn create<F>(&mut self, create_ui: F)
- where F: FnOnce(&mut toolkit::UiObject) {
+ where F: FnOnce(&mut toolkit::UiObject<T>) {
(self.create)(self.obj.ptr, self.args);
create_ui(self.obj);
unsafe {
}
}
-impl<'a> Drop for FrameBuilder<'a> {
+impl<'a, T> Drop for FrameBuilder<'a, T> {
fn drop(&mut self) {
unsafe {
ui_frame_args_free(self.args);
pub type SplitpaneCreate = fn(*mut UiObject, *const UiSplitPaneArgs );
-pub struct SplitPaneBuilder<'a> {
+pub struct SplitPaneBuilder<'a, T> {
args: *mut UiSplitPaneArgs,
- obj: &'a mut toolkit::UiObject,
+ obj: &'a mut toolkit::UiObject<T>,
create: SplitpaneCreate
}
}
-impl toolkit::UiObject {
+impl<T> toolkit::UiObject<T> {
container_fn!(hsplitpane, hsplitpane_builder, SplitPaneBuilder);
container_fn!(vsplitpane, vsplitpane_builder, SplitPaneBuilder);
- pub fn hsplitpane_builder(&mut self) -> SplitPaneBuilder<'_>
+ pub fn hsplitpane_builder(&mut self) -> SplitPaneBuilder<'_, T>
{
unsafe {
let args = ui_splitpane_args_new();
}
}
- pub fn vsplitpane_builder(&mut self) -> SplitPaneBuilder<'_>
+ pub fn vsplitpane_builder(&mut self) -> SplitPaneBuilder<'_, T>
{
unsafe {
let args = ui_splitpane_args_new();
}
}
-impl<'a> SplitPaneBuilder<'a> {
+impl<'a, T> SplitPaneBuilder<'a, T> {
pub fn create<F>(&mut self, create_ui: F)
- where F: FnOnce(&mut toolkit::UiObject) {
+ where F: FnOnce(&mut toolkit::UiObject<T>) {
(self.create)(self.obj.ptr, self.args);
create_ui(self.obj);
unsafe {
}
}
-impl<'a> Drop for SplitPaneBuilder<'a> {
+impl<'a, T> Drop for SplitPaneBuilder<'a, T> {
fn drop(&mut self) {
unsafe {
ui_splitpane_args_free(self.args);
pub type SidebarCreate = fn(*mut UiObject, *const UiSidebarArgs );
-pub struct SidebarBuilder<'a> {
+pub struct SidebarBuilder<'a, T> {
args: *mut UiSidebarArgs,
- obj: &'a mut toolkit::UiObject,
+ obj: &'a mut toolkit::UiObject<T>,
create: SidebarCreate
}
}
-impl toolkit::UiObject {
+impl<T> toolkit::UiObject<T> {
container_fn!(sidebar, sidebar_builder, SidebarBuilder);
- pub fn sidebar_builder(&mut self) -> SidebarBuilder<'_>
+ pub fn sidebar_builder(&mut self) -> SidebarBuilder<'_, T>
{
unsafe {
let args = ui_sidebar_args_new();
}
}
- pub fn left_panel_builder(&mut self) -> SidebarBuilder<'_>
+ pub fn left_panel_builder(&mut self) -> SidebarBuilder<'_, T>
{
unsafe {
let args = ui_sidebar_args_new();
}
}
- pub fn right_panel_builder(&mut self) -> SidebarBuilder<'_>
+ pub fn right_panel_builder(&mut self) -> SidebarBuilder<'_, T>
{
unsafe {
let args = ui_sidebar_args_new();
}
}
-impl<'a> SidebarBuilder<'a> {
+impl<'a, T> SidebarBuilder<'a, T> {
pub fn create<F>(&mut self, create_ui: F)
- where F: FnOnce(&mut toolkit::UiObject) {
+ where F: FnOnce(&mut toolkit::UiObject<T>) {
(self.create)(self.obj.ptr, self.args);
create_ui(self.obj);
unsafe {
}
}
-impl<'a> Drop for SidebarBuilder<'a> {
+impl<'a, T> Drop for SidebarBuilder<'a, T> {
fn drop(&mut self) {
unsafe {
ui_sidebar_args_free(self.args);
/* -------------------------------- Tabview Container -------------------------------- */
-pub struct TabViewBuilder<'a> {
+pub struct TabViewBuilder<'a, T> {
args: *mut UiTabViewArgs,
- obj: &'a mut toolkit::UiObject
+ obj: &'a mut toolkit::UiObject<T>
}
-pub struct TabBuilder<'a> {
- obj: &'a mut toolkit::UiObject
+pub struct TabBuilder<'a, T> {
+ obj: &'a mut toolkit::UiObject<T>
}
-impl<'a> TabBuilder<'a> {
+impl<'a, T> TabBuilder<'a, T> {
pub fn tab<F>(&mut self, title: &str, create_ui: F)
where
- F: FnOnce(&mut toolkit::UiObject)
+ F: FnOnce(&mut toolkit::UiObject<T>)
{
unsafe {
let title = CString::new(title).unwrap();
}
}
-impl toolkit::UiObject {
+impl<T> toolkit::UiObject<T> {
pub fn tabview<F, U>(&mut self, build: F, ui: U)
where
- F: Fn(&mut TabViewBuilder),
- U: FnOnce(&mut TabBuilder) {
+ F: Fn(&mut TabViewBuilder<T>),
+ U: FnOnce(&mut TabBuilder<T>) {
let mut builder = self.tabview_builder();
build(&mut builder);
builder.create(ui);
}
- pub fn tabview_builder(&mut self) -> TabViewBuilder<'_>
+ pub fn tabview_builder(&mut self) -> TabViewBuilder<'_, T>
{
unsafe {
let args = ui_tabview_args_new();
}
}
-impl<'a> TabViewBuilder<'a> {
+impl<'a, T> TabViewBuilder<'a, T> {
pub fn create<F>(&mut self, create_ui: F)
- where F: FnOnce(&mut TabBuilder) {
+ where F: FnOnce(&mut TabBuilder<T>) {
unsafe {
ui_tabview_create(self.obj.ptr, self.args);
}
use std::ffi::{c_char, c_int, c_void};
use std::ffi::CString;
+use std::marker::PhantomData;
use crate::ui::toolkit;
use crate::ui::ffi::UiObject;
fn ui_show(ui: *const UiObject);
+
+ fn ui_object_get_windowdata(obj: *const UiObject) -> *mut c_void;
+ fn ui_object_set_windowdata(obj: *mut UiObject, data: *mut c_void);
}
-impl toolkit::UiObject {
+impl<T> toolkit::UiObject<T> {
pub fn show(&self) {
unsafe {
ui_show(self.ptr);
Simple
}
-fn window_create(title: &str, kind: WindowType) -> toolkit::UiObject {
- unsafe {
+fn window_create<T, F>(title: &str, kind: WindowType, mut data: T, create_ui: F) -> toolkit::UiObject<T>
+where F: FnOnce(&mut toolkit::UiObject<T>, &mut T) {
+ // create the window
+ let objptr = unsafe {
let str = CString::new(title).unwrap();
-
- let objptr = match kind {
+ match kind {
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())
- };
+ }
+ };
- toolkit::UiObject { ptr: objptr }
+ // create local UiObject
+ let mut obj = toolkit::UiObject::<T> { ptr: objptr, _data: PhantomData };
+
+ // call ui building closure
+ create_ui(&mut obj, &mut data);
+
+ // store windowdata object in the UiObject
+ let window_data = Box::new(data);
+ let wdata_ptr = Box::into_raw(window_data);
+ unsafe {
+ ui_object_set_windowdata(objptr, wdata_ptr as *mut c_void);
}
+ obj
}
-pub fn window(title: &str) -> toolkit::UiObject {
- return window_create(title, WindowType::Standard);
+pub fn window<T, 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)
}
-pub fn sidebar_window(title: &str) -> toolkit::UiObject {
- return window_create(title, WindowType::Sidebar);
+pub fn sidebar_window<T, 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 splitview_window(title: &str, sidebar: bool) -> toolkit::UiObject {
- return window_create(title, WindowType::SplitView(sidebar));
+pub fn splitview_window<T, 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 simple_window(title: &str) -> toolkit::UiObject {
- return window_create(title, WindowType::Simple);
+pub fn simple_window<T, 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)
}