move menu work, start on preliminary save system
This commit is contained in:
+110
-19
@@ -1,4 +1,8 @@
|
||||
use crate::save::get_saves;
|
||||
use crate::{AppState, WINDOW_TARGET_HEIGHT, WINDOW_TARGET_WIDTH};
|
||||
use bevy::color::palettes::tailwind::SLATE_900;
|
||||
use bevy::input_focus::tab_navigation::TabIndex;
|
||||
use bevy::text::{EditableText, TextCursorStyle};
|
||||
use bevy::ui_widgets::Button;
|
||||
use bevy::{prelude::*, ui_widgets::Activate};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
@@ -9,6 +13,7 @@ impl Plugin for MainMenuPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(OnEnter(AppState::Menu), setup_menu)
|
||||
.add_systems(OnExit(AppState::Menu), cleanup_menu)
|
||||
// .add_systems(Startup, enable_ui_debug)
|
||||
.add_systems(Update, (menu_redraw).run_if(in_state(AppState::Menu)))
|
||||
.add_observer(button_activate_observer)
|
||||
.add_systems(Update, (scale_ui, style_ui_elements));
|
||||
@@ -78,6 +83,7 @@ pub enum MenuLayer {
|
||||
Root,
|
||||
Play,
|
||||
LoadSave,
|
||||
NewGame,
|
||||
Browse,
|
||||
DirectConnect,
|
||||
Settings,
|
||||
@@ -110,16 +116,31 @@ impl MenuLayer {
|
||||
menu_button("Direct Connect", Some(MenuLayer::DirectConnect)),
|
||||
]
|
||||
}),
|
||||
MenuLayer::LoadSave => Box::new(bsn! {
|
||||
menu_layer(layer)
|
||||
MenuLayer::LoadSave => {
|
||||
// TODO: this needs to be on an IO thread
|
||||
let saves = get_saves().unwrap_or_default();
|
||||
let entries: Vec<_> = saves
|
||||
.into_iter()
|
||||
.map(|m| menu_button(m.save_name, None))
|
||||
.collect();
|
||||
|
||||
Box::new(bsn! {
|
||||
menu_layer(layer)
|
||||
ChildOf(menu_root)
|
||||
Children [
|
||||
{entries}
|
||||
(
|
||||
menu_button("New Game", Some(MenuLayer::NewGame))
|
||||
InteractionColors::GOOD
|
||||
),
|
||||
]
|
||||
})
|
||||
}
|
||||
MenuLayer::NewGame => Box::new(bsn! {
|
||||
full_menu_layer(layer)
|
||||
ChildOf(menu_root)
|
||||
Children [
|
||||
menu_button("Save 1", None),
|
||||
menu_button("Save 2", None),
|
||||
(
|
||||
menu_button("New Game", None)
|
||||
InteractionColors::GOOD
|
||||
),
|
||||
{new_game_menu()}
|
||||
]
|
||||
}),
|
||||
MenuLayer::Browse => Box::new(bsn! {
|
||||
@@ -170,6 +191,13 @@ struct LastMenu(Vec<MenuLayer>);
|
||||
#[derive(Resource, Debug, Clone, PartialEq, Eq, Hash, Deref, DerefMut)]
|
||||
struct CurrentMenu(Vec<MenuLayer>);
|
||||
|
||||
// fn enable_ui_debug(mut debug_options: ResMut<GlobalUiDebugOptions>) {
|
||||
// debug_options.enabled = true;
|
||||
// debug_options.outline_border_box = true;
|
||||
// debug_options.outline_padding_box = true;
|
||||
// debug_options.outline_content_box = true;
|
||||
// }
|
||||
|
||||
fn setup_menu(mut commands: Commands) {
|
||||
commands.insert_resource(CurrentMenu(vec![MenuLayer::Root]));
|
||||
commands.insert_resource(LastMenu(vec![]));
|
||||
@@ -233,6 +261,70 @@ fn menu_redraw(
|
||||
}
|
||||
}
|
||||
|
||||
fn new_game_menu() -> impl SceneList {
|
||||
bsn_list![
|
||||
(
|
||||
Text("New Game")
|
||||
Node {
|
||||
align_self: AlignSelf::Center,
|
||||
}
|
||||
TextFont {
|
||||
// font: FontSourceTemplate::Handle("fonts/FiraSans-Bold.ttf"),
|
||||
font_size: px(100.0),
|
||||
}
|
||||
TextColor(Color::srgb(0.9, 0.9, 0.9))
|
||||
TextShadow
|
||||
),
|
||||
(
|
||||
Text("Save Name")
|
||||
Node {
|
||||
margin: UiRect::axes(px(12), px(0)),
|
||||
}
|
||||
TextFont {
|
||||
// font: FontSourceTemplate::Handle("fonts/FiraSans-Bold.ttf"),
|
||||
font_size: px(66.0),
|
||||
}
|
||||
TextColor(Color::srgb(0.9, 0.9, 0.9))
|
||||
TextShadow
|
||||
),
|
||||
(
|
||||
#NewGameTextField
|
||||
Node {
|
||||
border: Val::all(px(6)),
|
||||
padding: Val::all(px(12)),
|
||||
border_radius: BorderRadius::all(px(12)),
|
||||
}
|
||||
// BorderColor::from(SLATE_800)
|
||||
BorderColor::from(SLATE_900)
|
||||
EditableText {
|
||||
cursor_width: 0.05,
|
||||
}
|
||||
TextLayout::no_wrap()
|
||||
TextFont {
|
||||
font_size: FontSize::Px(66.),
|
||||
}
|
||||
TextCursorStyle {
|
||||
color: Color::BLACK
|
||||
}
|
||||
TabIndex(0)
|
||||
BackgroundColor(Color::srgb(0.48, 0.84, 0.87))
|
||||
),
|
||||
(
|
||||
Node {
|
||||
margin: UiRect::top(px(48)),
|
||||
}
|
||||
Children [
|
||||
menu_button("Create", None)
|
||||
Node {
|
||||
margin: UiRect::left(Val::Auto),
|
||||
}
|
||||
InteractionColors::GOOD
|
||||
on(|event: On<Activate>, q_text:| { info!("create!") })
|
||||
]
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
fn menu_layer(layer: usize) -> impl Scene {
|
||||
let name = format!("MenuLayer{}", layer);
|
||||
bsn! {
|
||||
@@ -242,8 +334,6 @@ fn menu_layer(layer: usize) -> impl Scene {
|
||||
width: percent(100.0 / N_LAYERS as f32),
|
||||
height: percent(100),
|
||||
flex_direction: FlexDirection::Column,
|
||||
// align_items: AlignItems::Start,
|
||||
align_items: AlignItems::Baseline,
|
||||
justify_content: JustifyContent::FlexEnd,
|
||||
row_gap: px(100),
|
||||
}
|
||||
@@ -251,21 +341,22 @@ fn menu_layer(layer: usize) -> impl Scene {
|
||||
}
|
||||
|
||||
fn full_menu_layer(layer: usize) -> impl Scene {
|
||||
let name = format!("FullMenuLayer{}", layer);
|
||||
bsn! {
|
||||
menu_layer(layer)
|
||||
Name(name)
|
||||
Layer(layer)
|
||||
Node {
|
||||
width: Val::Auto,
|
||||
flex_direction: FlexDirection::Column,
|
||||
align_self: AlignSelf::FlexEnd,
|
||||
flex_grow: 1.,
|
||||
border_radius: BorderRadius::all(px(24)),
|
||||
padding: Val::all(px(24)),
|
||||
}
|
||||
BackgroundColor(Color::srgba(0.8, 0.1, 0.1, 0.7))
|
||||
BackgroundColor(Color::srgb(0.4, 0.4, 0.4))
|
||||
}
|
||||
}
|
||||
|
||||
fn menu_button(label: &str, next_layer: Option<MenuLayer>) -> impl Scene {
|
||||
let next_layer_component = next_layer
|
||||
.map(|n| Box::new(bsn! { NextLayer(n) }) as Box<dyn Scene>)
|
||||
.unwrap_or(Box::new(bsn! {}));
|
||||
|
||||
fn menu_button(label: impl Into<String>, next_layer: Option<MenuLayer>) -> impl Scene {
|
||||
bsn! {
|
||||
Button
|
||||
Node {
|
||||
@@ -277,7 +368,7 @@ fn menu_button(label: &str, next_layer: Option<MenuLayer>) -> impl Scene {
|
||||
align_items: AlignItems::Center,
|
||||
margin: UiRect::all(px(4)),
|
||||
}
|
||||
next_layer_component
|
||||
{next_layer.map(|l| template_value(NextLayer(l)))}
|
||||
BorderColor::from(Color::BLACK)
|
||||
InteractionColors::DEFAULT
|
||||
Interaction
|
||||
|
||||
Reference in New Issue
Block a user