From 2e73497a9e7ab4b3cf47d382e7b0eec64aebf803 Mon Sep 17 00:00:00 2001 From: MrGVSV <gino.valente.code@gmail.com> Date: Fri, 4 Feb 2022 14:20:24 -0800 Subject: [PATCH] Updated examples to use props --- examples/fold.rs | 7 +++++-- examples/full_ui.rs | 15 +++++++++++--- examples/global_counter.rs | 7 +++++-- examples/hooks.rs | 12 ++++++++--- examples/if.rs | 7 +++++-- examples/provider.rs | 37 +++++++++++++++++++++++++++------- examples/tabs/tab.rs | 20 ++++++++++++++---- examples/tabs/tab_bar.rs | 27 +++++++++++++++---------- examples/tabs/tab_box.rs | 15 +++++++++++--- examples/tabs/tab_content.rs | 18 +++++++++++++---- examples/tabs/tabs.rs | 13 ++++++------ examples/tabs/theming.rs | 12 +++++++++-- examples/text_box.rs | 7 +++++-- examples/todo/add_button.rs | 18 ++++++++++++----- examples/todo/card.rs | 12 +++++++++-- examples/todo/cards.rs | 11 ++++++++-- examples/todo/delete_button.rs | 18 ++++++++++++----- examples/todo/todo.rs | 7 +++++-- examples/world_interaction.rs | 9 ++++++--- 19 files changed, 201 insertions(+), 71 deletions(-) diff --git a/examples/fold.rs b/examples/fold.rs index 3158dcc..f88ed60 100644 --- a/examples/fold.rs +++ b/examples/fold.rs @@ -7,15 +7,18 @@ use bevy::{ use kayak_ui::{ bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}, core::{ - render, rsx, + render, rsx, WidgetProps, styles::{Style, StyleProp, Units}, use_state, widget, Color, EventType, Handler, Index, OnEvent, }, widgets::{App, Background, Button, Fold, If, Text, Window}, }; +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct FolderTreeProps {} + #[widget] -fn FolderTree(context: &mut KayakContext) { +fn FolderTree(props: FolderTreeProps) { let button_text_styles = Style { width: StyleProp::Value(Units::Stretch(1.0)), height: StyleProp::Value(Units::Pixels(22.0)), diff --git a/examples/full_ui.rs b/examples/full_ui.rs index f40962a..2208c49 100644 --- a/examples/full_ui.rs +++ b/examples/full_ui.rs @@ -6,14 +6,22 @@ use bevy::{ use kayak_ui::bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, ImageManager, UICameraBundle}; use kayak_ui::core::{ layout_cache::Space, - render, rsx, + render, rsx, WidgetProps, styles::{LayoutType, Style, StyleProp, Units}, widget, Bound, Children, EventType, Index, MutableBound, OnEvent, }; use kayak_ui::widgets::{App, NinePatch, Text}; +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct BlueButtonProps { + #[prop_field(Styles)] + styles: Option<Style>, + #[prop_field(Children)] + children: Option<Children> +} + #[widget] -fn BlueButton(context: KayakContext, children: Children, styles: Option<Style>) { +fn BlueButton(props: BlueButtonProps) { let (blue_button_handle, blue_button_hover_handle) = { let world = context.get_global_state::<World>(); if world.is_err() { @@ -48,7 +56,7 @@ fn BlueButton(context: KayakContext, children: Children, styles: Option<Style>) padding_right: StyleProp::Value(Units::Stretch(1.0)), padding_top: StyleProp::Value(Units::Stretch(1.0)), padding_bottom: StyleProp::Value(Units::Stretch(1.0)), - ..styles.clone().unwrap_or_default() + ..props.styles.clone().unwrap_or_default() }; let cloned_current_button_handle = current_button_handle.clone(); @@ -62,6 +70,7 @@ fn BlueButton(context: KayakContext, children: Children, styles: Option<Style>) _ => (), }); + let children = props.get_children(); rsx! { <NinePatch border={Space { diff --git a/examples/global_counter.rs b/examples/global_counter.rs index ac6642b..e2fbb7e 100644 --- a/examples/global_counter.rs +++ b/examples/global_counter.rs @@ -4,14 +4,17 @@ use bevy::{ DefaultPlugins, }; use kayak_ui::bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}; -use kayak_ui::core::{bind, render, rsx, widget, Binding, Bound, Index, MutableBound}; +use kayak_ui::core::{bind, render, rsx, widget, WidgetProps, Binding, Bound, Index, MutableBound}; use kayak_ui::widgets::{App, Text, Window}; #[derive(Clone, PartialEq)] struct GlobalCount(pub u32); +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct CounterProps {} + #[widget] -fn Counter(context: &mut KayakContext) { +fn Counter(props: CounterProps) { let global_count = context .query_world::<Res<Binding<GlobalCount>>, _, _>(move |global_count| global_count.clone()); diff --git a/examples/hooks.rs b/examples/hooks.rs index d4a2533..a85973d 100644 --- a/examples/hooks.rs +++ b/examples/hooks.rs @@ -16,13 +16,16 @@ use bevy::{ }; use kayak_ui::{ bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}, - core::{render, rsx, use_effect, use_state, widget, EventType, Index, OnEvent}, + core::{render, rsx, use_effect, use_state, widget, WidgetProps, EventType, Index, OnEvent}, widgets::{App, Button, Text, Window}, }; +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct StateCounterProps {} + /// A simple widget that tracks how many times a button is clicked using simple state data #[widget] -fn StateCounter() { +fn StateCounter(props: StateCounterProps) { // On its own, a widget can't track anything, since every value will just be reset when the widget is re-rendered. // To get around this, and keep track of a value, we have to use states. States are values that are kept across renders. // Additionally, anytime a state is updated with a new value, it causes the containing widget to re-render, making it @@ -53,9 +56,12 @@ fn StateCounter() { } } +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct EffectCounterProps {} + /// Another widget that tracks how many times a button is clicked using side-effects #[widget] -fn EffectCounter() { +fn EffectCounter(props: EffectCounterProps) { // In this widget, we're going to implement another counter, but this time using side-effects. // To put it very simply, a side-effect is when something happens in response to something else happening. // In our case, we want to create a side-effect that updates a counter when another state is updated. diff --git a/examples/if.rs b/examples/if.rs index 3267511..7120ce9 100644 --- a/examples/if.rs +++ b/examples/if.rs @@ -5,14 +5,17 @@ use bevy::{ }; use kayak_ui::bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}; use kayak_ui::core::{ - render, rsx, + render, rsx, WidgetProps, styles::{Style, StyleProp, Units}, widget, Bound, EventType, Index, MutableBound, OnEvent, }; use kayak_ui::widgets::{App, Button, If, Text, Window}; +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct RemovalProps {} + #[widget] -fn Removal(context: &mut KayakContext) { +fn Removal(props: RemovalProps) { let text_styles = Style { bottom: StyleProp::Value(Units::Stretch(1.0)), left: StyleProp::Value(Units::Stretch(0.1)), diff --git a/examples/provider.rs b/examples/provider.rs index fc32364..8a39f05 100644 --- a/examples/provider.rs +++ b/examples/provider.rs @@ -16,13 +16,14 @@ use bevy::prelude::{ use kayak_ui::{ bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}, core::{ - render, rsx, + render, rsx, WidgetProps, styles::{LayoutType, Style, StyleProp, Units}, widget, Bound, Color, EventType, Index, MutableBound, OnEvent, }, widgets::{App, Background, Element, If, Text, TooltipConsumer, TooltipProvider, Window}, }; use std::sync::Arc; +use kayak_core::Children; /// The color theme struct we will be using across our demo widgets #[derive(Debug, Default, Clone, PartialEq)] @@ -60,23 +61,37 @@ impl Theme { } } +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct ThemeProviderProps { + pub initial_theme: Theme, + #[prop_field(Children)] + children: Option<Children>, +} + /// This widget provides a theme to its children /// /// Any descendant of this provider can access its theme by calling [create_consumer](kayak_core::KayakContext::create_consumer). /// It can also be nested within itself, allowing for differing provider values. #[widget] -fn ThemeProvider(context: &mut KayakContext, initial_theme: Theme) { +fn ThemeProvider(props: ThemeProviderProps) { + let ThemeProviderProps { initial_theme, children } = props.clone(); // Create the provider context.create_provider(initial_theme); rsx! { <>{children}</> } } +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct ThemeButtonProps { + pub theme: Theme, +} + /// A widget that shows a colored box, representing the theme /// /// This widget acts as one of our consumers of the [ThemeProvider]. It then uses the theme data to /// display its content and also updates the shared state when clicked. #[widget] -fn ThemeButton(context: &mut KayakContext, theme: Theme) { +fn ThemeButton(props: ThemeButtonProps) { + let ThemeButtonProps { theme } = props.clone(); // Create a consumer // This grabs the current theme from the nearest ThemeProvider up the widget tree let consumer = context @@ -120,11 +135,14 @@ fn ThemeButton(context: &mut KayakContext, theme: Theme) { } } +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct ThemeSelectorProps {} + /// A widget displaying a set of [ThemeButton] widgets /// /// This is just an abstracted container. Not much to see here... #[widget] -fn ThemeSelector() { +fn ThemeSelector(props: ThemeSelectorProps) { let vampire_theme = Theme::vampire(); let solar_theme = Theme::solar(); let vector_theme = Theme::vector(); @@ -146,11 +164,16 @@ fn ThemeSelector() { } } +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct ThemeDemoProps { + is_root: bool +} + /// A widget that demonstrates the theming in action /// /// The `is_root` prop just ensures we don't recursively render this widget to infinity #[widget] -fn ThemeDemo(context: &mut KayakContext, is_root: bool) { +fn ThemeDemo(props: ThemeDemoProps) { // Create a consumer // This grabs the current theme from the nearest ThemeProvider up the widget tree let consumer = context @@ -158,7 +181,7 @@ fn ThemeDemo(context: &mut KayakContext, is_root: bool) { .expect("Requires ThemeProvider as an ancestor"); let theme = consumer.get(); - let select_lbl = if is_root { + let select_lbl = if props.is_root { format!("Select Theme (Current: {})", theme.name) } else { format!("Select A Different Theme (Current: {})", theme.name) @@ -223,7 +246,7 @@ fn ThemeDemo(context: &mut KayakContext, is_root: bool) { <Text content={btn_text} line_height={Some(20.0)} size={14.0} styles={Some(btn_text_style)} /> </Background> - <If condition={is_root}> + <If condition={props.is_root}> <Element styles={Some(nested_style)}> // This is one of the benefits of the provider/consumer pattern: diff --git a/examples/tabs/tab.rs b/examples/tabs/tab.rs index 1d0eb9a..dd2eeae 100644 --- a/examples/tabs/tab.rs +++ b/examples/tabs/tab.rs @@ -1,7 +1,7 @@ use kayak_ui::{ core::{ render_command::RenderCommand, - rsx, + rsx, WidgetProps, styles::{LayoutType, Style, StyleProp, Units}, use_state, widget, Bound, EventType, OnEvent, }, @@ -17,9 +17,21 @@ enum TabHoverState { Active, } +#[derive(WidgetProps, Default, Debug, PartialEq, Clone)] +pub struct TabProps { + pub content: String, + pub selected: bool, + #[prop_field(Styles)] + pub styles: Option<Style>, + #[prop_field(OnEvent)] + pub on_event: Option<OnEvent>, +} + /// The actual tab, displayed in a [TabBar](crate::tab_bar::TabBar) #[widget] -pub fn Tab(context: &mut KayakContext, content: String, selected: bool) { +pub fn Tab(props: TabProps) { + let TabProps{content, selected, ..} = props.clone(); + let theme = context.create_consumer::<TabTheme>().unwrap_or_default(); let (focus_state, set_focus_state, ..) = use_state!(false); let (hover_state, set_hover_state, ..) = use_state!(TabHoverState::None); @@ -93,11 +105,11 @@ pub fn Tab(context: &mut KayakContext, content: String, selected: bool) { ..Default::default() }; - self.styles = Some(Style { + props.styles = Some(Style { render_command: StyleProp::Value(RenderCommand::Layout), height: StyleProp::Value(Units::Pixels(theme.get().tab_height)), max_width: StyleProp::Value(Units::Pixels(100.0)), - ..styles.clone().unwrap_or_default() + ..props.styles.clone().unwrap_or_default() }); rsx! { diff --git a/examples/tabs/tab_bar.rs b/examples/tabs/tab_bar.rs index 6c32a16..b382ea6 100644 --- a/examples/tabs/tab_bar.rs +++ b/examples/tabs/tab_bar.rs @@ -1,6 +1,6 @@ use kayak_ui::{ core::{ - constructor, rsx, + constructor, rsx, WidgetProps, styles::{LayoutType, Style, StyleProp, Units}, widget, Bound, EventType, Handler, KeyCode, OnEvent, VecTracker, }, @@ -10,17 +10,22 @@ use kayak_ui::{ use crate::tab::Tab; use crate::TabTheme; +#[derive(WidgetProps, Default, Debug, PartialEq, Clone)] +pub struct TabBarProps { + pub tabs: Vec<String>, + pub selected: usize, + pub on_select_tab: Handler<usize>, + #[prop_field(Styles)] + pub styles: Option<Style> +} + /// A widget displaying a collection of tabs in a horizontal bar #[widget] -pub fn TabBar( - context: &mut KayakContext, - tabs: Vec<String>, - selected: usize, - on_select_tab: Handler<usize>, -) { +pub fn TabBar(props: TabBarProps) { + let TabBarProps{on_select_tab, selected, tabs, ..} = props.clone(); let theme = context.create_consumer::<TabTheme>().unwrap_or_default(); - let tabs = tabs.iter().enumerate().map(|(index, tab)| { + let tabs = tabs.into_iter().enumerate().map(move |(index, tab)| { let on_select = on_select_tab.clone(); let tab_event_handler = OnEvent::new(move |_, event| { match event.event_type { @@ -40,19 +45,19 @@ pub fn TabBar( constructor! { <Tab content={tab.clone()} on_event={Some(tab_event_handler.clone())} selected={selected == index} /> } - }).collect::<Vec<_>>(); + }); let background_styles = Style { layout_type: StyleProp::Value(LayoutType::Row), background_color: StyleProp::Value(theme.get().bg), height: StyleProp::Value(Units::Auto), width: StyleProp::Value(Units::Stretch(1.0)), - ..styles.clone().unwrap_or_default() + ..props.styles.clone().unwrap_or_default() }; rsx! { <Background styles={Some(background_styles)}> - <VecTracker data={tabs} /> + {VecTracker::from(tabs.clone())} </Background> } } diff --git a/examples/tabs/tab_box.rs b/examples/tabs/tab_box.rs index fa186e4..4131307 100644 --- a/examples/tabs/tab_box.rs +++ b/examples/tabs/tab_box.rs @@ -1,6 +1,6 @@ use kayak_ui::core::{ render_command::RenderCommand, - rsx, + rsx, WidgetProps, styles::{Style, StyleProp}, use_state, widget, Bound, Fragment, Handler, }; @@ -18,11 +18,20 @@ pub struct TabData { pub content: Fragment, } +#[derive(WidgetProps, Default, Debug, PartialEq, Clone)] +pub struct TabBoxProps { + pub initial_tab: usize, + pub tabs: Vec<TabData>, + #[prop_field(Styles)] + pub styles: Option<Style>, +} + /// The actual tab container widget. /// /// This houses both the tab bar and its content. #[widget] -pub fn TabBox(context: &mut KayakContext, tabs: Vec<TabData>, initial_tab: usize) { +pub fn TabBox(props: TabBoxProps) { + let TabBoxProps { initial_tab, tabs, .. } = props.clone(); let theme = context.create_consumer::<TabTheme>().unwrap_or_default(); let (selected, set_selected, ..) = use_state!(initial_tab); @@ -39,7 +48,7 @@ pub fn TabBox(context: &mut KayakContext, tabs: Vec<TabData>, initial_tab: usize set_selected(index); }); - self.styles = Some(Style { + props.styles = Some(Style { render_command: StyleProp::Value(RenderCommand::Quad), background_color: StyleProp::Value(theme.get().fg), ..Default::default() diff --git a/examples/tabs/tab_content.rs b/examples/tabs/tab_content.rs index 3348cac..afae825 100644 --- a/examples/tabs/tab_content.rs +++ b/examples/tabs/tab_content.rs @@ -1,6 +1,6 @@ use kayak_ui::core::{ render_command::RenderCommand, - rsx, + rsx, WidgetProps, styles::{Style, StyleProp}, widget, Bound, Fragment, VecTracker, }; @@ -8,9 +8,18 @@ use std::ops::Index; use crate::TabTheme; +#[derive(WidgetProps, Default, Debug, PartialEq, Clone)] +pub struct TabContentProps { + pub selected: usize, + pub tabs: Vec<Fragment>, + #[prop_field(Styles)] + pub styles: Option<Style>, +} + /// A widget that displays the selected tab's content #[widget] -pub fn TabContent(context: &mut KayakContext, tabs: Vec<Fragment>, selected: usize) { +pub fn TabContent(props: TabContentProps) { + let TabContentProps { selected, tabs, .. } = props.clone(); let theme = context.create_consumer::<TabTheme>().unwrap_or_default(); if selected >= tabs.len() { @@ -18,17 +27,18 @@ pub fn TabContent(context: &mut KayakContext, tabs: Vec<Fragment>, selected: usi return; } - self.styles = Some(Style { + props.styles = Some(Style { render_command: StyleProp::Value(RenderCommand::Quad), background_color: StyleProp::Value(theme.get().fg), ..Default::default() }); let tab = tabs.index(selected).clone(); + let tab = vec![tab.clone()]; rsx! { <> - <VecTracker data={vec![tab.clone()]} /> + {VecTracker::from(tab.clone().into_iter())} </> } } diff --git a/examples/tabs/tabs.rs b/examples/tabs/tabs.rs index 9b199a9..04e9b3d 100644 --- a/examples/tabs/tabs.rs +++ b/examples/tabs/tabs.rs @@ -13,9 +13,9 @@ use bevy::{ use kayak_ui::{ bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}, core::{ - constructor, render, rsx, + constructor, render, rsx, WidgetProps, styles::{Style, StyleProp, Units}, - widget, Children, Color, Index, + widget, Color, Index, }, widgets::{App, Text, Window}, }; @@ -30,8 +30,11 @@ mod tab_box; mod tab_content; mod theming; +#[derive(WidgetProps, Default, Debug, PartialEq, Clone)] +pub struct TabDemoProps {} + #[widget] -fn TabDemo() { +fn TabDemo(props: TabDemoProps) { let text_style = Style { width: StyleProp::Value(Units::Percentage(75.0)), top: StyleProp::Value(Units::Stretch(0.5)), @@ -48,8 +51,6 @@ fn TabDemo() { TabData { name: "Tab 1".to_string(), content: { - // This is a temporary hack to prevent the `constructor` macro from throwing an error - let children = Children::None; let text_style = text_style.clone(); constructor! { <> @@ -61,7 +62,6 @@ fn TabDemo() { TabData { name: "Tab 2".to_string(), content: { - let children = Children::None; let text_style = text_style.clone(); constructor! { <> @@ -73,7 +73,6 @@ fn TabDemo() { TabData { name: "Tab 3".to_string(), content: { - let children = Children::None; let text_style = text_style.clone(); constructor! { <> diff --git a/examples/tabs/theming.rs b/examples/tabs/theming.rs index 0290690..41f3f29 100644 --- a/examples/tabs/theming.rs +++ b/examples/tabs/theming.rs @@ -1,4 +1,4 @@ -use kayak_ui::core::{rsx, widget, Color}; +use kayak_ui::core::{Children, rsx, widget, Color, WidgetProps}; #[derive(Clone, Copy, Debug, Default, PartialEq)] pub struct TabTheme { @@ -19,8 +19,16 @@ pub struct ColorState { pub active: Color, } +#[derive(WidgetProps, Default, Debug, PartialEq, Clone)] +pub struct TabThemeProviderProps { + pub initial_theme: TabTheme, + #[prop_field(Children)] + pub children: Option<Children> +} + #[widget] -pub fn TabThemeProvider(initial_theme: TabTheme) { +pub fn TabThemeProvider(props: TabThemeProviderProps) { + let TabThemeProviderProps { initial_theme, children } = props.clone(); context.create_provider(initial_theme); rsx! { <>{children}</> } } diff --git a/examples/text_box.rs b/examples/text_box.rs index 2507de9..bfaf2fc 100644 --- a/examples/text_box.rs +++ b/examples/text_box.rs @@ -7,14 +7,17 @@ use kayak_core::Color; use kayak_render_macros::use_state; use kayak_ui::bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}; use kayak_ui::core::{ - render, rsx, + render, rsx, WidgetProps, styles::{Style, StyleProp, Units}, widget, Index, }; use kayak_ui::widgets::{App, OnChange, TextBox, Window}; +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct TextBoxExampleProps {} + #[widget] -fn TextBoxExample(context: &mut KayakContext) { +fn TextBoxExample(props: TextBoxExampleProps) { let (value, set_value, _) = use_state!("I started with a value!".to_string()); let (empty_value, set_empty_value, _) = use_state!("".to_string()); let (red_value, set_red_value, _) = use_state!("This text is red".to_string()); diff --git a/examples/todo/add_button.rs b/examples/todo/add_button.rs index a3dbdbe..d6143fa 100644 --- a/examples/todo/add_button.rs +++ b/examples/todo/add_button.rs @@ -1,19 +1,27 @@ use kayak_ui::core::{ color::Color, render_command::RenderCommand, - rsx, + rsx, WidgetProps, styles::{Style, StyleProp, Units}, - use_state, widget, Children, EventType, OnEvent, + use_state, widget, EventType, OnEvent, }; use kayak_ui::widgets::{Background, Text}; +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +pub struct AddButtonProps { + #[prop_field(Styles)] + pub styles: Option<Style>, + #[prop_field(OnEvent)] + pub on_event: Option<OnEvent>, +} + #[widget] -pub fn AddButton(children: Children, styles: Option<Style>) { +pub fn AddButton(props: AddButtonProps) { let (color, set_color, ..) = use_state!(Color::new(0.0781, 0.0898, 0.101, 1.0)); - let base_styles = styles.clone().unwrap_or_default(); - *styles = Some(Style { + let base_styles = props.styles.clone().unwrap_or_default(); + props.styles = Some(Style { render_command: StyleProp::Value(RenderCommand::Layout), height: StyleProp::Value(Units::Pixels(32.0)), width: StyleProp::Value(Units::Pixels(30.0)), diff --git a/examples/todo/card.rs b/examples/todo/card.rs index 7196752..b9b0618 100644 --- a/examples/todo/card.rs +++ b/examples/todo/card.rs @@ -1,5 +1,5 @@ use kayak_ui::core::{ - rsx, + rsx, WidgetProps, styles::{LayoutType, Style, StyleProp, Units}, widget, Color, EventType, Handler, OnEvent, }; @@ -7,8 +7,16 @@ use kayak_ui::widgets::{Background, Text}; use super::delete_button::DeleteButton; +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +pub struct CardProps { + pub card_id: usize, + pub name: String, + pub on_delete: Handler<usize>, +} + #[widget] -pub fn Card(card_id: usize, name: String, on_delete: Handler<usize>) { +pub fn Card(props: CardProps) { + let CardProps{card_id, name, on_delete} = props.clone(); let background_styles = Style { layout_type: StyleProp::Value(LayoutType::Row), background_color: StyleProp::Value(Color::new(0.176, 0.196, 0.215, 1.0)), diff --git a/examples/todo/cards.rs b/examples/todo/cards.rs index 96b6661..88e6ba4 100644 --- a/examples/todo/cards.rs +++ b/examples/todo/cards.rs @@ -1,10 +1,17 @@ -use kayak_ui::core::{constructor, rsx, widget, Handler, VecTracker}; +use kayak_ui::core::{constructor, rsx, widget, Handler, VecTracker, WidgetProps}; use kayak_ui::widgets::Element; use super::{card::Card, Todo}; +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +pub struct CardsProps { + pub cards: Vec<Todo>, + pub on_delete: Handler<usize>, +} + #[widget] -pub fn Cards(cards: Vec<Todo>, on_delete: Handler<usize>) { +pub fn Cards(props: CardsProps) { + let CardsProps { cards, on_delete } = props.clone(); rsx! { <Element> {VecTracker::from( diff --git a/examples/todo/delete_button.rs b/examples/todo/delete_button.rs index bbe6735..34d5729 100644 --- a/examples/todo/delete_button.rs +++ b/examples/todo/delete_button.rs @@ -1,19 +1,27 @@ use kayak_ui::core::{ color::Color, render_command::RenderCommand, - rsx, + rsx, WidgetProps, styles::{Style, StyleProp, Units}, - use_state, widget, Children, EventType, OnEvent, + use_state, widget, EventType, OnEvent, }; use kayak_ui::widgets::{Background, Text}; +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +pub struct DeleteButtonProps { + #[prop_field(Styles)] + styles: Option<Style>, + #[prop_field(OnEvent)] + pub on_event: Option<OnEvent>, +} + #[widget] -pub fn DeleteButton(children: Children, styles: Option<Style>) { +pub fn DeleteButton(props: DeleteButtonProps) { let (color, set_color, ..) = use_state!(Color::new(0.0781, 0.0898, 0.101, 1.0)); - let base_styles = styles.clone().unwrap_or_default(); - *styles = Some(Style { + let base_styles = props.styles.clone().unwrap_or_default(); + props.styles = Some(Style { render_command: StyleProp::Value(RenderCommand::Layout), height: StyleProp::Value(Units::Pixels(32.0)), width: StyleProp::Value(Units::Pixels(30.0)), diff --git a/examples/todo/todo.rs b/examples/todo/todo.rs index fea3f1e..95b063c 100644 --- a/examples/todo/todo.rs +++ b/examples/todo/todo.rs @@ -5,7 +5,7 @@ use bevy::{ }; use kayak_ui::bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}; use kayak_ui::core::{ - render, rsx, + render, rsx, WidgetProps, styles::{LayoutType, Style, StyleProp, Units}, use_state, widget, EventType, Handler, Index, OnEvent, }; @@ -23,8 +23,11 @@ pub struct Todo { name: String, } +#[derive(WidgetProps, Clone, Debug, Default, PartialEq)] +struct TodoAppProps {} + #[widget] -fn TodoApp() { +fn TodoApp(props: TodoAppProps) { let (todos, set_todos, ..) = use_state!(vec![ Todo { name: "Use bevy to make a game!".to_string(), diff --git a/examples/world_interaction.rs b/examples/world_interaction.rs index 6494378..9663309 100644 --- a/examples/world_interaction.rs +++ b/examples/world_interaction.rs @@ -18,7 +18,7 @@ use bevy::{ use kayak_ui::{ bevy::{BevyContext, BevyKayakUIPlugin, FontMapping, UICameraBundle}, core::{ - render, rsx, + render, rsx, WidgetProps, styles::{Style, StyleProp, Units}, use_state, widget, EventType, Index, OnEvent, }, @@ -65,8 +65,11 @@ fn set_active_tile_target( tile.target = tile_pos; } +#[derive(WidgetProps, Default, Debug, PartialEq, Clone)] +pub struct ControlPanelProps {} + #[widget] -fn ControlPanel() { +fn ControlPanel(props: ControlPanelProps) { let text_styles = Style { left: StyleProp::Value(Units::Stretch(1.0)), right: StyleProp::Value(Units::Stretch(1.0)), @@ -106,7 +109,7 @@ fn ControlPanel() { rsx! { <> - <Window draggable={true} position={(50.0, 50.0)} size={(300.0, 150.0)} title={"Square Mover: The Game".to_string()}> + <Window draggable={true} position={(50.0, 50.0)} size={(300.0, 200.0)} title={"Square Mover: The Game".to_string()}> <Text size={13.0} content={"You can check if the cursor is over the UI or on a focusable widget using the BevyContext resource.".to_string()} styles={Some(text_styles)} /> <Button on_event={Some(on_change_color)} styles={Some(button_styles)}> <Text size={16.0} content={"Change Tile Color".to_string()} /> -- GitLab