Merge branch '56-add-ui-library' into 'dev'
Add UI Library See merge request softwaregrundprojekt/2025-2026/einzelprojekt/tutorium-moritz/bernroider-dominik/bernroider-dominik!15
This commit is contained in:
@@ -39,37 +39,27 @@ fn setup(mut commands: Commands) {
|
|||||||
},
|
},
|
||||||
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
|
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
|
||||||
children![
|
children![
|
||||||
(
|
text_with_component(TextType::Phase, "...", 16.0, Color::WHITE),
|
||||||
TextType::Phase,
|
text_with_component(TextType::Timer, "...", 16.0, Color::WHITE),
|
||||||
Text::new("..."),
|
button(
|
||||||
TextFont::from_font_size(16.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
),
|
|
||||||
(
|
|
||||||
TextType::Timer,
|
|
||||||
Text::new("--:--"),
|
|
||||||
TextFont::from_font_size(16.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Button,
|
|
||||||
inventory::components::ButtonType::InventoryOpen,
|
inventory::components::ButtonType::InventoryOpen,
|
||||||
Node::default(),
|
ButtonVariant::Secondary,
|
||||||
children![(
|
Node {
|
||||||
Text::new("Inventar"),
|
padding: UiRect::all(px(10)),
|
||||||
TextFont::from_font_size(16.0),
|
..default()
|
||||||
TextColor(Color::WHITE)
|
},
|
||||||
)]
|
"Inventar",
|
||||||
|
16.0
|
||||||
),
|
),
|
||||||
(
|
button(
|
||||||
Button,
|
|
||||||
ButtonType::SettingsOpen,
|
ButtonType::SettingsOpen,
|
||||||
Node::default(),
|
ButtonVariant::Secondary,
|
||||||
children![(
|
Node {
|
||||||
Text::new("Einstellungen"),
|
padding: UiRect::all(px(10)),
|
||||||
TextFont::from_font_size(16.0),
|
..default()
|
||||||
TextColor(Color::WHITE)
|
},
|
||||||
)]
|
"Einstellungen",
|
||||||
|
16.0
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ pub fn open_settings(commands: &mut Commands) {
|
|||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
width: percent(100),
|
width: percent(100),
|
||||||
height: percent(100),
|
height: percent(100),
|
||||||
justify_content: JustifyContent::Center,
|
..Node::center()
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..default()
|
|
||||||
},
|
},
|
||||||
ZIndex(1),
|
ZIndex(1),
|
||||||
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
|
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
|
||||||
@@ -21,10 +19,9 @@ pub fn open_settings(commands: &mut Commands) {
|
|||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Node {
|
Node {
|
||||||
flex_direction: FlexDirection::Column,
|
width: px(700),
|
||||||
align_items: AlignItems::Center,
|
|
||||||
padding: UiRect::all(px(20.0)),
|
padding: UiRect::all(px(20.0)),
|
||||||
..default()
|
..Node::vstack(px(20))
|
||||||
},
|
},
|
||||||
BackgroundColor(Color::srgb(0.2, 0.2, 0.2)),
|
BackgroundColor(Color::srgb(0.2, 0.2, 0.2)),
|
||||||
BorderRadius::all(px(10.0)),
|
BorderRadius::all(px(10.0)),
|
||||||
@@ -32,145 +29,97 @@ pub fn open_settings(commands: &mut Commands) {
|
|||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
Node {
|
Node {
|
||||||
width: percent(100.0),
|
|
||||||
justify_content: JustifyContent::SpaceBetween,
|
justify_content: JustifyContent::SpaceBetween,
|
||||||
align_items: AlignItems::Center,
|
..Node::hstack(px(20))
|
||||||
margin: UiRect::bottom(px(20.0)),
|
|
||||||
column_gap: px(20.0),
|
|
||||||
..default()
|
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
(
|
text("Spiel Einstellungen", 40.0, Color::WHITE),
|
||||||
Text::new("Spiel Einstellungen"),
|
pill_button(
|
||||||
TextFont::from_font_size(40.0),
|
|
||||||
TextColor(Color::WHITE),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Button,
|
|
||||||
ButtonType::SettingsClose,
|
ButtonType::SettingsClose,
|
||||||
|
ButtonVariant::Destructive,
|
||||||
Node {
|
Node {
|
||||||
width: px(40.0),
|
width: px(40),
|
||||||
height: px(40.0),
|
height: px(40),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(Color::srgb(0.8, 0.2, 0.2)),
|
"X",
|
||||||
BorderRadius::MAX,
|
24.0
|
||||||
children![(
|
),
|
||||||
Text::new("X"),
|
|
||||||
TextFont::from_font_size(24.0),
|
|
||||||
TextColor(Color::WHITE),
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
||||||
parent
|
parent
|
||||||
.spawn(Node {
|
.spawn(Node::vstack(px(10)))
|
||||||
width: percent(100),
|
|
||||||
flex_direction: FlexDirection::Column,
|
|
||||||
margin: UiRect::top(px(10.0)),
|
|
||||||
row_gap: px(10.0),
|
|
||||||
..default()
|
|
||||||
})
|
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn((
|
parent.spawn(button(
|
||||||
Button,
|
|
||||||
ButtonType::SettingsExit,
|
ButtonType::SettingsExit,
|
||||||
|
ButtonVariant::Secondary,
|
||||||
Node {
|
Node {
|
||||||
width: percent(100),
|
padding: UiRect::all(px(10)),
|
||||||
height: px(80),
|
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
padding: UiRect::horizontal(px(10.0)),
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
"Spiel verlassen",
|
||||||
BorderRadius::all(px(10)),
|
24.0,
|
||||||
children![(
|
|
||||||
Text::new("Spiel verlassen"),
|
|
||||||
TextFont::from_font_size(24.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
)],
|
|
||||||
));
|
));
|
||||||
|
|
||||||
parent.spawn((
|
parent.spawn(button(
|
||||||
Button,
|
|
||||||
ButtonType::SettingsSave,
|
ButtonType::SettingsSave,
|
||||||
|
ButtonVariant::Secondary,
|
||||||
Node {
|
Node {
|
||||||
width: percent(100),
|
padding: UiRect::all(px(10)),
|
||||||
height: px(80),
|
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
padding: UiRect::horizontal(px(10.0)),
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
"Spiel speichern",
|
||||||
BorderRadius::all(px(10)),
|
24.0,
|
||||||
children![(
|
|
||||||
Text::new("Spiel speichern"),
|
|
||||||
TextFont::from_font_size(24.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
)],
|
|
||||||
));
|
));
|
||||||
|
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
Node {
|
Node {
|
||||||
width: percent(100),
|
justify_content: JustifyContent::Center,
|
||||||
flex_direction: FlexDirection::Row,
|
..Node::hstack(px(30))
|
||||||
justify_content: JustifyContent::SpaceBetween,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
column_gap: px(10),
|
|
||||||
padding: UiRect::horizontal(px(10.0)),
|
|
||||||
..default()
|
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
flex_direction: FlexDirection::Column,
|
width: percent(40),
|
||||||
align_items: AlignItems::Center,
|
..Node::vstack(px(10))
|
||||||
row_gap: px(10),
|
|
||||||
..default()
|
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
(
|
text("Spiel Einstellungen", 18.0, Color::WHITE),
|
||||||
Text::new("Fokus Phase"),
|
text(
|
||||||
TextFont::from_font_size(12.0),
|
"Tipp: Benutze [Umstellen] um in 10er Schritten zu inkrementieren oder dekrementieren!",
|
||||||
TextColor(Color::WHITE)
|
16.0,
|
||||||
|
Color::WHITE
|
||||||
),
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Node {
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
..Node::vstack(px(10))
|
||||||
|
},
|
||||||
|
children![
|
||||||
|
text("Fokus Phase", 12.0, Color::WHITE),
|
||||||
timer_settings(TimerType::Focus)
|
timer_settings(TimerType::Focus)
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
flex_direction: FlexDirection::Column,
|
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
row_gap: px(10),
|
..Node::vstack(px(10))
|
||||||
..default()
|
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
(
|
text("Kurze Pause", 12.0, Color::WHITE),
|
||||||
Text::new("Kurze Pause"),
|
|
||||||
TextFont::from_font_size(12.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
),
|
|
||||||
timer_settings(TimerType::ShortBreak)
|
timer_settings(TimerType::ShortBreak)
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
flex_direction: FlexDirection::Column,
|
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
row_gap: px(10),
|
..Node::vstack(px(10))
|
||||||
..default()
|
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
(
|
text("Lange Pause", 12.0, Color::WHITE),
|
||||||
Text::new("Lange Pause"),
|
|
||||||
TextFont::from_font_size(12.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
),
|
|
||||||
timer_settings(TimerType::LongBreak)
|
timer_settings(TimerType::LongBreak)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,17 +4,12 @@ use crate::prelude::*;
|
|||||||
pub fn timer_settings(timer_type: TimerType) -> impl Bundle {
|
pub fn timer_settings(timer_type: TimerType) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
flex_direction: FlexDirection::Row,
|
|
||||||
align_items: AlignItems::Center,
|
align_items: AlignItems::Center,
|
||||||
..default()
|
..Node::hstack(px(0))
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
timer_settings_part(SettingsTimerInput::Minutes(timer_type.clone()), 1),
|
timer_settings_part(SettingsTimerInput::Minutes(timer_type.clone()), 1),
|
||||||
(
|
text(":", 24.0, Color::WHITE),
|
||||||
Text::new(":"),
|
|
||||||
TextFont::from_font_size(24.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
),
|
|
||||||
timer_settings_part(SettingsTimerInput::Seconds(timer_type.clone()), 1),
|
timer_settings_part(SettingsTimerInput::Seconds(timer_type.clone()), 1),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -22,52 +17,34 @@ pub fn timer_settings(timer_type: TimerType) -> impl Bundle {
|
|||||||
|
|
||||||
fn timer_settings_part(input: SettingsTimerInput, amount: u32) -> impl Bundle {
|
fn timer_settings_part(input: SettingsTimerInput, amount: u32) -> impl Bundle {
|
||||||
(
|
(
|
||||||
Node {
|
Node::vstack(px(0)),
|
||||||
flex_direction: FlexDirection::Column,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
children![
|
children![
|
||||||
(
|
button(
|
||||||
Button,
|
|
||||||
ButtonType::SettingsTimerChange {
|
ButtonType::SettingsTimerChange {
|
||||||
input: input.clone(),
|
input: input.clone(),
|
||||||
amount: amount as i32
|
amount: amount as i32
|
||||||
},
|
},
|
||||||
|
ButtonVariant::Secondary,
|
||||||
Node {
|
Node {
|
||||||
width: auto(),
|
width: percent(100),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
"+",
|
||||||
children![
|
12.0
|
||||||
Text::new("+"),
|
|
||||||
TextFont::from_font_size(12.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
]
|
|
||||||
),
|
),
|
||||||
(
|
text_with_component(input.clone(), "--", 24.0, Color::WHITE),
|
||||||
input.clone(),
|
button(
|
||||||
Text::new("--"),
|
|
||||||
TextFont::from_font_size(24.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Button,
|
|
||||||
ButtonType::SettingsTimerChange {
|
ButtonType::SettingsTimerChange {
|
||||||
input: input.clone(),
|
input: input.clone(),
|
||||||
amount: -(amount as i32),
|
amount: -(amount as i32)
|
||||||
},
|
},
|
||||||
|
ButtonVariant::Secondary,
|
||||||
Node {
|
Node {
|
||||||
width: auto(),
|
width: percent(100),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
"-",
|
||||||
children![
|
12.0
|
||||||
Text::new("-"),
|
|
||||||
TextFont::from_font_size(12.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
]
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ pub fn open_inventory(commands: &mut Commands, items: Query<&ItemStack>) {
|
|||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
width: percent(100),
|
width: percent(100),
|
||||||
height: percent(100),
|
height: percent(100),
|
||||||
justify_content: JustifyContent::Center,
|
..Node::center()
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..default()
|
|
||||||
},
|
},
|
||||||
ZIndex(1),
|
ZIndex(1),
|
||||||
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
|
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
|
||||||
@@ -20,10 +18,8 @@ pub fn open_inventory(commands: &mut Commands, items: Query<&ItemStack>) {
|
|||||||
parent
|
parent
|
||||||
.spawn((
|
.spawn((
|
||||||
Node {
|
Node {
|
||||||
flex_direction: FlexDirection::Column,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
padding: UiRect::all(px(20.0)),
|
padding: UiRect::all(px(20.0)),
|
||||||
..default()
|
..Node::vstack(px(0))
|
||||||
},
|
},
|
||||||
BackgroundColor(Color::srgb(0.2, 0.2, 0.2)),
|
BackgroundColor(Color::srgb(0.2, 0.2, 0.2)),
|
||||||
BorderRadius::all(px(10.0)),
|
BorderRadius::all(px(10.0)),
|
||||||
@@ -33,45 +29,30 @@ pub fn open_inventory(commands: &mut Commands, items: Query<&ItemStack>) {
|
|||||||
Node {
|
Node {
|
||||||
width: percent(100.0),
|
width: percent(100.0),
|
||||||
justify_content: JustifyContent::SpaceBetween,
|
justify_content: JustifyContent::SpaceBetween,
|
||||||
align_items: AlignItems::Center,
|
|
||||||
margin: UiRect::bottom(px(20.0)),
|
margin: UiRect::bottom(px(20.0)),
|
||||||
column_gap: px(20.0),
|
..Node::hstack(px(20))
|
||||||
..default()
|
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
(
|
text("Inventar", 40.0, Color::WHITE),
|
||||||
Text::new("Inventar"),
|
pill_button(
|
||||||
TextFont::from_font_size(40.0),
|
|
||||||
TextColor(Color::WHITE),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Button,
|
|
||||||
ButtonType::InventoryClose,
|
ButtonType::InventoryClose,
|
||||||
|
ButtonVariant::Destructive,
|
||||||
Node {
|
Node {
|
||||||
width: px(40.0),
|
width: px(40),
|
||||||
height: px(40.0),
|
height: px(40),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(Color::srgb(0.8, 0.2, 0.2)),
|
"X",
|
||||||
BorderRadius::MAX,
|
24.0
|
||||||
children![(
|
),
|
||||||
Text::new("X"),
|
|
||||||
TextFont::from_font_size(24.0),
|
|
||||||
TextColor(Color::WHITE),
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
|
|
||||||
parent
|
parent
|
||||||
.spawn(Node {
|
.spawn(Node {
|
||||||
width: percent(100),
|
width: percent(100),
|
||||||
flex_direction: FlexDirection::Column,
|
|
||||||
margin: UiRect::top(px(10.0)),
|
margin: UiRect::top(px(10.0)),
|
||||||
row_gap: px(10.0),
|
..Node::vstack(px(10))
|
||||||
..default()
|
|
||||||
})
|
})
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
for itemstack in items.iter() {
|
for itemstack in items.iter() {
|
||||||
|
|||||||
@@ -8,13 +8,10 @@ pub fn list_itemstack(itemstack: &ItemStack) -> impl Bundle {
|
|||||||
|
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
flex_direction: FlexDirection::Row,
|
|
||||||
column_gap: px(8),
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
padding: UiRect::all(px(4)),
|
padding: UiRect::all(px(4)),
|
||||||
..default()
|
..Node::hstack(px(8))
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
BackgroundColor(ButtonVariant::Secondary.normal_background()),
|
||||||
BorderRadius::all(px(10)),
|
BorderRadius::all(px(10)),
|
||||||
children![
|
children![
|
||||||
(
|
(
|
||||||
@@ -24,28 +21,22 @@ pub fn list_itemstack(itemstack: &ItemStack) -> impl Bundle {
|
|||||||
aspect_ratio: Some(1.0),
|
aspect_ratio: Some(1.0),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(HOVERED_BUTTON),
|
BackgroundColor(ButtonVariant::Secondary.hover_background()),
|
||||||
BorderRadius::all(px(10))
|
BorderRadius::all(px(10))
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
flex_direction: FlexDirection::Column,
|
|
||||||
justify_content: JustifyContent::Center,
|
justify_content: JustifyContent::Center,
|
||||||
row_gap: px(4),
|
|
||||||
padding: UiRect::vertical(px(4)),
|
padding: UiRect::vertical(px(4)),
|
||||||
..default()
|
..Node::vstack(px(4))
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
(
|
text(
|
||||||
Text::new(format!("{} ({})", name, itemstack.amount)),
|
format!("{} ({})", name, itemstack.amount),
|
||||||
TextFont::from_font_size(14.0),
|
14.0,
|
||||||
TextColor(Color::WHITE)
|
Color::WHITE
|
||||||
),
|
),
|
||||||
(
|
text(itemstack.item_type.description(), 10.0, Color::WHITE)
|
||||||
Text::new(itemstack.item_type.description()),
|
|
||||||
TextFont::from_font_size(10.0),
|
|
||||||
TextColor(Color::WHITE)
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -92,3 +92,15 @@ impl SavegamePath {
|
|||||||
Self::new(next_index)
|
Self::new(next_index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub enum RootMarker {
|
||||||
|
PopupSavegameLoad,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)]
|
||||||
|
pub enum ButtonType {
|
||||||
|
SavegameLoad { savegame_path: SavegamePath },
|
||||||
|
SavegameDelete { savegame_path: SavegamePath },
|
||||||
|
PopupClose,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::features::phase::components::{SessionTracker, TimerSettings};
|
use crate::features::phase::components::{SessionTracker, TimerSettings};
|
||||||
|
use crate::features::savegame::ui::load_popup_handler;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use messages::*;
|
use messages::*;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
@@ -6,6 +7,7 @@ use std::io::{Read, Write};
|
|||||||
|
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
|
pub mod ui;
|
||||||
|
|
||||||
pub struct SavegamePlugin;
|
pub struct SavegamePlugin;
|
||||||
|
|
||||||
@@ -16,6 +18,8 @@ impl Plugin for SavegamePlugin {
|
|||||||
|
|
||||||
app.add_systems(Update, dump_savegame.run_if(in_state(AppState::GameScreen)));
|
app.add_systems(Update, dump_savegame.run_if(in_state(AppState::GameScreen)));
|
||||||
app.add_systems(Update, load_savegame.run_if(in_state(AppState::GameScreen)));
|
app.add_systems(Update, load_savegame.run_if(in_state(AppState::GameScreen)));
|
||||||
|
|
||||||
|
app.add_systems(Update, load_popup_handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::super::components::*;
|
use super::super::components::{ButtonType, RootMarker};
|
||||||
use crate::prelude::*;
|
use crate::{features::savegame::messages::SavegameLoadMessage, prelude::*};
|
||||||
|
|
||||||
pub fn spawn_load_popup(commands: &mut Commands) {
|
pub fn spawn_load_popup(commands: &mut Commands) {
|
||||||
commands
|
commands
|
||||||
@@ -9,9 +9,7 @@ pub fn spawn_load_popup(commands: &mut Commands) {
|
|||||||
position_type: PositionType::Absolute,
|
position_type: PositionType::Absolute,
|
||||||
width: percent(100),
|
width: percent(100),
|
||||||
height: percent(100),
|
height: percent(100),
|
||||||
justify_content: JustifyContent::Center,
|
..Node::center()
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..default()
|
|
||||||
},
|
},
|
||||||
ZIndex(1),
|
ZIndex(1),
|
||||||
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
|
BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.8)),
|
||||||
@@ -22,13 +20,12 @@ pub fn spawn_load_popup(commands: &mut Commands) {
|
|||||||
Node {
|
Node {
|
||||||
width: px(600.0),
|
width: px(600.0),
|
||||||
height: px(500.0),
|
height: px(500.0),
|
||||||
flex_direction: FlexDirection::Column,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
padding: UiRect::all(px(20.0)),
|
padding: UiRect::all(px(20.0)),
|
||||||
..default()
|
align_items: AlignItems::Center,
|
||||||
|
..Node::vstack(px(10))
|
||||||
},
|
},
|
||||||
BackgroundColor(Color::srgb(0.2, 0.2, 0.2)),
|
BackgroundColor(Color::srgb(0.2, 0.2, 0.2)),
|
||||||
BorderRadius::all(Val::Px(10.0)),
|
BorderRadius::all(px(10.0)),
|
||||||
))
|
))
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
@@ -40,27 +37,17 @@ pub fn spawn_load_popup(commands: &mut Commands) {
|
|||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
(
|
text("Spielstand Auswahl", 40.0, Color::WHITE),
|
||||||
Text::new("Spielstand Auswahl"),
|
pill_button(
|
||||||
TextFont::from_font_size(40.0),
|
|
||||||
TextColor(Color::WHITE),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Button,
|
|
||||||
ButtonType::PopupClose,
|
ButtonType::PopupClose,
|
||||||
|
ButtonVariant::Destructive,
|
||||||
Node {
|
Node {
|
||||||
width: px(40.0),
|
width: px(40),
|
||||||
height: px(40.0),
|
height: px(40),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(Color::srgb(0.8, 0.2, 0.2)),
|
"X",
|
||||||
children![(
|
24.0
|
||||||
Text::new("X"),
|
|
||||||
TextFont::from_font_size(24.0),
|
|
||||||
TextColor(Color::WHITE),
|
|
||||||
)]
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
@@ -78,20 +65,20 @@ pub fn spawn_load_popup(commands: &mut Commands) {
|
|||||||
for savegame in SavegamePath::list() {
|
for savegame in SavegamePath::list() {
|
||||||
parent.spawn((
|
parent.spawn((
|
||||||
Button,
|
Button,
|
||||||
ButtonType::PopupSavegameLoad {
|
ButtonType::SavegameLoad {
|
||||||
savegame_path: savegame.path.clone(),
|
savegame_path: savegame.path.clone(),
|
||||||
},
|
},
|
||||||
|
ButtonVariant::Secondary,
|
||||||
Node {
|
Node {
|
||||||
width: percent(100),
|
width: percent(100),
|
||||||
height: px(80),
|
height: px(80),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
flex_direction: FlexDirection::Row,
|
flex_direction: FlexDirection::Row,
|
||||||
column_gap: px(10.0),
|
column_gap: px(10.0),
|
||||||
padding: UiRect::horizontal(px(10.0)),
|
padding: UiRect::horizontal(px(10.0)),
|
||||||
..default()
|
..Node::center()
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
BackgroundColor(ButtonVariant::Secondary.normal_background()),
|
||||||
|
BorderRadius::all(px(10)),
|
||||||
children![
|
children![
|
||||||
(
|
(
|
||||||
Node {
|
Node {
|
||||||
@@ -102,43 +89,35 @@ pub fn spawn_load_popup(commands: &mut Commands) {
|
|||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
(
|
text(
|
||||||
Text::new(format!(
|
format!("Spielstand {}", savegame.index + 1),
|
||||||
"Spielstand {}",
|
24.0,
|
||||||
savegame.index + 1
|
Color::WHITE
|
||||||
)),
|
|
||||||
TextFont::from_font_size(24.0),
|
|
||||||
TextColor(Color::srgb(0.9, 0.9, 0.9))
|
|
||||||
),
|
),
|
||||||
(
|
text(
|
||||||
Text::new(format!(
|
format!(
|
||||||
"Beeren: {}, Fokusphasen abgeschlossen: {}",
|
"Beeren: {}, Fokusphasen abgeschlossen: {}",
|
||||||
savegame.total_berries,
|
savegame.total_berries,
|
||||||
savegame.completed_focus
|
savegame.completed_focus
|
||||||
)),
|
),
|
||||||
TextFont::from_font_size(18.0),
|
18.0,
|
||||||
TextColor(Color::srgb(0.9, 0.9, 0.9))
|
Color::WHITE,
|
||||||
)
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
(
|
pill_button(
|
||||||
Button,
|
ButtonType::SavegameDelete {
|
||||||
ButtonType::PopupSavegameDelete {
|
|
||||||
savegame_path: savegame.path.clone()
|
savegame_path: savegame.path.clone()
|
||||||
},
|
},
|
||||||
|
ButtonVariant::Destructive,
|
||||||
Node {
|
Node {
|
||||||
width: px(40.0),
|
width: px(40),
|
||||||
height: px(40.0),
|
height: px(40),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
children![(
|
"X",
|
||||||
Text::new("X"),
|
24.0
|
||||||
TextFont::from_font_size(24.0),
|
),
|
||||||
TextColor(Color::srgb(0.9, 0.9, 0.9))
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -146,3 +125,38 @@ pub fn spawn_load_popup(commands: &mut Commands) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_popup_handler(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut next_state: ResMut<NextState<AppState>>,
|
||||||
|
mut interaction_query: Query<(&Interaction, &ButtonType), (Changed<Interaction>, With<Button>)>,
|
||||||
|
root_query: Query<(Entity, &RootMarker)>,
|
||||||
|
mut savegame_messages: MessageWriter<SavegameLoadMessage>,
|
||||||
|
) {
|
||||||
|
for (interaction, button_type) in &mut interaction_query {
|
||||||
|
match *interaction {
|
||||||
|
Interaction::Pressed => {
|
||||||
|
match button_type {
|
||||||
|
ButtonType::PopupClose => {}
|
||||||
|
ButtonType::SavegameLoad { savegame_path } => {
|
||||||
|
commands.insert_resource(savegame_path.clone());
|
||||||
|
next_state.set(AppState::GameScreen);
|
||||||
|
savegame_messages.write(SavegameLoadMessage);
|
||||||
|
}
|
||||||
|
ButtonType::SavegameDelete { savegame_path } => {
|
||||||
|
if let Err(e) = std::fs::remove_file(savegame_path.clone().0) {
|
||||||
|
println!("Error while deleting savegame: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (entity, root) in root_query.iter() {
|
||||||
|
match *root {
|
||||||
|
RootMarker::PopupSavegameLoad => commands.entity(entity).despawn(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@ use crate::prelude::*;
|
|||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub enum RootMarker {
|
pub enum RootMarker {
|
||||||
MainMenu,
|
MainMenu,
|
||||||
PopupSavegameLoad,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
@@ -11,7 +10,4 @@ pub enum ButtonType {
|
|||||||
LoadGame,
|
LoadGame,
|
||||||
NewGame,
|
NewGame,
|
||||||
Settings,
|
Settings,
|
||||||
PopupSavegameLoad { savegame_path: SavegamePath },
|
|
||||||
PopupSavegameDelete { savegame_path: SavegamePath },
|
|
||||||
PopupClose,
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
use crate::{features::savegame::messages::SavegameLoadMessage, prelude::*};
|
use crate::features::savegame::ui::spawn_load_popup;
|
||||||
|
use crate::prelude::*;
|
||||||
use components::*;
|
use components::*;
|
||||||
use ui::*;
|
|
||||||
|
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod ui;
|
|
||||||
|
|
||||||
pub struct StartScreenPlugin;
|
pub struct StartScreenPlugin;
|
||||||
|
|
||||||
@@ -21,68 +20,45 @@ fn setup(mut commands: Commands) {
|
|||||||
Node {
|
Node {
|
||||||
width: percent(100),
|
width: percent(100),
|
||||||
height: percent(100),
|
height: percent(100),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
flex_direction: FlexDirection::Column,
|
flex_direction: FlexDirection::Column,
|
||||||
..default()
|
row_gap: px(10),
|
||||||
|
..Node::center()
|
||||||
},
|
},
|
||||||
children![
|
children![
|
||||||
(
|
text("Pomomon Garden", 64.0, Color::WHITE),
|
||||||
Text::new("Pomonon Garten"),
|
button(
|
||||||
TextFont::from_font_size(64.0),
|
|
||||||
TextColor(Color::srgb(0.9, 0.9, 0.9))
|
|
||||||
),
|
|
||||||
(
|
|
||||||
Button,
|
|
||||||
ButtonType::LoadGame,
|
ButtonType::LoadGame,
|
||||||
|
ButtonVariant::Primary,
|
||||||
Node {
|
Node {
|
||||||
width: px(300),
|
width: px(280),
|
||||||
height: px(65),
|
padding: UiRect::all(px(10)),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
"Spiel laden",
|
||||||
children![(
|
33.0
|
||||||
Text::new("Spiel laden"),
|
|
||||||
TextFont::from_font_size(33.0),
|
|
||||||
TextColor(Color::srgb(0.9, 0.9, 0.9))
|
|
||||||
)]
|
|
||||||
),
|
),
|
||||||
(
|
button(
|
||||||
Button,
|
|
||||||
ButtonType::NewGame,
|
ButtonType::NewGame,
|
||||||
|
ButtonVariant::Primary,
|
||||||
Node {
|
Node {
|
||||||
width: px(300),
|
width: px(280),
|
||||||
height: px(65),
|
padding: UiRect::all(px(10)),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
"Neues Spiel",
|
||||||
children![(
|
33.0,
|
||||||
Text::new("Neues Spiel"),
|
|
||||||
TextFont::from_font_size(33.0),
|
|
||||||
TextColor(Color::srgb(0.9, 0.9, 0.9))
|
|
||||||
)]
|
|
||||||
),
|
),
|
||||||
(
|
button(
|
||||||
Button,
|
|
||||||
ButtonType::Settings,
|
ButtonType::Settings,
|
||||||
|
ButtonVariant::Secondary,
|
||||||
Node {
|
Node {
|
||||||
width: px(300),
|
width: px(280),
|
||||||
height: px(65),
|
padding: UiRect::all(px(10)),
|
||||||
justify_content: JustifyContent::Center,
|
|
||||||
align_items: AlignItems::Center,
|
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
BackgroundColor(NORMAL_BUTTON),
|
"Einstellungen",
|
||||||
children![(
|
33.0
|
||||||
Text::new("Einstellungen"),
|
),
|
||||||
TextFont::from_font_size(33.0),
|
|
||||||
TextColor(Color::srgb(0.9, 0.9, 0.9))
|
|
||||||
)]
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -90,18 +66,11 @@ fn setup(mut commands: Commands) {
|
|||||||
fn menu(
|
fn menu(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut next_state: ResMut<NextState<AppState>>,
|
mut next_state: ResMut<NextState<AppState>>,
|
||||||
mut interaction_query: Query<
|
mut interaction_query: Query<(&Interaction, &ButtonType), (Changed<Interaction>, With<Button>)>,
|
||||||
(&Interaction, &ButtonType, &mut BackgroundColor),
|
|
||||||
(Changed<Interaction>, With<Button>),
|
|
||||||
>,
|
|
||||||
root_query: Query<(Entity, &RootMarker)>,
|
|
||||||
mut savegame_messages: MessageWriter<SavegameLoadMessage>,
|
|
||||||
) {
|
) {
|
||||||
for (interaction, button_type, mut color) in &mut interaction_query {
|
for (interaction, button_type) in &mut interaction_query {
|
||||||
match *interaction {
|
match *interaction {
|
||||||
Interaction::Pressed => {
|
Interaction::Pressed => {
|
||||||
*color = PRESSED_BUTTON.into();
|
|
||||||
|
|
||||||
match button_type {
|
match button_type {
|
||||||
ButtonType::LoadGame => {
|
ButtonType::LoadGame => {
|
||||||
spawn_load_popup(&mut commands);
|
spawn_load_popup(&mut commands);
|
||||||
@@ -110,40 +79,10 @@ fn menu(
|
|||||||
commands.insert_resource(SavegamePath::next());
|
commands.insert_resource(SavegamePath::next());
|
||||||
next_state.set(AppState::GameScreen);
|
next_state.set(AppState::GameScreen);
|
||||||
}
|
}
|
||||||
ButtonType::PopupClose => {
|
ButtonType::Settings => todo!(),
|
||||||
for (entity, root) in root_query.iter() {
|
|
||||||
match *root {
|
|
||||||
RootMarker::PopupSavegameLoad => commands.entity(entity).despawn(),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ButtonType::PopupSavegameLoad { savegame_path } => {
|
|
||||||
commands.insert_resource(savegame_path.clone());
|
|
||||||
next_state.set(AppState::GameScreen);
|
|
||||||
savegame_messages.write(SavegameLoadMessage);
|
|
||||||
}
|
|
||||||
ButtonType::PopupSavegameDelete { savegame_path } => {
|
|
||||||
if let Err(e) = std::fs::remove_file(savegame_path.clone().0) {
|
|
||||||
println!("Error while deleting savegame: {:?}", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (entity, root) in root_query.iter() {
|
|
||||||
match *root {
|
|
||||||
RootMarker::PopupSavegameLoad => commands.entity(entity).despawn(),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Interaction::Hovered => {
|
_ => (),
|
||||||
*color = HOVERED_BUTTON.into();
|
|
||||||
}
|
|
||||||
Interaction::None => {
|
|
||||||
*color = NORMAL_BUTTON.into();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,3 +6,43 @@ pub struct Scroll {
|
|||||||
pub entity: Entity,
|
pub entity: Entity,
|
||||||
pub delta: Vec2,
|
pub delta: Vec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Clone)]
|
||||||
|
pub enum ButtonVariant {
|
||||||
|
Primary,
|
||||||
|
Secondary,
|
||||||
|
Destructive,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ButtonVariant {
|
||||||
|
pub fn normal_background(&self) -> Color {
|
||||||
|
match self {
|
||||||
|
ButtonVariant::Primary => Color::srgb(0.35, 0.17, 0.78),
|
||||||
|
ButtonVariant::Secondary => Color::srgb(0.15, 0.15, 0.15),
|
||||||
|
ButtonVariant::Destructive => Color::srgb(0.79, 0.17, 0.20),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hover_background(&self) -> Color {
|
||||||
|
match self {
|
||||||
|
ButtonVariant::Primary => Color::srgb(0.45, 0.27, 0.88),
|
||||||
|
ButtonVariant::Secondary => Color::srgb(0.25, 0.25, 0.25),
|
||||||
|
ButtonVariant::Destructive => Color::srgb(0.89, 0.27, 0.30),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pressed_background(&self) -> Color {
|
||||||
|
match self {
|
||||||
|
ButtonVariant::Primary => Color::srgb(0.55, 0.37, 0.98),
|
||||||
|
ButtonVariant::Secondary => Color::srgb(0.35, 0.35, 0.35),
|
||||||
|
ButtonVariant::Destructive => Color::srgb(0.99, 0.37, 0.40),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn text_color(&self) -> Color {
|
||||||
|
match self {
|
||||||
|
ButtonVariant::Primary | ButtonVariant::Destructive => Color::srgb(0.1, 0.1, 0.1),
|
||||||
|
ButtonVariant::Secondary => Color::WHITE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::{button::update_buttons, *};
|
||||||
use bevy::{input::mouse::*, picking::hover::HoverMap};
|
use bevy::{input::mouse::*, picking::hover::HoverMap};
|
||||||
|
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod consts;
|
pub mod consts;
|
||||||
|
pub mod ui;
|
||||||
|
|
||||||
pub struct UiPlugin;
|
pub struct UiPlugin;
|
||||||
|
|
||||||
@@ -10,6 +11,8 @@ impl Plugin for UiPlugin {
|
|||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_systems(Update, scroll_events);
|
app.add_systems(Update, scroll_events);
|
||||||
app.add_observer(on_scroll_handler);
|
app.add_observer(on_scroll_handler);
|
||||||
|
|
||||||
|
app.add_systems(Update, update_buttons);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
59
src/features/ui/ui/button.rs
Normal file
59
src/features/ui/ui/button.rs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
pub fn button(
|
||||||
|
button_type: impl Component,
|
||||||
|
variant: ButtonVariant,
|
||||||
|
mut node: Node,
|
||||||
|
title: impl Into<String>,
|
||||||
|
font_size: f32,
|
||||||
|
) -> impl Bundle {
|
||||||
|
node.justify_content = JustifyContent::Center;
|
||||||
|
node.align_items = AlignItems::Center;
|
||||||
|
|
||||||
|
(
|
||||||
|
Button,
|
||||||
|
button_type,
|
||||||
|
variant.clone(),
|
||||||
|
node,
|
||||||
|
BackgroundColor(variant.normal_background()),
|
||||||
|
BorderRadius::all(px(10)),
|
||||||
|
children![text(title, font_size, variant.text_color())],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pill_button(
|
||||||
|
button_type: impl Component,
|
||||||
|
variant: ButtonVariant,
|
||||||
|
mut node: Node,
|
||||||
|
title: impl Into<String>,
|
||||||
|
font_size: f32,
|
||||||
|
) -> impl Bundle {
|
||||||
|
node.justify_content = JustifyContent::Center;
|
||||||
|
node.align_items = AlignItems::Center;
|
||||||
|
|
||||||
|
(
|
||||||
|
Button,
|
||||||
|
button_type,
|
||||||
|
variant.clone(),
|
||||||
|
node,
|
||||||
|
BackgroundColor(variant.normal_background()),
|
||||||
|
BorderRadius::MAX,
|
||||||
|
children![text(title, font_size, variant.text_color())],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_buttons(
|
||||||
|
mut interaction_query: Query<
|
||||||
|
(&Interaction, &ButtonVariant, &mut BackgroundColor),
|
||||||
|
(Changed<Interaction>, With<Button>),
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
for (interaction, variant, mut color) in &mut interaction_query {
|
||||||
|
*color = match *interaction {
|
||||||
|
Interaction::None => variant.normal_background(),
|
||||||
|
Interaction::Hovered => variant.hover_background(),
|
||||||
|
Interaction::Pressed => variant.pressed_background(),
|
||||||
|
}
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/features/ui/ui/flexbox.rs
Normal file
33
src/features/ui/ui/flexbox.rs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
pub trait Flexbox {
|
||||||
|
fn hstack(spacing: Val) -> Self;
|
||||||
|
fn vstack(spacing: Val) -> Self;
|
||||||
|
fn center() -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Flexbox for Node {
|
||||||
|
fn hstack(spacing: Val) -> Self {
|
||||||
|
Self {
|
||||||
|
flex_direction: FlexDirection::Row,
|
||||||
|
column_gap: spacing,
|
||||||
|
..default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vstack(spacing: Val) -> Self {
|
||||||
|
Self {
|
||||||
|
flex_direction: FlexDirection::Column,
|
||||||
|
row_gap: spacing,
|
||||||
|
..default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn center() -> Self {
|
||||||
|
Self {
|
||||||
|
justify_content: JustifyContent::Center,
|
||||||
|
align_items: AlignItems::Center,
|
||||||
|
..default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/features/ui/ui/mod.rs
Normal file
7
src/features/ui/ui/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
pub mod button;
|
||||||
|
pub mod flexbox;
|
||||||
|
pub mod texts;
|
||||||
|
|
||||||
|
pub use button::{button, pill_button};
|
||||||
|
pub use flexbox::Flexbox;
|
||||||
|
pub use texts::{text, text_with_component};
|
||||||
19
src/features/ui/ui/texts.rs
Normal file
19
src/features/ui/ui/texts.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
pub use crate::prelude::*;
|
||||||
|
|
||||||
|
pub fn text(content: impl Into<String>, size: f32, color: Color) -> (Text, TextFont, TextColor) {
|
||||||
|
(
|
||||||
|
Text::new(content),
|
||||||
|
TextFont::from_font_size(size),
|
||||||
|
TextColor(color),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn text_with_component(
|
||||||
|
component: impl Component,
|
||||||
|
content: impl Into<String>,
|
||||||
|
size: f32,
|
||||||
|
color: Color,
|
||||||
|
) -> impl Bundle {
|
||||||
|
let (a, b, c) = text(content, size, color);
|
||||||
|
(component, a, b, c)
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ pub use crate::features::{
|
|||||||
messages::{InteractStartMessage, MoveMessage},
|
messages::{InteractStartMessage, MoveMessage},
|
||||||
},
|
},
|
||||||
savegame::components::SavegamePath,
|
savegame::components::SavegamePath,
|
||||||
ui::consts::*,
|
ui::{components::ButtonVariant, consts::*, ui::*},
|
||||||
};
|
};
|
||||||
pub use crate::utils::path::get_internal_path;
|
pub use crate::utils::path::get_internal_path;
|
||||||
pub use bevy::prelude::*;
|
pub use bevy::prelude::*;
|
||||||
|
|||||||
Reference in New Issue
Block a user