diff --git a/core/src/lib.rs b/core/src/lib.rs index 935fb6c..e70cf37 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -19,6 +19,7 @@ mod orientation; mod painter; mod primitive; mod render; +mod state; mod ui; mod widget; diff --git a/core/src/state.rs b/core/src/state.rs new file mode 100644 index 0000000..d3987d0 --- /dev/null +++ b/core/src/state.rs @@ -0,0 +1,8 @@ +#[macro_export] +macro_rules! core_state { + ($vis: vis $state: ty) => { + $vis type WidgetHandle> = $crate::WidgetHandle<$state, W>; + $vis type WidgetRef> = $crate::WidgetRef<$state, W>; + $vis type Ui = $crate::Ui<$state>; + }; +} diff --git a/examples/minimal.rs b/examples/minimal.rs index 348fc6c..a91e58b 100644 --- a/examples/minimal.rs +++ b/examples/minimal.rs @@ -5,7 +5,7 @@ fn main() { App::::run(); } -#[derive(HasUi, HasUiState)] +#[derive(DefaultUiState)] struct State { ui: Ui, ui_state: UiState, diff --git a/macro/src/lib.rs b/macro/src/lib.rs index 9b0b123..b3031b5 100644 --- a/macro/src/lib.rs +++ b/macro/src/lib.rs @@ -145,9 +145,16 @@ pub fn derive_global_state(input: TokenStream) -> TokenStream { #[proc_macro_derive(HasUi)] pub fn derive_has_ui(input: TokenStream) -> TokenStream { - let input = parse_macro_input!(input as ItemStruct); - let name = input.ident; - let Some(field) = input.fields.iter().find(|f| f.ty == parse_quote!(Ui)) else { + has_ui(&parse_macro_input!(input)) +} + +fn has_ui(input: &ItemStruct) -> TokenStream { + let name = &input.ident; + let Some(field) = input + .fields + .iter() + .find(|f| f.ty == parse_quote!(Ui) || f.ty == parse_quote!(Ui)) + else { return Error::new(name.span(), "could not find a Ui field for HasUi") .into_compile_error() .into(); @@ -155,11 +162,11 @@ pub fn derive_has_ui(input: TokenStream) -> TokenStream { let field = &field.ident; quote! { impl HasUi for #name { - fn ui_ref(&self) -> &Ui { + fn ui_ref(&self) -> &iris::iris_core::Ui { &self.#field } - fn ui(&mut self) -> &mut Ui { + fn ui(&mut self) -> &mut iris::iris_core::Ui { &mut self.#field } } @@ -167,14 +174,15 @@ pub fn derive_has_ui(input: TokenStream) -> TokenStream { .into() } -#[proc_macro_derive(HasUiState)] -pub fn derive_has_ui_state(input: TokenStream) -> TokenStream { +#[proc_macro_derive(DefaultUiState)] +pub fn derive_default_ui_state(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as ItemStruct); + let mut output = has_ui(&input); let name = input.ident; let Some(field) = input .fields .iter() - .find(|f| f.ty == parse_quote!(UiState)) + .find(|f| f.ty == parse_quote!(UiState) || f.ty == parse_quote!(UiState)) else { return Error::new( name.span(), @@ -184,12 +192,15 @@ pub fn derive_has_ui_state(input: TokenStream) -> TokenStream { .into(); }; let field = &field.ident; - quote! { - impl HasUiState for #name { - fn ui_state(&mut self) -> &mut UiState { - &mut self.#field + output.extend::( + quote! { + impl HasUiState for #name { + fn ui_state(&mut self) -> &mut iris::default::UiState { + &mut self.#field + } } } - } - .into() + .into(), + ); + output } diff --git a/src/bin/test/main.rs b/src/bin/test/main.rs index 4728ed1..8a9c125 100644 --- a/src/bin/test/main.rs +++ b/src/bin/test/main.rs @@ -1,23 +1,20 @@ -use std::{cell::RefCell, rc::Rc}; - use cosmic_text::Family; -use iris::prelude::*; -use len_fns::*; +use std::{cell::RefCell, rc::Rc}; use winit::{event::WindowEvent, event_loop::ActiveEventLoop, window::WindowAttributes}; +iris::state_prelude!(Client); + fn main() { App::::run(); } -#[derive(HasUi, HasUiState)] +#[derive(DefaultUiState)] pub struct Client { - ui: Ui, - ui_state: UiState, - info: WidgetRef>, + ui: Ui, + ui_state: UiState, + info: WidgetRef, } -event_ctx!(Client); - impl DefaultAppState for Client { fn new(event_loop: &ActiveEventLoop, _proxy: Proxy) -> Self { let mut ui = Ui::new(); @@ -153,7 +150,7 @@ impl DefaultAppState for Client { let main = WidgetPtr::new().handles(ui); let vals = Rc::new(RefCell::new((0, Vec::new()))); - let mut switch_button = |color, to: WidgetHandle, label| { + let mut switch_button = |color, to: WidgetHandle, label| { let vec = &mut vals.borrow_mut().1; let i = vec.len(); if vec.is_empty() { diff --git a/src/default/mod.rs b/src/default/mod.rs index 1ee8412..63ac348 100644 --- a/src/default/mod.rs +++ b/src/default/mod.rs @@ -52,7 +52,10 @@ pub trait HasUiState: Sized + 'static + HasUi { fn ui_state(&mut self) -> &mut UiState; fn ui_with_ui_state(&mut self) -> (&mut Ui, &mut UiState) { // as long as you're not doing anything actually unhinged this should always work safely - (unsafe { std::mem::transmute(self.ui()) }, self.ui_state()) + ( + unsafe { std::mem::transmute::<&mut Ui, &mut Ui>(self.ui()) }, + self.ui_state(), + ) } } diff --git a/src/event.rs b/src/event.rs index 26767eb..fe48f28 100644 --- a/src/event.rs +++ b/src/event.rs @@ -23,34 +23,3 @@ pub mod eventable { } } } - -// TODO: naming in here is a bit weird like eventable -#[macro_export] -macro_rules! event_ctx { - ($ty: ty) => { - mod local_event_trait { - use super::*; - #[allow(unused_imports)] - use $crate::prelude::*; - - pub trait EventableCtx, Tag> { - fn on( - self, - event: E, - f: impl for<'a> WidgetEventFn<$ty, ::Data<'a>, WL::Widget>, - ) -> impl WidgetIdFn<$ty, WL::Widget>; - } - impl, Tag> EventableCtx for WL { - fn on( - self, - event: E, - f: impl for<'a> WidgetEventFn::Data<'a>, WL::Widget>, - ) -> impl WidgetIdFn { - eventable::Eventable::on(self, event, f) - } - } - } - use local_event_trait::*; - }; -} -pub use event_ctx; diff --git a/src/lib.rs b/src/lib.rs index e563464..c2f1414 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,9 +4,29 @@ #![feature(associated_type_defaults)] #![feature(unsize)] -mod default; -mod event; -mod widget; +pub mod default; +pub mod event; +pub mod state; +pub mod widget; + +pub use iris_core; +pub use iris_macro; + +#[macro_export] +macro_rules! state_prelude { + ($state:ty) => { + iris::event_state!($state); + iris::iris_core::core_state!($state); + iris::default_state!($state); + iris::widget_state!($state); + pub use iris::{ + default::*, + iris_core::{len_fns::*, util::Vec2, *}, + iris_macro::*, + widget::*, + }; + }; +} pub mod prelude { use super::*; @@ -17,4 +37,5 @@ pub mod prelude { pub use widget::*; pub use iris_core::util::Vec2; + pub use state::*; } diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..f7c9517 --- /dev/null +++ b/src/state.rs @@ -0,0 +1,60 @@ +#[macro_export] +macro_rules! default_state { + ($vis:vis $state:ty) => { + $vis type UiState = $crate::default::UiState<$state>; + }; +} + +#[macro_export] +macro_rules! widget_state { + ($vis:vis $state:ty) => { + $crate::widget_state!( + $vis $state; + Aligned, + LayerOffset, + MaxSize, + Offset, + Scroll, + Sized, + Span, + Stack, + Text, + TextEdit, + Masked, + WidgetPtr, + ); + }; + ($vis:vis $state:ty; $($ty:ident,)*) => { + $($vis type $ty = $crate::widget::$ty<$state>;)* + } +} + +#[macro_export] +macro_rules! event_state { + ($state:ty) => { + mod local_event_trait { + use super::*; + #[allow(unused_imports)] + use $crate::prelude::*; + + pub trait EventableCtx, Tag> { + fn on( + self, + event: E, + f: impl for<'a> WidgetEventFn<$state, ::Data<'a>, WL::Widget>, + ) -> impl WidgetIdFn<$state, WL::Widget>; + } + impl, Tag> EventableCtx for WL { + fn on( + self, + event: E, + f: impl for<'a> WidgetEventFn::Data<'a>, WL::Widget>, + ) -> impl WidgetIdFn { + eventable::Eventable::on(self, event, f) + } + } + } + use local_event_trait::*; + }; +} +pub use event_state;