Skip to content
Snippets Groups Projects
Verified Commit 9b22b4e7 authored by Louis's avatar Louis :fire:
Browse files

Set up tips panel

parent 94947743
No related branches found
No related tags found
No related merge requests found
Pipeline #255 failed with stages
in 4 minutes
......@@ -18,6 +18,8 @@ pub enum AppState {
Splash,
/// An initial landing page that will present players with options
Menu,
Tips,
Settings,
/// The in game state runs all of the actual gameplay logic. Most of the runtime
/// will be spent here.
InGame,
......
use bevy::prelude::*;
use kayak_ui::prelude::*;
use crate::{empty_props, parent_widget};
#[derive(Copy, Clone, Default, Debug, Eq, PartialEq)]
pub enum MainMenuView {
MenuPanel,
TipsPanel,
SettingsPanel,
#[default]
None,
}
impl MainMenuView {
pub fn is_none(&self) -> bool {
self == &MainMenuView::None
}
}
#[derive(Copy, Clone, Default, Debug, Component, Eq, PartialEq)]
pub struct MainMenuContext {
pub view: MainMenuView,
pub next: Option<MainMenuView>,
}
impl MainMenuContext {
pub fn new() -> Self {
Self {
view: MainMenuView::MenuPanel,
next: None,
}
}
pub fn next(&mut self, next: MainMenuView) {
self.view = next;
// self.view = MainMenuView::None;
// self.next = Some(next);
}
fn cycle(&mut self) {
if let Some(next) = self.next {
self.view = next;
self.next = None;
}
}
}
empty_props!(MainMenuContextProps);
parent_widget!(MainMenuContextProps => MainMenuContextProvider);
pub fn render_main_menu_context_provider(
In((mut widget_context, entity)): In<(KayakWidgetContext, Entity)>,
mut commands: Commands,
mut children_query: Query<(&KStyle, &mut ComputedStyles, &KChildren)>,
mut context_query: Query<&mut MainMenuContext>,
) -> bool {
if let Ok((style, mut computed, children)) = children_query.get_mut(entity) {
*computed = ComputedStyles(style.clone());
if let Some(context_entity) = widget_context.get_context_entity::<MainMenuContext>(entity) {
children.process(&mut widget_context, Some(entity));
} else {
let context_entity = commands.spawn(MainMenuContext::new()).id();
widget_context.set_context_entity::<MainMenuContext>(Some(entity), context_entity);
}
}
true
}
mod main_menu_context;
pub use main_menu_context::{
render_main_menu_context_provider, MainMenuContext, MainMenuContextProps,
MainMenuContextProvider, MainMenuView,
};
......@@ -3,6 +3,7 @@ use kayak_ui::prelude::KayakContextPlugin;
use kayak_ui::widgets::KayakWidgets;
pub mod components;
pub mod context;
pub mod screens;
pub mod sync;
pub mod utilities;
......@@ -91,7 +92,10 @@ mod _config {
app.add_exit_system(AppState::Setup, configure_kayak_ui)
.add_enter_system(AppState::Menu, super::screens::render_menu_ui)
.add_enter_system(AppState::InGame, super::screens::render_in_game_ui)
.add_enter_system(AppState::Tips, super::screens::render_menu_tips_ui)
.add_exit_system(AppState::InGame, remove_ui)
.add_exit_system(AppState::Tips, remove_ui)
.add_exit_system(AppState::Settings, remove_ui)
.add_exit_system(AppState::Menu, remove_ui);
}
}
......
......@@ -9,6 +9,7 @@ use crate::assets::AssetHandles;
use crate::persistance::{fs_utils, LoadFileEvent};
use crate::system::flow::AppState;
use crate::ui::components::*;
use crate::ui::context::*;
use crate::ui::prelude::{pct, px, stretch, value};
use crate::ui::sync::UITravelInfo;
use crate::ui::utilities::context::create_root_context;
......@@ -16,128 +17,86 @@ use crate::ui::utilities::StateUIRoot;
use crate::ui::widgets::*;
use crate::world::EncounterState;
use crate::{
empty_props, on_button_click, parent_widget, register_widget,
empty_props, on_button_click, parent_widget, register_widget, register_widget_with_context,
register_widget_with_many_resources, register_widget_with_resource,
};
empty_props!(MainMenuProps);
parent_widget!(MainMenuProps => MainMenuLayout);
#[derive(Component, PartialEq, Eq, Clone, Default)]
pub struct MainMenuState {
bg_idx: usize,
}
pub fn render_main_menu_layout(
In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
mut commands: Commands,
assets: Res<AssetHandles>,
state_query: Query<&MainMenuState>,
) -> bool {
let parent_id = Some(entity);
let has_autosave = fs_utils::has_auto_save();
let root_styles = KStyle {
..Default::default()
};
let image_styles = KStyle {
position_type: value(KPositionType::SelfDirected),
..Default::default()
};
let contents_container_style = KStyle {
position_type: value(KPositionType::SelfDirected),
width: pct(65.0),
height: pct(80.0),
min_width: px(400.0),
min_height: px(300.0),
max_width: px(500.0),
max_height: px(400.0),
top: stretch(1.0),
left: stretch(1.0),
right: stretch(1.0),
bottom: stretch(1.0),
layout_type: value(LayoutType::Column),
row_between: px(20.0),
..Default::default()
};
let header_style = KStyle {
left: stretch(1.0),
right: stretch(1.0),
..Default::default()
};
let background_idx = fastrand::usize(1..6);
let image = KImage(assets.image(format!("menu_background_{}", background_idx)));
let button_style = KStyle {
width: px(300.0),
left: stretch(1.0),
right: stretch(1.0),
..Default::default()
};
let on_new = on_button_click!(Commands, |mut commands: Commands| {
commands.insert_resource(NextState(AppState::InGame));
});
let on_continue = on_button_click!(EventWriter<LoadFileEvent>, |mut events: EventWriter<
LoadFileEvent,
>| {
events.send(LoadFileEvent::autosave());
});
let state_entity = widget_context.use_state(
&mut commands,
entity,
MainMenuState {
bg_idx: fastrand::usize(1..6),
},
);
rsx! {
<ElementBundle styles={root_styles}>
<KImageBundle styles={image_styles} image={image} />
<ElementBundle styles={contents_container_style}>
<TextWidgetBundle
text={TextProps {
content: String::from("Trader Tales"),
font: Some(String::from("header")),
size: 72.0,
..Default::default()
}}
styles={header_style}
/>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from("New Game"),
font_size: 32.0,
..Default::default()
}}
on_event={on_new}
/>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from("Continue Game"),
font_size: 32.0,
is_disabled: !has_autosave,
..Default::default()
}}
on_event={on_continue}
/>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from("Tips"),
font_size: 32.0,
is_disabled: true,
..Default::default()
}}
/>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from("Settings"),
font_size: 32.0,
is_disabled: true,
..Default::default()
}}
/>
if let Ok(state) = state_query.get(state_entity) {
log::info!("Rendering main menu");
let root_styles = KStyle {
..Default::default()
};
let image_styles = KStyle {
position_type: value(KPositionType::SelfDirected),
..Default::default()
};
let contents_container_style = KStyle {
position_type: value(KPositionType::SelfDirected),
width: pct(65.0),
height: pct(80.0),
min_width: px(400.0),
min_height: px(300.0),
max_width: px(500.0),
max_height: px(400.0),
top: stretch(1.0),
left: stretch(1.0),
right: stretch(1.0),
bottom: stretch(1.0),
layout_type: value(LayoutType::Column),
row_between: px(20.0),
..Default::default()
};
let header_style = KStyle {
left: stretch(1.0),
right: stretch(1.0),
..Default::default()
};
let image = KImage(assets.image(format!("menu_background_{}", state.bg_idx)));
let button_style = KStyle {
width: px(300.0),
left: stretch(1.0),
right: stretch(1.0),
..Default::default()
};
rsx! {
<ElementBundle styles={root_styles}>
<KImageBundle styles={image_styles} image={image} />
<MainMenuPanel />
</ElementBundle>
</ElementBundle>
};
};
}
true
}
......@@ -158,12 +117,21 @@ pub fn render_menu_ui(mut commands: Commands) {
fn create_main_menu_context() -> KayakRootContext {
let mut widget_context = create_root_context();
register_widget!(
register_widget_with_context!(
widget_context,
MainMenuProps,
EmptyState,
MainMenuState,
MainMenuContext,
render_main_menu_layout
);
register_widget_with_context!(
widget_context,
MainMenuContextProps,
EmptyState,
MainMenuContext,
render_main_menu_context_provider
);
widget_context
}
use bevy::prelude::*;
use iyes_loopless::prelude::NextState;
use kayak_ui::prelude::*;
use kayak_ui::widgets::{
ElementBundle, KImage, KImageBundle, KayakAppBundle, TextProps, TextWidgetBundle,
};
use crate::assets::AssetHandles;
use crate::persistance::{fs_utils, LoadFileEvent};
use crate::system::flow::AppState;
use crate::ui::components::*;
use crate::ui::context::*;
use crate::ui::prelude::{pct, px, stretch, value};
use crate::ui::sync::UITravelInfo;
use crate::ui::utilities::context::create_root_context;
use crate::ui::utilities::StateUIRoot;
use crate::ui::widgets::*;
use crate::world::EncounterState;
use crate::{
empty_props, on_button_click, parent_widget, register_widget, register_widget_with_context,
register_widget_with_many_resources, register_widget_with_resource,
};
empty_props!(MainMenuTipsProps);
parent_widget!(MainMenuTipsProps => MainMenuTipsLayout);
#[derive(Component, PartialEq, Eq, Clone, Default)]
pub struct MainMenuState {
bg_idx: usize,
}
pub fn render_main_menu_tips_layout(
In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
mut commands: Commands,
assets: Res<AssetHandles>,
context_query: Query<&MainMenuContext>,
state_query: Query<&MainMenuState>,
) -> bool {
let parent_id = Some(entity);
let has_autosave = fs_utils::has_auto_save();
let state_entity = widget_context.use_state(
&mut commands,
entity,
MainMenuState {
bg_idx: fastrand::usize(1..6),
},
);
if let Ok(state) = state_query.get(state_entity) {
log::info!("Rendering main menu");
let root_styles = KStyle {
..Default::default()
};
let image_styles = KStyle {
position_type: value(KPositionType::SelfDirected),
..Default::default()
};
let contents_container_style = KStyle {
position_type: value(KPositionType::SelfDirected),
width: pct(65.0),
height: pct(80.0),
min_width: px(400.0),
min_height: px(300.0),
max_width: px(500.0),
max_height: px(400.0),
top: stretch(1.0),
left: stretch(1.0),
right: stretch(1.0),
bottom: stretch(1.0),
layout_type: value(LayoutType::Column),
row_between: px(20.0),
..Default::default()
};
let header_style = KStyle {
left: stretch(1.0),
right: stretch(1.0),
..Default::default()
};
let image = KImage(assets.image(format!("menu_background_{}", state.bg_idx)));
let button_style = KStyle {
width: px(300.0),
left: stretch(1.0),
right: stretch(1.0),
..Default::default()
};
rsx! {
<ElementBundle styles={root_styles}>
<KImageBundle styles={image_styles} image={image} />
<TipsPanel />
</ElementBundle>
};
}
true
}
pub fn render_menu_tips_ui(mut commands: Commands) {
let parent_id = None;
let mut widget_context = create_main_menu_context();
rsx! {
<KayakAppBundle>
<MainMenuTipsLayout />
</KayakAppBundle>
};
commands.spawn((UICameraBundle::new(widget_context), StateUIRoot));
}
fn create_main_menu_context() -> KayakRootContext {
let mut widget_context = create_root_context();
register_widget!(
widget_context,
MainMenuTipsProps,
MainMenuState,
render_main_menu_tips_layout
);
widget_context
}
mod in_game;
mod main_menu;
mod main_menu_tips;
pub use in_game::render_in_game_ui;
pub use main_menu::render_menu_ui;
pub use main_menu_tips::render_menu_tips_ui;
......@@ -114,6 +114,18 @@ macro_rules! register_widget_with_resource {
}};
}
#[macro_export]
macro_rules! register_widget_with_context {
($ctx: expr, $props: ident, $state: path, $context: ident, $system: ident) => {{
$ctx.add_widget_data::<$props, $state>();
$ctx.add_widget_system(
::kayak_ui::prelude::Widget::get_name(&$props::default()),
::kayak_ui::prelude::widget_update_with_context::<$props, $state, $context>,
$system,
);
}};
}
#[macro_export]
macro_rules! register_widget_with_many_resources {
($ctx: expr, $props: ident, $state: ident, $system: ident, $($name: ident: $resource: ident),+) => {{
......@@ -133,6 +145,59 @@ macro_rules! register_widget_with_many_resources {
}};
}
// pub fn widget_update_with_context<
// Props: PartialEq + Component + Clone,
// State: PartialEq + Component + Clone,
// Context: PartialEq + Component + Clone + Default,
// >(
// In((widget_context, entity, previous_entity)): In<(KayakWidgetContext, Entity, Entity)>,
// widget_param: WidgetParam<Props, State>,
// context_query: Query<Entity, Changed<Context>>,
// ) -> bool {
// // Uses bevy state changes to see if context has changed.
// if let Some(context_entity) = widget_context.get_context_entity::<Context>(entity) {
// if context_query.contains(context_entity) {
// log::trace!(
// "Entity context: {} has changed! {}-{}",
// std::any::type_name::<Context>(),
// widget_param.widget_names.get(entity).unwrap().0,
// entity.index()
// );
// return true;
// }
// }
//
// widget_param.has_changed(&widget_context, entity, previous_entity)
// }
#[macro_export]
macro_rules! register_complex_widget {
($ctx: expr, $props: ident, $state: ident, $system: ident, R($($r_name: ident: $resource: ident),*), C($($c_name: ident: $context: ident),*)) => {{
$ctx.add_widget_data::<$props, $state>();
$ctx.add_widget_system(
::kayak_ui::prelude::Widget::get_name(&$props::default()),
|
::bevy::prelude::In((widget_context, entity, previous_entity)): ::bevy::prelude::In<(::kayak_ui::prelude::KayakWidgetContext, ::bevy::prelude::Entity, ::bevy::prelude::Entity)>,
$( $r_name: ::bevy::prelude::Res<$resource> ),*,
$( $c_name: ::bevy::prelude::Query<::bevy::prelude::Entity, ::bevy::prelude::Changed<$context>> ),*,
widget_param: ::kayak_ui::prelude::WidgetParam<$props, $state>,
| {
$(
if let Some(context_entity) = widget_context.get_context_entity::<$context>(entity) {
if $c_name.contains(context_entity) {
return true;
}
}
)*
widget_param.has_changed(&widget_context, entity, previous_entity)
$( || $r_name.is_changed() )*
},
$system,
);
}};
}
pub fn widget_update_with_resource<
Props: PartialEq + Component + Clone,
State: PartialEq + Component + Clone,
......@@ -162,8 +227,10 @@ pub mod context {
use kayak_ui::widgets::KayakWidgetsContextPlugin;
use kayak_ui::KayakUIPlugin;
use crate::assets::AssetHandles;
use crate::register_widget;
use crate::ui::components::*;
use crate::ui::context::*;
use crate::ui::sync::{UIStatsData, UITradeData, UITravelInfo};
use crate::ui::widgets::*;
use crate::world::EncounterState;
......@@ -263,6 +330,30 @@ pub mod context {
UIStatsData,
render_stats_panel
);
register_widget_with_context!(
widget_context,
MainMenuPanelProps,
EmptyState,
MainMenuContext,
render_main_menu_panel
);
// register_widget_with_context!(
// widget_context,
// TipsPanelProps,
// TipsPanelState,
// MainMenuContext,
// render_tips_panel
// );
register_complex_widget! {
widget_context,
TipsPanelProps,
TipsPanelState,
render_tips_panel,
R(ass: AssetHandles),
C(mainmenucontext: MainMenuContext)
};
register_widget_with_resource!(
widget_context,
EncounterPanelProps,
......
use bevy::prelude::*;
use iyes_loopless::prelude::NextState;
use kayak_ui::prelude::*;
use kayak_ui::widgets::{ElementBundle, KImage, KImageBundle, TextProps, TextWidgetBundle};
use crate::assets::AssetHandles;
use crate::persistance::{fs_utils, LoadFileEvent};
use crate::system::flow::AppState;
use crate::ui::components::*;
use crate::ui::context::{MainMenuContext, MainMenuView};
use crate::ui::prelude::{pct, px, stretch, value};
use crate::ui::widgets::*;
use crate::{basic_widget, empty_props, on_button_click};
empty_props!(MainMenuPanelProps);
basic_widget!(MainMenuPanelProps => MainMenuPanel);
pub fn render_main_menu_panel(
In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
mut commands: Commands,
mut props_query: Query<&mut ComputedStyles>,
assets: Res<AssetHandles>,
) -> bool {
let parent_id = Some(entity);
let has_autosave = fs_utils::has_auto_save();
let contents_container_style = KStyle {
position_type: value(KPositionType::SelfDirected),
width: pct(65.0),
height: pct(80.0),
min_width: px(400.0),
min_height: px(300.0),
max_width: px(500.0),
max_height: px(400.0),
top: stretch(1.0),
left: stretch(1.0),
right: stretch(1.0),
bottom: stretch(1.0),
layout_type: value(LayoutType::Column),
row_between: px(20.0),
..Default::default()
};
let header_style = KStyle {
left: stretch(1.0),
right: stretch(1.0),
..Default::default()
};
let button_style = KStyle {
width: px(300.0),
left: stretch(1.0),
right: stretch(1.0),
..Default::default()
};
let on_new = on_button_click!(Commands, |mut commands: Commands| {
commands.insert_resource(NextState(AppState::InGame));
});
let on_tips = on_button_click!(Commands, |mut commands: Commands| {
commands.insert_resource(NextState(AppState::Tips));
});
let on_settings = on_button_click!(Commands, |mut commands: Commands| {
commands.insert_resource(NextState(AppState::Settings));
});
let on_continue = on_button_click!(EventWriter<LoadFileEvent>, |mut events: EventWriter<
LoadFileEvent,
>| {
events.send(LoadFileEvent::autosave());
});
rsx! {
<ElementBundle styles={contents_container_style}>
<TextWidgetBundle
text={TextProps {
content: String::from("Trader Tales"),
font: Some(String::from("header")),
size: 72.0,
..Default::default()
}}
styles={header_style}
/>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from("New Game"),
font_size: 32.0,
..Default::default()
}}
on_event={on_new}
/>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from("Continue Game"),
font_size: 32.0,
is_disabled: !has_autosave,
..Default::default()
}}
on_event={on_continue}
/>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from("Tips"),
font_size: 32.0,
..Default::default()
}}
on_event={on_tips}
/>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from("Settings"),
font_size: 32.0,
is_disabled: true,
..Default::default()
}}
/>
</ElementBundle>
};
true
}
mod encounter_panel;
mod main_menu_panel;
mod shop_panel;
mod stats_panel;
mod tavern_panel;
mod tips_panel;
mod town_menu;
mod transit_panel;
pub use encounter_panel::{render_encounter_panel, EncounterPanel, EncounterPanelProps};
pub use main_menu_panel::{render_main_menu_panel, MainMenuPanel, MainMenuPanelProps};
pub use shop_panel::{render_shop_panel, ShopPanel, ShopPanelProps};
pub use stats_panel::{render_stats_panel, StatsPanel, StatsPanelProps};
pub use tavern_panel::{render_tavern_panel, TavernPanel, TavernPanelProps};
pub use tips_panel::{render_tips_panel, TipsPanel, TipsPanelProps, TipsPanelState};
pub use town_menu::{
render_town_menu_panel, TownMenuPanel, TownMenuPanelProps, TownMenuPanelState,
};
......
use bevy::prelude::*;
use iyes_loopless::prelude::NextState;
use kayak_ui::prelude::*;
use kayak_ui::widgets::{
BackgroundBundle, ElementBundle, KImage, KImageBundle, TextProps, TextWidgetBundle,
};
use crate::assets::AssetHandles;
use crate::persistance::{fs_utils, LoadFileEvent};
use crate::system::flow::AppState;
use crate::ui::components::*;
use crate::ui::context::{MainMenuContext, MainMenuView};
use crate::ui::prelude::{edge_px, pct, px, stretch, value};
use crate::ui::widgets::*;
use crate::{basic_widget, empty_props, on_button_click};
empty_props!(TipsPanelProps);
basic_widget!(TipsPanelProps => TipsPanel);
#[derive(Default, Component, Clone, Copy, Eq, PartialEq)]
pub struct TipsPanelState {
tip_index: usize,
}
pub fn render_tips_panel(
In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
mut commands: Commands,
assets: Res<AssetHandles>,
mut props_query: Query<&mut ComputedStyles>,
state_query: Query<&TipsPanelState>,
) -> bool {
let parent_id = Some(entity);
let state_entity = widget_context.use_state(&mut commands, entity, TipsPanelState::default());
if let Ok(mut computed) = props_query.get_mut(entity) {
if let Ok(state) = state_query.get(state_entity) {
let tips = vec![
"Town merchants will only pay 80% of their sell price when buying goods from you",
"Be sure to tip your barkeep, they usually have great information on the various towns",
"Your game will be saved when you enter a town - make sure you reach your next destination to save your progress!",
"Without a regular supply of foods, towns might starve. Visit the tavern to check up on the locals.",
];
let tips_len = tips.len();
let contents_container_style = KStyle {
position_type: value(KPositionType::SelfDirected),
width: pct(65.0),
height: pct(80.0),
min_width: px(400.0),
min_height: px(300.0),
max_width: px(500.0),
max_height: px(400.0),
top: stretch(1.0),
left: stretch(1.0),
right: stretch(1.0),
bottom: stretch(1.0),
layout_type: value(LayoutType::Column),
row_between: px(20.0),
color: value(Color::BLACK),
..Default::default()
};
let header_style = KStyle {
left: stretch(1.0),
right: stretch(1.0),
..Default::default()
};
let tip_style = KStyle {
height: stretch(1.0),
padding_left: px(20.0),
padding_right: px(20.0),
..Default::default()
};
let button_style = KStyle {
..Default::default()
};
let controls_style = KStyle {
top: stretch(1.0),
layout_type: value(LayoutType::Row),
col_between: stretch(1.0),
..Default::default()
};
let on_next_tip = on_button_click!(Query<&mut TipsPanelState>, |mut query: Query<
&mut TipsPanelState,
>| {
if let Ok(mut state) = query.get_mut(state_entity) {
state.tip_index = if state.tip_index == tips_len - 1 {
0
} else {
state.tip_index + 1
};
}
});
let on_previous_tip =
on_button_click!(Query<&mut TipsPanelState>, |mut query: Query<
&mut TipsPanelState,
>| {
if let Ok(mut state) = query.get_mut(state_entity) {
state.tip_index = if state.tip_index == 0 {
tips_len - 1
} else {
state.tip_index - 1
};
}
});
let on_back = on_button_click!(Commands, |mut commands: Commands| commands
.insert_resource(NextState(AppState::Menu)));
rsx! {
<ElementBundle>
<PanelWidget styles={contents_container_style}>
<TextWidgetBundle
text={TextProps {
content: format!("Tip #{}", state.tip_index + 1),
font: Some(String::from("header")),
size: 52.0,
..Default::default()
}}
styles={header_style}
/>
<BackgroundBundle
styles={KStyle {
height: stretch(1.0),
width: pct(80.0),
left: stretch(1.0),
right: stretch(1.0),
top: px(30.0),
bottom: px(30.0),
..Default::default()
}}
>
<TextWidgetBundle
text={TextProps {
content: tips[state.tip_index].to_string(),
size: 32.0,
..Default::default()
}}
/>
</BackgroundBundle>
<BackgroundBundle styles={controls_style}>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from("<"),
font_size: 32.0,
..Default::default()
}}
on_event={on_previous_tip}
/>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from("back"),
font_size: 32.0,
..Default::default()
}}
on_event={on_back}
/>
<ButtonWidget
styles={button_style.clone()}
props={ButtonWidgetProps {
text: String::from(">"),
font_size: 32.0,
..Default::default()
}}
on_event={on_next_tip}
/>
</BackgroundBundle>
</PanelWidget>
</ElementBundle>
};
}
}
true
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment