M sdbclient/assets/ui.ess => sdbclient/assets/ui.ess +6 -0
@@ 18,6 18,12 @@
   color: #E6E6E6;
 }
 
+.mainmenutitle {
+  font-size: 80;
+  margin: 50px;
+  color: #E6E6E6;
+}
+
 .menubutton {
   width: 200px;
   height: 65px;
 
M sdbclient/src/plugins/menu/mainmenuscreen.rs => sdbclient/src/plugins/menu/mainmenuscreen.rs +60 -77
@@ 1,92 1,75 @@
 /*
  * 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::{app::AppExit, prelude::*};
+use iyes_loopless::prelude::*;
 
-use crate::constants::TEXT_COLOR;
+use belly::prelude::*;
 
-use super::{MenuButtonAction, NORMAL_BUTTON};
+use crate::cfg::CfgUser;
 
-/// Tag component for tagging entities on menu screen
-#[derive(Component)]
-pub struct OnMainMenuScreen;
+use super::MenuState;
 
-pub fn main_menu_setup(mut commands: Commands, asset_server: Res<AssetServer>) {
-    let font = asset_server.load("fonts/FiraMono-Regular.ttf");
+pub(super) struct ToAccountEvent;
+pub(super) struct ExitEvent;
 
-    let button_style = Style {
-        size: Size::new(Val::Px(250.), Val::Px(65.)),
-        margin: UiRect::all(Val::Px(20.)),
-        justify_content: JustifyContent::Center,
-        align_items: AlignItems::Center,
-        ..Default::default()
-    };
-
-    let button_text_style = TextStyle {
-        font: font.clone(),
-        font_size: 40.0,
-        color: TEXT_COLOR,
-    };
+pub(super) fn main_menu_setup(mut commands: Commands) {
+    // TODO: Change the title to a fancy image logo thingy
+    commands.add(eml! {
+        <body>
+            <div c:menu>
+                <span c:mainmenutitle>
+                    "Deck Builder"
+                </span>
+                <button c:menubutton s:width="250px" on:press=connect!(|ctx| {
+                    ctx.commands().insert_resource(NextState(MenuState::Play))
+                })>
+                    "Play"
+                </button>
+                <button c:menubutton s:width="250px" on:press=connect!(|ctx| {
+                    ctx.send_event(ToAccountEvent)
+                })>
+                    "Account"
+                </button>
+                <button c:menubutton s:width="250px" on:press=connect!(|ctx| {
+                    ctx.commands().insert_resource(NextState(MenuState::Settings))
+                })>
+                    "Settings"
+                </button>
+                <button c:menubutton s:width="250px" on:press=connect!(|ctx| {
+                    ctx.send_event(ExitEvent)
+                })>
+                    "Exit"
+                </button>
+            </div>
+        </body>
+    });
+}
 
-    commands
-        .spawn((
-            NodeBundle {
-                style: Style {
-                    size: Size::new(Val::Percent(100.), Val::Percent(100.)),
-                    align_items: AlignItems::Center,
-                    justify_content: JustifyContent::Center,
-                    flex_direction: FlexDirection::Column,
-                    ..Default::default()
-                },
-                ..Default::default()
-            },
-            OnMainMenuScreen,
-        ))
-        .with_children(|parent| {
-            // Game title, currently text
-            // TODO: Change to a fancy image logo
-            parent.spawn(
-                TextBundle::from_section(
-                    "Deck Builder",
-                    TextStyle {
-                        font: font.clone(),
-                        font_size: 80.0,
-                        color: TEXT_COLOR,
-                    },
-                )
-                .with_style(Style {
-                    margin: UiRect::all(Val::Px(50.)),
-                    ..Default::default()
-                }),
-            );
+pub(super) fn handle_to_account_event(
+    mut events: EventReader<ToAccountEvent>,
+    mut commands: Commands,
+    cfg_user: Res<CfgUser>,
+) {
+    for _event in events.iter() {
+        if cfg_user.logged_in {
+            commands.insert_resource(NextState(MenuState::AccountLoggedIn))
+        } else {
+            commands.insert_resource(NextState(MenuState::AccountLoggedOut))
+        }
+    }
+}
 
-            // Main menu buttons
-            for (action, text) in [
-                (MenuButtonAction::Play, "Play"),
-                (MenuButtonAction::Account, "Account"),
-                (MenuButtonAction::Settings, "Settings"),
-                (MenuButtonAction::Exit, "Exit"),
-            ] {
-                parent
-                    .spawn((
-                        ButtonBundle {
-                            style: button_style.clone(),
-                            background_color: NORMAL_BUTTON.into(),
-                            ..Default::default()
-                        },
-                        action,
-                    ))
-                    .with_children(|parent| {
-                        parent.spawn(TextBundle::from_section(text, button_text_style.clone()));
-                    });
-            }
-        });
+pub(super) fn handle_exit_event(
+    mut events: EventReader<ExitEvent>,
+    mut app_exit_event_writer: EventWriter<AppExit>,
+) {
+    for _event in events.iter() {
+        app_exit_event_writer.send(AppExit);
+    }
 }
 
M  =>  +10 -18
@@ 52,7 52,16 @@ impl Plugin for MenuPlugin {
            .add_enter_system(GameState::MainMenu, menu_setup)
            // Systems for main menu screen
            .add_enter_system(MenuState::Main, main_menu_setup)
            .add_exit_system(MenuState::Main, despawn_screen::<OnMainMenuScreen>)
            .add_exit_system(MenuState::Main, remove_ui)
            .add_event::<ToAccountEvent>()
            .add_event::<ExitEvent>()
            .add_system_set(
                ConditionSet::new()
                    .run_in_state(MenuState::Main)
                    .with_system(handle_to_account_event.run_on_event::<ToAccountEvent>())
                    .with_system(handle_exit_event.run_on_event::<ExitEvent>())
                    .into()
            )
            // Systems for settings menu screen
            .add_enter_system(MenuState::Settings, settings_menu_setup)
            .add_exit_system(MenuState::Settings, despawn_screen::<OnSettingsMenuScreen>)
@@ 123,18 132,14 @@ struct SelectedSettingsTab;
/// All button actions
#[derive(Component)]
enum MenuButtonAction {
    Play,
    Settings,
    SettingsDisplay,
    SettingsAudio,
    SettingsMisc,
    Account,
    AccountLogin,
    AccountRegister,
    AccountLogout,
    BackToMainMenu,
    BackToSettings,
    Exit,
}
fn menu_action(
@@ 143,18 148,12 @@ fn menu_action(
        (&Interaction, &MenuButtonAction),
        (Changed<Interaction>, With<Button>),
    >,
    mut app_exit_events: EventWriter<AppExit>,
    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::Exit => app_exit_events.send(AppExit),
                MenuButtonAction::Play => commands.insert_resource(NextState(MenuState::Play)),
                MenuButtonAction::Settings => {
                    commands.insert_resource(NextState(MenuState::Settings))
                }
                MenuButtonAction::SettingsDisplay => {
                    commands.insert_resource(NextState(MenuState::SettingsDisplay))
                }
@@ 164,13 163,6 @@ fn menu_action(
                MenuButtonAction::SettingsMisc => {
                    commands.insert_resource(NextState(MenuState::SettingsMisc))
                }
                MenuButtonAction::Account => {
                    if cfg_user.logged_in {
                        commands.insert_resource(NextState(MenuState::AccountLoggedIn))
                    } else {
                        commands.insert_resource(NextState(MenuState::AccountLoggedOut))
                    }
                }
                MenuButtonAction::AccountLogin => {
                    commands.insert_resource(NextState(MenuState::AccountLogin));
                    commands.insert_resource(NextState(accountlogin::LoginState::Input));