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

Implement settings menu

parent 9b22b4e7
No related branches found
No related tags found
No related merge requests found
Pipeline #256 failed with stages
in 3 minutes and 50 seconds
......@@ -124,10 +124,10 @@ pub fn render_button_widget(
}
if should_click {
params.p2().play_sfx("ui_ping");
params.p2().play_ui_sfx("ui_ping");
}
if should_proing {
params.p2().play_sfx("ui_confirm");
params.p2().play_ui_sfx("ui_confirm");
}
(event_dispatcher_context, event)
......
......@@ -93,6 +93,7 @@ mod _config {
.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_enter_system(AppState::Settings, super::screens::render_menu_settings_ui)
.add_exit_system(AppState::InGame, remove_ui)
.add_exit_system(AppState::Tips, remove_ui)
.add_exit_system(AppState::Settings, remove_ui)
......
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!(MainMenuSettingsProps);
parent_widget!(MainMenuSettingsProps => MainMenuSettingsLayout);
#[derive(Component, PartialEq, Eq, Clone, Default)]
pub struct MainMenuState {
bg_idx: usize,
}
pub fn render_main_menu_settings_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} />
<SettingsPanel />
</ElementBundle>
};
}
true
}
pub fn render_menu_settings_ui(mut commands: Commands) {
let parent_id = None;
let mut widget_context = create_main_menu_context();
rsx! {
<KayakAppBundle>
<MainMenuSettingsLayout />
</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,
MainMenuSettingsProps,
MainMenuState,
render_main_menu_settings_layout
);
widget_context
}
mod in_game;
mod main_menu;
mod main_menu_settings;
mod main_menu_tips;
pub use in_game::render_in_game_ui;
pub use main_menu::render_menu_ui;
pub use main_menu_settings::render_menu_settings_ui;
pub use main_menu_tips::render_menu_tips_ui;
......@@ -226,6 +226,7 @@ pub mod context {
use kayak_ui::prelude::{widget_update, EmptyState, KayakRootContext};
use kayak_ui::widgets::KayakWidgetsContextPlugin;
use kayak_ui::KayakUIPlugin;
use micro_musicbox::prelude::AudioSettings;
use crate::assets::AssetHandles;
use crate::register_widget;
......@@ -361,6 +362,13 @@ pub mod context {
EncounterState,
render_encounter_panel
);
register_widget_with_resource!(
widget_context,
SettingsPanelProps,
EmptyState,
AudioSettings,
render_settings_panel
);
}
}
}
......
......@@ -115,9 +115,9 @@ pub fn render_main_menu_panel(
props={ButtonWidgetProps {
text: String::from("Settings"),
font_size: 32.0,
is_disabled: true,
..Default::default()
}}
on_event={on_settings}
/>
</ElementBundle>
};
......
mod encounter_panel;
mod main_menu_panel;
mod settings_panel;
mod shop_panel;
mod stats_panel;
mod tavern_panel;
......@@ -9,6 +10,7 @@ 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 settings_panel::{render_settings_panel, SettingsPanel, SettingsPanelProps};
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};
......
use bevy::prelude::*;
use iyes_loopless::prelude::NextState;
use kayak_ui::prelude::*;
use kayak_ui::widgets::{
BackgroundBundle, ElementBundle, KImage, KImageBundle, TextProps, TextWidgetBundle,
};
use micro_musicbox::prelude::AudioSettings;
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!(SettingsPanelProps);
basic_widget!(SettingsPanelProps => SettingsPanel);
#[derive(Default, Component, Clone, Copy, Eq, PartialEq)]
pub struct SettingsPanelState {
tip_index: usize,
}
pub fn render_settings_panel(
In((widget_context, entity)): In<(KayakWidgetContext, Entity)>,
mut commands: Commands,
assets: Res<AssetHandles>,
audio: Res<AudioSettings>,
) -> bool {
let parent_id = Some(entity);
let state_entity =
widget_context.use_state(&mut commands, entity, SettingsPanelState::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),
color: value(Color::BLACK),
..Default::default()
};
let header_style = KStyle {
left: stretch(1.0),
right: stretch(1.0),
bottom: px(30.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 row_style = KStyle {
layout_type: value(LayoutType::Row),
col_between: px(10.0),
height: px(60.0),
padding_top: stretch(1.0),
padding_bottom: stretch(1.0),
..Default::default()
};
rsx! {
<ElementBundle styles={contents_container_style}>
<PanelWidget>
<TextWidgetBundle
text={TextProps {
content: String::from("Settings"),
font: Some(String::from("header")),
size: 52.0,
..Default::default()
}}
styles={header_style}
/>
<BackgroundBundle
styles={row_style.clone()}
>
<TextWidgetBundle
text={TextProps {
content: String::from("Master Volume"),
size: 32.0,
..Default::default()
}}
/>
<BackgroundBundle styles={KStyle { width: stretch(1.0), ..Default::default() }} />
<ButtonWidget
props={ButtonWidgetProps {
text: String::from("-"),
font_size: 24.0,
..Default::default()
}}
on_event={on_button_click!(ResMut<AudioSettings>, |mut settings: ResMut<
AudioSettings,
>| {
settings.master_volume = (settings.master_volume - 0.05).max(0.0);
})}
/>
<BackgroundBundle
styles={KStyle {
padding_left: stretch(1.0),
padding_right: stretch(1.0),
padding_top: stretch(1.0),
padding_bottom: stretch(1.0),
width: px(100.0),
..Default::default()
}}
>
<TextWidgetBundle
text={TextProps {
content: format!("{:.0}", audio.master_volume * 100.0),
size: 32.0,
..Default::default()
}}
/>
</BackgroundBundle>
<ButtonWidget
props={ButtonWidgetProps {
text: String::from("+"),
font_size: 24.0,
..Default::default()
}}
on_event={on_button_click!(ResMut<AudioSettings>, |mut settings: ResMut<
AudioSettings,
>| {
settings.master_volume = (settings.master_volume + 0.05).min(1.0);
})}
/>
</BackgroundBundle>
<BackgroundBundle
styles={row_style.clone()}
>
<TextWidgetBundle
text={TextProps {
content: String::from("Music Volume"),
size: 32.0,
..Default::default()
}}
/>
<BackgroundBundle styles={KStyle { width: stretch(1.0), ..Default::default() }} />
<ButtonWidget
props={ButtonWidgetProps {
text: String::from("-"),
font_size: 24.0,
..Default::default()
}}
on_event={on_button_click!(ResMut<AudioSettings>, |mut settings: ResMut<
AudioSettings,
>| {
settings.music_volume = (settings.music_volume - 0.05).max(0.0);
})}
/>
<BackgroundBundle
styles={KStyle {
padding_left: stretch(1.0),
padding_right: stretch(1.0),
padding_top: stretch(1.0),
padding_bottom: stretch(1.0),
width: px(100.0),
..Default::default()
}}
>
<TextWidgetBundle
text={TextProps {
content: format!("{:.0}", audio.music_volume * 100.0),
size: 32.0,
..Default::default()
}}
/>
</BackgroundBundle>
<ButtonWidget
props={ButtonWidgetProps {
text: String::from("+"),
font_size: 24.0,
..Default::default()
}}
on_event={on_button_click!(ResMut<AudioSettings>, |mut settings: ResMut<
AudioSettings,
>| {
settings.music_volume = (settings.music_volume + 0.05).min(1.0);
})}
/>
</BackgroundBundle>
<BackgroundBundle
styles={row_style}
>
<TextWidgetBundle
text={TextProps {
content: String::from("UI Volume"),
size: 32.0,
..Default::default()
}}
/>
<BackgroundBundle styles={KStyle { width: stretch(1.0), ..Default::default() }} />
<ButtonWidget
props={ButtonWidgetProps {
text: String::from("-"),
font_size: 24.0,
..Default::default()
}}
on_event={on_button_click!(ResMut<AudioSettings>, |mut settings: ResMut<
AudioSettings,
>| {
settings.ui_volume = (settings.ui_volume - 0.05).max(0.0);
})}
/>
<BackgroundBundle
styles={KStyle {
padding_left: stretch(1.0),
padding_right: stretch(1.0),
padding_top: stretch(1.0),
padding_bottom: stretch(1.0),
width: px(100.0),
..Default::default()
}}
>
<TextWidgetBundle
text={TextProps {
content: format!("{:.0}", audio.ui_volume * 100.0),
size: 32.0,
..Default::default()
}}
/>
</BackgroundBundle>
<ButtonWidget
props={ButtonWidgetProps {
text: String::from("+"),
font_size: 24.0,
..Default::default()
}}
on_event={on_button_click!(ResMut<AudioSettings>, |mut settings: ResMut<
AudioSettings,
>| {
settings.ui_volume = (settings.ui_volume + 0.05).min(1.0);
})}
/>
</BackgroundBundle>
</PanelWidget>
<ButtonWidget
props={ButtonWidgetProps { text: String::from("Back"), font_size: 32.0, ..Default::default() }}
on_event={on_button_click!(Commands, |mut commands: Commands| {
commands.insert_resource(NextState(AppState::Menu));
})}
/>
</ElementBundle>
};
true
}
......@@ -80,7 +80,10 @@ pub fn render_tips_panel(
};
let controls_style = KStyle {
top: stretch(1.0),
// top: stretch(1.0),
height: px(60.0),
padding_top: stretch(1.0),
padding_bottom: stretch(1.0),
layout_type: value(LayoutType::Row),
col_between: stretch(1.0),
..Default::default()
......@@ -114,36 +117,36 @@ pub fn render_tips_panel(
.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()
}}
>
<ElementBundle styles={contents_container_style}>
<PanelWidget>
<TextWidgetBundle
text={TextProps {
content: tips[state.tip_index].to_string(),
size: 32.0,
content: format!("Tip #{}", state.tip_index + 1),
font: Some(String::from("header")),
size: 52.0,
..Default::default()
}}
styles={header_style}
/>
</BackgroundBundle>
<BackgroundBundle
styles={KStyle {
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>
</PanelWidget>
<BackgroundBundle styles={controls_style}>
<ButtonWidget
styles={button_style.clone()}
......@@ -175,8 +178,7 @@ pub fn render_tips_panel(
on_event={on_next_tip}
/>
</BackgroundBundle>
</PanelWidget>
</ElementBundle>
</ElementBundle>
};
}
......
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