DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

4bab96d766de25e1ce3c66416b2d9ca48c90ede6 — Jonni Liljamo 1 year, 8 months ago 59714f5
feat(sdbclient): new account UIs
M sdbclient/src/plugins/menu/accountscreenloggedin.rs => sdbclient/src/plugins/menu/accountscreenloggedin.rs +52 -116
@@ 1,133 1,69 @@
/*
 * This file is part of sdbclient
 * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
 * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
 *
 * Licensed under GPL-3.0-only.
 * See LICENSE for licensing information.
 */

use bevy::{
    prelude::*,
    ui::{JustifyContent, Size, Style, Val},
use bevy::prelude::*;
use iyes_loopless::prelude::*;

use belly::prelude::*;

use crate::{
    cfg::CfgUser,
    plugins::config::{SaveEvent, SaveEventValue},
};

use crate::{cfg::CfgUser, constants::TEXT_COLOR};
use super::MenuState;

use super::{MenuButtonAction, NORMAL_BUTTON};
pub(super) struct LogoutEvent;

/// Tag component for tagging entities on settings menu screen
#[derive(Component)]
pub struct OnAccountLoggedInScreen;
pub(super) fn account_loggedin_setup(mut commands: Commands, cfg_user: Res<CfgUser>) {
    let username = cfg_user.username.clone();

    commands.add(eml! {
        <body>
            <div c:menu>
                <span c:menutitle>
                    "Account"
                </span>
                <span>
                    "Logged in as:"
                </span>
                <span>
                    { username }
                </span>
                <button c:menubutton on:press=connect!(|ctx| {
                    ctx.send_event(LogoutEvent)
                })>
                    "Logout"
                </button>
                <button c:menubutton on:press=connect!(|ctx| {
                    ctx.commands().insert_resource(NextState(MenuState::Main))
                })>
                    "Back"
                </button>
            </div>
        </body>
    });
}

pub fn account_loggedin_setup(
pub(super) fn handle_logout_event(
    mut events: EventReader<LogoutEvent>,
    mut commands: Commands,
    asset_server: Res<AssetServer>,
    cfg_user: ResMut<CfgUser>,
    mut cfg_user: ResMut<CfgUser>,
    mut save_event_writer: EventWriter<SaveEvent>,
) {
    let font = asset_server.load("fonts/FiraMono-Regular.ttf");
    let font_bold = asset_server.load("fonts/FiraMono-Bold.ttf");
    for _event in events.iter() {
        // Reset CfgUser to default
        *cfg_user = CfgUser::default();

    let button_style = Style {
        size: Size::new(Val::Px(200.0), Val::Px(65.0)),
        margin: UiRect::all(Val::Px(20.0)),
        justify_content: JustifyContent::Center,
        align_items: AlignItems::Center,
        ..default()
    };

    let button_text_style = TextStyle {
        font: font.clone(),
        font_size: 40.0,
        color: TEXT_COLOR,
    };

    commands
        .spawn((
            NodeBundle {
                style: Style {
                    size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
                    align_items: AlignItems::Center,
                    justify_content: JustifyContent::Center,
                    flex_direction: FlexDirection::Column,
                    ..default()
                },
                ..default()
            },
            OnAccountLoggedInScreen,
        ))
        .with_children(|parent| {
            parent.spawn(
                TextBundle::from_section(
                    "Account",
                    TextStyle {
                        font: font.clone(),
                        font_size: 60.0,
                        color: TEXT_COLOR,
                    },
                )
                .with_style(Style {
                    margin: UiRect::all(Val::Px(50.)),
                    ..Default::default()
                }),
            );
            parent.spawn(
                TextBundle::from_section(
                    "Logged in as: ",
                    TextStyle {
                        font: font.clone(),
                        font_size: 25.0,
                        color: TEXT_COLOR,
                    },
                )
                .with_style(Style {
                    ..Default::default()
                }),
            );
            parent.spawn(
                TextBundle::from_section(
                    cfg_user.username.clone(),
                    TextStyle {
                        font: font_bold.clone(),
                        font_size: 40.0,
                        color: TEXT_COLOR,
                    },
                )
                .with_style(Style {
                    margin: UiRect::bottom(Val::Px(25.)),
                    ..Default::default()
                }),
            );
            parent
                .spawn(NodeBundle {
                    style: Style {
                        flex_direction: FlexDirection::Column,
                        align_items: AlignItems::Center,
                        ..default()
                    },
                    background_color: Color::GRAY.into(),
                    ..default()
                })
                .with_children(|parent| {
                    for (action, text) in [
                        (MenuButtonAction::AccountLogout, "Logout"),
                        (MenuButtonAction::BackToMainMenu, "Back"),
                    ] {
                        parent
                            .spawn((
                                ButtonBundle {
                                    style: button_style.clone(),
                                    background_color: NORMAL_BUTTON.into(),
                                    ..default()
                                },
                                action,
                            ))
                            .with_children(|parent| {
                                parent.spawn(TextBundle::from_section(
                                    text,
                                    button_text_style.clone(),
                                ));
                            });
                    }
                });
        save_event_writer.send(SaveEvent {
            value: SaveEventValue::User(cfg_user.clone()),
        });

        commands.insert_resource(NextState(MenuState::AccountLoggedOut));
    }
}

M sdbclient/src/plugins/menu/accountscreenloggedout.rs => sdbclient/src/plugins/menu/accountscreenloggedout.rs +35 -94
@@ 1,102 1,43 @@
/*
 * This file is part of sdbclient
 * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
 * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
 *
 * Licensed under GPL-3.0-only.
 * See LICENSE for licensing information.
 */

use bevy::{
    prelude::*,
    ui::{JustifyContent, Size, Style, Val},
};

use crate::constants::TEXT_COLOR;

use super::{MenuButtonAction, NORMAL_BUTTON};

/// Tag component for tagging entities on settings menu screen
#[derive(Component)]
pub struct OnAccountLoggedOutScreen;

pub fn account_loggedout_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    let font = asset_server.load("fonts/FiraMono-Regular.ttf");

    let button_style = Style {
        size: Size::new(Val::Px(200.0), Val::Px(65.0)),
        margin: UiRect::all(Val::Px(20.0)),
        justify_content: JustifyContent::Center,
        align_items: AlignItems::Center,
        ..default()
    };

    let button_text_style = TextStyle {
        font: font.clone(),
        font_size: 40.0,
        color: TEXT_COLOR,
    };

    commands
        .spawn((
            NodeBundle {
                style: Style {
                    size: Size::new(Val::Percent(100.0), Val::Percent(100.0)),
                    align_items: AlignItems::Center,
                    justify_content: JustifyContent::Center,
                    flex_direction: FlexDirection::Column,
                    ..default()
                },
                ..default()
            },
            OnAccountLoggedOutScreen,
        ))
        .with_children(|parent| {
            parent.spawn(
                TextBundle::from_section(
                    "Account",
                    TextStyle {
                        font: font.clone(),
                        font_size: 60.0,
                        color: TEXT_COLOR,
                    },
                )
                .with_style(Style {
                    margin: UiRect::all(Val::Px(50.)),
                    ..Default::default()
                }),
            );
            parent
                .spawn(NodeBundle {
                    style: Style {
                        flex_direction: FlexDirection::Column,
                        align_items: AlignItems::Center,
                        ..default()
                    },
                    background_color: Color::GRAY.into(),
                    ..default()
                })
                .with_children(|parent| {
                    for (action, text) in [
                        (MenuButtonAction::AccountLogin, "Login"),
                        (MenuButtonAction::AccountRegister, "Register"),
                        (MenuButtonAction::BackToMainMenu, "Back"),
                    ] {
                        parent
                            .spawn((
                                ButtonBundle {
                                    style: button_style.clone(),
                                    background_color: NORMAL_BUTTON.into(),
                                    ..default()
                                },
                                action,
                            ))
                            .with_children(|parent| {
                                parent.spawn(TextBundle::from_section(
                                    text,
                                    button_text_style.clone(),
                                ));
                            });
                    }
                });
        });
use bevy::prelude::*;
use iyes_loopless::prelude::*;

use belly::prelude::*;

use super::{accountlogin::LoginState, accountregister::RegisterState, MenuState};

pub(super) fn account_loggedout_setup(mut commands: Commands) {
    commands.add(eml! {
        <body>
            <div c:menu>
                <span c:menutitle>
                    "Account"
                </span>
                <button c:menubutton on:press=connect!(|ctx| {
                    ctx.commands().insert_resource(NextState(MenuState::AccountLogin));
                    ctx.commands().insert_resource(NextState(LoginState::Input));
                })>
                    "Login"
                </button>
                <button c:menubutton on:press=connect!(|ctx| {
                    ctx.commands().insert_resource(NextState(MenuState::AccountRegister));
                    ctx.commands().insert_resource(NextState(RegisterState::Input));
                })>
                    "Register"
                </button>
                <button c:menubutton on:press=connect!(|ctx| {
                    ctx.commands().insert_resource(NextState(MenuState::Main))
                })>
                    "Back"
                </button>
            </div>
        </body>
    });
}

M sdbclient/src/plugins/menu/mod.rs => sdbclient/src/plugins/menu/mod.rs +10 -96
@@ 9,9 9,7 @@
use bevy::prelude::*;
use iyes_loopless::prelude::*;

use crate::cfg::CfgUser;

use crate::{despawn_screen, remove_ui, GameState};
use crate::{remove_ui, GameState};

mod mainmenuscreen;
use mainmenuscreen::*;


@@ 28,8 26,6 @@ use accountscreenloggedin::*;
mod playscreen;
use playscreen::*;

use super::config::{SaveEvent, SaveEventValue};

mod accountlogin;
mod accountregister;



@@ 58,21 54,20 @@ impl Plugin for MenuPlugin {
            .add_exit_system(MenuState::Settings, remove_ui)
            // Systems for account loggedout screen
            .add_enter_system(MenuState::AccountLoggedOut, account_loggedout_setup)
            .add_exit_system(MenuState::AccountLoggedOut, despawn_screen::<OnAccountLoggedOutScreen>)
            .add_exit_system(MenuState::AccountLoggedOut, remove_ui)
            // Systems for account loggedin screen
            .add_enter_system(MenuState::AccountLoggedIn, account_loggedin_setup)
            .add_exit_system(MenuState::AccountLoggedIn, despawn_screen::<OnAccountLoggedInScreen>)
            // Systems for play screen
            .add_enter_system(MenuState::Play, play_setup)
            .add_exit_system(MenuState::Play, remove_ui)
            // Common systems
            .add_exit_system(MenuState::AccountLoggedIn, remove_ui)
            .add_event::<LogoutEvent>()
            .add_system_set(
                ConditionSet::new()
                    .run_in_state(GameState::MainMenu)
                    .with_system(menu_action)
                    .with_system(button_system)
                    .run_in_state(MenuState::AccountLoggedIn)
                    .with_system(handle_logout_event.run_on_event::<LogoutEvent>())
                    .into()
            );
            )
            // Systems for play screen
            .add_enter_system(MenuState::Play, play_setup)
            .add_exit_system(MenuState::Play, remove_ui);

        app.add_plugin(accountregister::AccountRegisterPlugin)
            .add_plugin(accountlogin::AccountLoginPlugin);


@@ 95,87 90,6 @@ pub enum MenuState {
    AccountRegister,
}

/// Tag component for tagging entities on account screen
#[derive(Component)]
struct OnAccountScreen;

const NORMAL_BUTTON: Color = Color::rgb(0.15, 0.15, 0.15);
const HOVERED_BUTTON: Color = Color::rgb(0.25, 0.25, 0.25);
const HOVERED_PRESSED_BUTTON: Color = Color::rgb(0.25, 0.65, 0.25);
const PRESSED_BUTTON: Color = Color::rgb(0.35, 0.75, 0.35);

/// Tag component for tagging currently selected settings tab
#[derive(Component)]
struct SelectedSettingsTab;

/// All button actions
#[derive(Component)]
enum MenuButtonAction {
    AccountLogin,
    AccountRegister,
    AccountLogout,
    BackToMainMenu,
}

fn menu_action(
    mut commands: Commands,
    interaction_query: Query<
        (&Interaction, &MenuButtonAction),
        (Changed<Interaction>, With<Button>),
    >,
    mut cfg_user: ResMut<CfgUser>,
    mut save_event_writer: EventWriter<SaveEvent>,
) {
    for (interaction, menu_button_action) in &interaction_query {
        if *interaction == Interaction::Clicked {
            match menu_button_action {
                MenuButtonAction::AccountLogin => {
                    commands.insert_resource(NextState(MenuState::AccountLogin));
                    commands.insert_resource(NextState(accountlogin::LoginState::Input));
                }
                MenuButtonAction::AccountRegister => {
                    commands.insert_resource(NextState(MenuState::AccountRegister));
                    commands.insert_resource(NextState(accountregister::RegisterState::Input));
                }
                MenuButtonAction::AccountLogout => {
                    // Reset CfgUser to default.
                    *cfg_user = CfgUser::default();

                    save_event_writer.send(SaveEvent {
                        value: SaveEventValue::User(cfg_user.clone()),
                    });

                    commands.insert_resource(NextState(MenuState::AccountLoggedOut))
                }
                MenuButtonAction::BackToMainMenu => {
                    commands.insert_resource(NextState(MenuState::Main))
                }
            }
        }
    }
}

/// System for handling button hovering
fn button_system(
    mut interaction_query: Query<
        (
            &Interaction,
            &mut BackgroundColor,
            Option<&SelectedSettingsTab>,
        ),
        (Changed<Interaction>, With<Button>),
    >,
) {
    for (interaction, mut color, selected) in &mut interaction_query {
        *color = match (*interaction, selected) {
            (Interaction::Clicked, _) | (Interaction::None, Some(_)) => PRESSED_BUTTON.into(),
            (Interaction::Hovered, Some(_)) => HOVERED_PRESSED_BUTTON.into(),
            (Interaction::Hovered, None) => HOVERED_BUTTON.into(),
            (Interaction::None, None) => NORMAL_BUTTON.into(),
        }
    }
}

fn menu_setup(mut commands: Commands) {
    commands.insert_resource(NextState(MenuState::Main))
}