Skip to content

Commit

Permalink
Make level up menu fully functional
Browse files Browse the repository at this point in the history
  • Loading branch information
benfrankel committed Jul 27, 2024
1 parent bf49ffe commit c18bd96
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/screen/playing/hud.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ fn arrow(entity: Entity, world: &mut World) {
let config = SystemState::<ConfigRef<CardConfig>>::new(world).get(world);
let config = r!(config.get());
let height = config.card_height / 18.0 * 5.0;
let margin = config.card_height / 18.0 * 2.0;
let margin = config.card_height / 18.0;
let texture = world.resource::<PlayingAssets>().arrow.clone();

world.entity_mut(entity).insert((
Expand Down
100 changes: 85 additions & 15 deletions src/screen/playing/level_up_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ use crate::screen::playing::PlayingMenu;
use crate::ui::prelude::*;
use crate::util::prelude::*;

// TODO: Random card selection to add to deck.
// TODO: Helpful message if the player is at deck capacity.
// TODO: Helpful message if the player is at deck capacity?
pub(super) fn plugin(app: &mut App) {
app.add_systems(
StateFlush,
Expand All @@ -34,7 +33,7 @@ pub(super) fn plugin(app: &mut App) {
.run_if(on_event::<LevelUp>()),
);

app.configure::<LevelUpMenuAction>();
app.configure::<(LevelUpMenuAction, ToggleDisplay)>();
}

fn open_level_up_menu(mut commands: Commands, ui_root: Res<UiRoot>) {
Expand Down Expand Up @@ -64,7 +63,7 @@ fn level_up_menu(mut entity: EntityWorldMut) {
NodeBundle {
style: Style {
height: VMin(60.0),
top: Vw(-1.5),
top: Vw(-2.5),
align_items: AlignItems::Center,
justify_content: JustifyContent::SpaceBetween,
flex_direction: FlexDirection::Column,
Expand All @@ -77,6 +76,7 @@ fn level_up_menu(mut entity: EntityWorldMut) {
))
.with_children(|children| {
children.spawn_with(header);
children.spawn_with(instructions_container);
children.spawn_with(card_options_container);
children.spawn_with(button_container);
});
Expand All @@ -100,6 +100,42 @@ fn header(mut entity: EntityWorldMut) {
));
}

fn instructions_container(mut entity: EntityWorldMut) {
entity
.insert((
Name::new("InstructionsContainer"),
NodeBundle {
style: Style {
display: Display::None,
flex_direction: FlexDirection::Column,
row_gap: Vh(2.3),
..default()
},
..default()
},
ToggleDisplay,
))
.with_children(|children| {
for (i, text) in [
"You can sort your cards during a level up:",
"",
"- [b]Select: [r] A/D or Arrow Keys",
"- [b]Move: [r] Shift + A/D",
"- [b]Discard:[r] Delete",
]
.into_iter()
.enumerate()
{
children.spawn((
Name::new(format!("InstructionsParagraph{}", i)),
TextBundle::from_sections(parse_rich(text)),
DynamicFontSize::new(Vw(3.0)).with_step(8.0),
ThemeColorForText(vec![ThemeColor::BodyText]),
));
}
});
}

fn card_options_container(entity: Entity, world: &mut World) {
let config = SystemState::<ConfigRef<CardConfig>>::new(world).get(world);
let config = r!(config.get());
Expand All @@ -126,6 +162,7 @@ fn card_options_container(entity: Entity, world: &mut World) {
},
..default()
},
ToggleDisplay,
))
.with_children(|children| {
for key in card_keys {
Expand Down Expand Up @@ -161,12 +198,24 @@ fn card_button(key: impl Into<String>) -> impl EntityCommand<World> {
let key = key.into();

move |mut entity: EntityWorldMut| {
entity.add(card(key, None)).insert((
entity.add(card(key.clone(), None)).insert((
Interaction::default(),
On::<Pointer<Click>>::run(|| {
// TODO: Add card to deck, then run the same logic as the skip button.
println!("Click!");
}),
On::<Pointer<Click>>::run(
move |deck_display_query: Query<&Selection, With<IsDeckDisplay>>,
mut deck_query: Query<&mut Deck>,
mut toggle_query: Query<&mut Style, With<ToggleDisplay>>| {
for selection in &deck_display_query {
let mut deck = c!(deck_query.get_mut(selection.0));
deck.add(key.clone());
}
for mut style in &mut toggle_query {
style.display = match style.display {
Display::None => Display::Flex,
_ => Display::None,
};
}
},
),
));
}
}
Expand Down Expand Up @@ -211,27 +260,35 @@ fn button_container(mut entity: EntityWorldMut) {
.insert((Name::new("ButtonContainer"), NodeBundle::default()))
.with_children(|children| {
children.spawn_with(skip_button);
children.spawn_with(ready_button);
children.spawn_with(dance_button);
});
}

fn skip_button(mut entity: EntityWorldMut) {
entity.add(widget::menu_button("Skip")).insert((
// TODO: Hide this button + the card options container,
// and show the ready button + the instructions container.
On::<Pointer<Click>>::run(PlayingMenu::disable),
On::<Pointer<Click>>::run(
move |mut toggle_query: Query<&mut Style, With<ToggleDisplay>>| {
for mut style in &mut toggle_query {
style.display = match style.display {
Display::None => Display::Flex,
_ => Display::None,
};
}
},
),
Style {
height: Vw(8.0),
width: Vw(28.0),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
..default()
},
ToggleDisplay,
));
}

fn ready_button(mut entity: EntityWorldMut) {
entity.add(widget::menu_button("Ready?")).insert((
fn dance_button(mut entity: EntityWorldMut) {
entity.add(widget::menu_button("Dance~")).insert((
On::<Pointer<Click>>::run(PlayingMenu::disable),
Style {
display: Display::None,
Expand All @@ -241,6 +298,7 @@ fn ready_button(mut entity: EntityWorldMut) {
justify_content: JustifyContent::Center,
..default()
},
ToggleDisplay,
));
}

Expand Down Expand Up @@ -352,3 +410,15 @@ fn card_discard(
deck.discard();
}
}

/// A marker component for entities that should toggle between
/// `Display::None` and `Display::Flexbox` to swap sub-menus.
#[derive(Component, Reflect)]
#[reflect(Component)]
struct ToggleDisplay;

impl Configure for ToggleDisplay {
fn configure(app: &mut App) {
app.register_type::<Self>();
}
}
2 changes: 1 addition & 1 deletion src/screen/playing/pause_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ fn button_container(mut entity: EntityWorldMut) {
style: Style {
align_items: AlignItems::Center,
flex_direction: FlexDirection::Column,
margin: UiRect::vertical(VMin(7.0)),
margin: UiRect::top(VMin(6.0)),
row_gap: Vw(2.5),
..default()
},
Expand Down
14 changes: 9 additions & 5 deletions src/ui/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ fn apply_dynamic_font_size(
}

/// Parses a "rich text" string with tags `"[r]"`, `"[b]"`, and `"[t]"`.
pub fn parse_rich(text: &str) -> Text {
pub fn parse_rich(text: &str) -> Vec<TextSection> {
let styles = HashMap::from([
(
"r",
Expand Down Expand Up @@ -136,7 +136,11 @@ pub fn parse_rich(text: &str) -> Text {
/// - `"[tag]"` will set the text style to `styles["tag"]` for the following text.
/// - If `styles["tag"]` is not found, `"[tag]"` will be interpreted as literal text.
/// - Tags cannot be escaped. To allow literal `"[tag]"`, don't use `"tag"` as a key.
pub fn parse_rich_custom(text: &str, styles: &HashMap<&str, TextStyle>, start_tag: &str) -> Text {
pub fn parse_rich_custom(
text: &str,
styles: &HashMap<&str, TextStyle>,
start_tag: &str,
) -> Vec<TextSection> {
let mut sections = vec![];

let mut lo = 0;
Expand Down Expand Up @@ -176,7 +180,7 @@ pub fn parse_rich_custom(text: &str, styles: &HashMap<&str, TextStyle>, start_ta
sections.push(section);
}

Text::from_sections(sections)
sections
}

#[cfg(test)]
Expand Down Expand Up @@ -278,8 +282,8 @@ mod tests {
),
] {
let got = parse_rich_custom(case, &styles, "regular");
assert_eq!(got.sections.len(), want.len());
for (got, want) in got.sections.iter().zip(&want) {
assert_eq!(got.len(), want.len());
for (got, want) in got.iter().zip(&want) {
assert_eq!(got.value, want.value);
assert_eq!(got.style.font, want.style.font);
assert_eq!(got.style.font_size, want.style.font_size);
Expand Down

0 comments on commit c18bd96

Please sign in to comment.