DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

977e440bf1876853ee128c287bd2f5c02cce82f4 — Jonni Liljamo 1 year, 4 months ago d11c5cc
wip(client): log ui
M client/src/plugins/game/mod.rs => client/src/plugins/game/mod.rs +3 -1
@@ 11,7 11,7 @@ use bevy_rapier3d::prelude::*;

use crate::{api::game::{Game, GameState}, game_status::GameStatus, AppState, Global};

use self::{hand::SpawnHandEvent, supply::SpawnSupplyPilesEvent};
use self::{hand::SpawnHandEvent, supply::SpawnSupplyPilesEvent, ui::log::UpdateLogEvent};

use super::GameDetailsCallEvent;



@@ 93,7 93,9 @@ pub struct FinishedRefreshGameEvent;
fn handle_finished_refresh_game_event(
    mut ssp_ev_w: EventWriter<SpawnSupplyPilesEvent>,
    mut sh_ev_w: EventWriter<SpawnHandEvent>,
    mut ul_ev_w: EventWriter<UpdateLogEvent>,
) {
    ssp_ev_w.send(SpawnSupplyPilesEvent);
    sh_ev_w.send(SpawnHandEvent);
    ul_ev_w.send(UpdateLogEvent);
}

M client/src/plugins/game/ui/log.rs => client/src/plugins/game/ui/log.rs +97 -41
@@ 8,7 8,7 @@

use bevy::{prelude::*, input::mouse::{MouseScrollUnit, MouseWheel}, a11y::{AccessibilityNode, accesskit::NodeBuilder}};

use crate::AppState;
use crate::{AppState, plugins::GameData, util::action_to_log};

pub struct LogPlugin;



@@ 24,7 24,7 @@ impl Plugin for LogPlugin {
    }
}

pub struct ToggleLogEvent;
struct ToggleLogEvent;
pub struct UpdateLogEvent;

const NORMAL_BUTTON: Color = Color::rgb(0.15, 0.15, 0.15);


@@ 34,12 34,13 @@ const PRESSED_BUTTON: Color = Color::rgb(0.35, 0.75, 0.35);
#[derive(Component)]
struct LogButton;
#[derive(Component)]
struct LogListParent;
#[derive(Component)]
struct LogList;
#[derive(Component)]
struct LogListEntry;

fn setup_log(mut commands: Commands, asset_server: Res<AssetServer>) {
    // setup a button for log toggle
    // setup the log ui itself, with hidden visibility

    let font = asset_server.load("fonts/FiraMono-Bold.ttf");

    // log toggle button


@@ 88,26 89,30 @@ fn setup_log(mut commands: Commands, asset_server: Res<AssetServer>) {

    // log window
    commands
        .spawn(NodeBundle {
            style: Style {
                flex_direction: FlexDirection::Column,
                justify_content: JustifyContent::Center,
                align_items: AlignItems::Center,
                size: Size {
                    width: Val::Px(300.),
                    height: Val::Px(300.),
                },
                position_type: PositionType::Absolute,
                position: UiRect {
                    bottom: Val::Percent(12.5),
                    right: Val::Px(100.),
        .spawn((
            NodeBundle {
                style: Style {
                    flex_direction: FlexDirection::Column,
                    justify_content: JustifyContent::Center,
                    align_items: AlignItems::Center,
                    size: Size {
                        width: Val::Px(300.),
                        height: Val::Percent(75.),
                    },
                    position_type: PositionType::Absolute,
                    position: UiRect {
                        bottom: Val::Percent(12.5),
                        right: Val::Px(100.),
                        ..Default::default()
                    },
                    ..Default::default()
                },
                background_color: Color::rgb(0.15, 0.15, 0.15).into(),
                visibility: Visibility::Hidden,
                ..Default::default()
            },
            background_color: Color::rgb(0.15, 0.15, 0.15).into(),
            ..Default::default()
        })
            LogListParent,
        ))
        .with_children(|parent| {
            parent
                .spawn(NodeBundle {


@@ 136,19 141,18 @@ fn setup_log(mut commands: Commands, asset_server: Res<AssetServer>) {
                            LogList,
                        ))
                        .with_children(|parent| {
                            for i in 0..30 {
                                parent.spawn((
                                    TextBundle::from_section(
                                        format!("Item {i}"),
                                        TextStyle {
                                            font: font.clone(),
                                            font_size: 20.,
                                            color: Color::WHITE,
                                        },
                                    ),
                                    AccessibilityNode(NodeBuilder::new(bevy::a11y::accesskit::Role::ListItem)),
                                ));
                            }
                            parent.spawn((
                                TextBundle::from_section(
                                    format!("Empty"),
                                    TextStyle {
                                        font: font.clone(),
                                        font_size: 20.,
                                        color: Color::WHITE,
                                    },
                                ),
                                AccessibilityNode(NodeBuilder::new(bevy::a11y::accesskit::Role::ListItem)),
                                LogListEntry,
                            ));
                        });
                });
        });


@@ 159,13 163,13 @@ fn update_log_button(
        (&Interaction, &mut BackgroundColor),
        (Changed<Interaction>, With<LogButton>),
    >,
    mut ul_ev_w: EventWriter<UpdateLogEvent>,
    mut tl_ev_w: EventWriter<ToggleLogEvent>,
) {
    for (interaction, mut color) in &mut interaction_query {
        match interaction {
            Interaction::Clicked => {
                *color = PRESSED_BUTTON.into();
                ul_ev_w.send(UpdateLogEvent);
                tl_ev_w.send(ToggleLogEvent);
            }
            Interaction::Hovered => {
                *color = HOVERED_BUTTON.into();


@@ 177,13 181,65 @@ fn update_log_button(
    }
}

fn toggle_log() {
    // toggle the node visibility, see the state button for e.g
fn toggle_log(
    mut log_parent_query: Query<&mut Visibility, With<LogListParent>>,
) {
    for mut visibility in &mut log_parent_query {
        if *visibility == Visibility::Hidden {
            *visibility = Visibility::Inherited;
        } else {
            *visibility = Visibility::Hidden;
        }
    }
}

fn update_log() {
    // despawn the children ui nodes, and create new ones.
    // update log ui scrolling items with... log items
fn update_log(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    log_query: Query<Entity, With<LogList>>,
    log_entries_query: Query<Entity, With<LogListEntry>>,
    game_data: Res<GameData>,
) {
    for entity in &log_entries_query {
        commands.entity(entity).despawn_recursive();
    }
    for entity in &log_query {
        let Some(status) = game_data.clone().game_status else {
            return;
        };

        let font = asset_server.load("fonts/FiraMono-Regular.ttf");
        let font_bold = asset_server.load("fonts/FiraMono-Bold.ttf");

        let style = TextStyle {
            font: font.clone(),
            font_size: 20.,
            color: Color::WHITE,
        };

        let index_spaces = status.actions.len().to_string().len();

        for (i, action) in status.actions.iter().enumerate() {
            let spaces = "".repeat(index_spaces - i.to_string().len());

            commands.spawn((
                TextBundle::from_sections([[
                    TextSection {
                        value: format!("{}{}. ", spaces, i),
                        style: TextStyle {
                            font: font_bold.clone(),
                            ..style
                        },
                    },
                ],
                    action_to_log(action, font, style).into_iter()
                ].concat()),
                AccessibilityNode(NodeBuilder::new(bevy::a11y::accesskit::Role::ListItem)),
                LogListEntry,
            ))
                .set_parent(entity);
        }
    }
}

#[derive(Component, Default)]

M client/src/plugins/game/ui/mod.rs => client/src/plugins/game/ui/mod.rs +1 -1
@@ 18,7 18,7 @@ use crate::{

use super::{GameData, RefreshGameEvent};

mod log;
pub mod log;
mod state_button;

pub struct GameUIPlugin;

A client/src/util/action_to_log.rs => client/src/util/action_to_log.rs +30 -0
@@ 0,0 1,30 @@
/*
 * This file is part of laurelin_client
 * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
 *
 * Licensed under GPL-3.0-only.
 * See LICENSE for licensing information.
 */

use bevy::prelude::*;

use crate::api::game::Action;

pub fn action_to_log(
    action: &Action,
    font: Handle<Font>,
    style: TextStyle,
) -> Vec<TextSection> {
    match &action.command {
        _ => {
            vec![
                TextSection {
                    value: format!("No log configuration for this command"),
                    style: TextStyle {
                        ..style
                    },
                },
            ]
        }
    }
}

M client/src/util/mod.rs => client/src/util/mod.rs +3 -0
@@ 7,3 7,6 @@
 */

pub mod egui;

mod action_to_log;
pub use action_to_log::action_to_log;