add settings to main menu

This commit is contained in:
griffi-gh 2024-12-12 19:01:01 +01:00
parent eec074ae43
commit 28a828430b
4 changed files with 117 additions and 23 deletions

View file

@ -16,7 +16,7 @@ use shipyard::{
WorkloadModificator, WorkloadModificator,
SystemModificator SystemModificator
}; };
use ui::main_menu::update_main_menu; use ui::{main_menu::update_main_menu, settings_ui::f1_held_settings_condition};
use winit::{ use winit::{
event_loop::{EventLoop, ControlFlow}, event_loop::{EventLoop, ControlFlow},
event::{Event, WindowEvent} event::{Event, WindowEvent}
@ -161,7 +161,7 @@ fn update() -> Workload {
//UI: //UI:
render_chat, render_chat,
draw_crosshair, draw_crosshair,
render_settings_ui, render_settings_ui.run_if(f1_held_settings_condition),
).into_sequential_workload().run_if(is_ingame), ).into_sequential_workload().run_if(is_ingame),
( (
update_shutdown_screen, update_shutdown_screen,

View file

@ -15,14 +15,19 @@ use hui::{
size, size,
}; };
use kubi_shared::data::{io_thread::IOThreadManager, open_local_save_file}; use kubi_shared::data::{io_thread::IOThreadManager, open_local_save_file};
use shipyard::{AllStoragesView, AllStoragesViewMut, IntoWorkload, NonSendSync, Unique, UniqueView, UniqueViewMut, Workload}; use settings_overlay::{not_settings_ui_shown, settings_overlay_logic};
use shipyard::{AllStoragesView, AllStoragesViewMut, IntoWorkload, NonSendSync, SystemModificator, Unique, UniqueView, UniqueViewMut, Workload, WorkloadModificator};
use crate::{ use crate::{
control_flow::RequestExit, control_flow::RequestExit,
hui_integration::UiState, networking::GameType, rendering::Renderer, state::{GameState, NextState}}; hui_integration::UiState, networking::GameType, rendering::Renderer, state::{GameState, NextState}};
mod settings_overlay;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
enum MainMenuPage { enum MainMenuPage {
TopMenu, TopMenu,
Settings,
// ListWorlds { // ListWorlds {
// list: Vec<String>, // list: Vec<String>,
// }, // },
@ -36,7 +41,8 @@ struct MainMenuState {
#[derive(Signal, Clone, Copy)] #[derive(Signal, Clone, Copy)]
enum MainMenuSignal { enum MainMenuSignal {
GotoPage(MainMenuPage), GotoPage(MainMenuPage),
Play, PlayOffline,
PlayOnline,
Quit, Quit,
// CreatePlayWorld { // CreatePlayWorld {
// name: String, // name: String,
@ -90,7 +96,9 @@ pub fn render_main_menu_ui(
}) })
.with_children(|ui| { .with_children(|ui| {
for (button_text, button_signal) in [ for (button_text, button_signal) in [
("Play", MainMenuSignal::Play), ("Singleplayer", MainMenuSignal::PlayOffline),
("Multiplayer", MainMenuSignal::PlayOnline),
("Settings", MainMenuSignal::GotoPage(MainMenuPage::Settings)),
("Quit", MainMenuSignal::Quit), ("Quit", MainMenuSignal::Quit),
] { ] {
Container::default() Container::default()
@ -123,7 +131,7 @@ fn main_menu_process_signals(
let mut quit = storages.borrow::<UniqueViewMut<RequestExit>>().unwrap(); let mut quit = storages.borrow::<UniqueViewMut<RequestExit>>().unwrap();
hui.hui.process_signals(|signal| { hui.hui.process_signals(|signal| {
match signal { match signal {
MainMenuSignal::Play => { MainMenuSignal::PlayOffline => {
log::info!("play button pressed"); log::info!("play button pressed");
// Open the local save file // Open the local save file
let save_file = open_local_save_file(Path::new("./world.kubi")).expect("failed to open save file"); let save_file = open_local_save_file(Path::new("./world.kubi")).expect("failed to open save file");
@ -132,6 +140,13 @@ fn main_menu_process_signals(
storages.add_unique(GameType::Singleplayer); storages.add_unique(GameType::Singleplayer);
storages.borrow::<UniqueViewMut<NextState>>().unwrap().0 = Some(GameState::LoadingWorld); storages.borrow::<UniqueViewMut<NextState>>().unwrap().0 = Some(GameState::LoadingWorld);
} }
MainMenuSignal::PlayOnline => {
},
MainMenuSignal::GotoPage(page) => {
log::info!("goto page button pressed");
storages.add_unique(MainMenuState { page });
}
MainMenuSignal::Quit => { MainMenuSignal::Quit => {
log::info!("quit button pressed"); log::info!("quit button pressed");
quit.0 = true; quit.0 = true;
@ -143,7 +158,8 @@ fn main_menu_process_signals(
pub fn update_main_menu() -> Workload { pub fn update_main_menu() -> Workload {
( (
render_main_menu_ui, render_main_menu_ui.run_if(not_settings_ui_shown),
settings_overlay_logic,
main_menu_process_signals, main_menu_process_signals,
).into_sequential_workload() ).into_sequential_workload()
} }

View file

@ -0,0 +1,68 @@
use std::path::Path;
use glam::vec4;
use hui::{
element::{
container::Container,
interactable::ElementInteractableExt,
text::Text,
UiElementExt
},
layout::Alignment,
rect::Corners,
signal::Signal,
rect_frame,
size,
};
use kubi_shared::data::{io_thread::IOThreadManager, open_local_save_file};
use shipyard::{AllStoragesView, AllStoragesViewMut, IntoWorkload, NonSendSync, SystemModificator, Unique, UniqueView, UniqueViewMut, Workload, WorkloadModificator};
use crate::{
control_flow::RequestExit, hui_integration::UiState, main_menu::MainMenuPage, networking::GameType, rendering::Renderer, state::{GameState, NextState}};
use super::{super::settings_ui::render_settings_ui2, MainMenuSignal, MainMenuState};
pub fn settings_ui_shown(mms: Option<UniqueView<MainMenuState>>) -> bool {
let Some(mms) = mms else { return false };
matches!(mms.page, MainMenuPage::Settings)
}
#[allow(clippy::just_underscores_and_digits)]
pub fn not_settings_ui_shown(_0: Option<UniqueView<MainMenuState>>) -> bool {
!settings_ui_shown(_0)
}
// HACK: shows the back button over the settings UI
fn show_settings_back_button(
mut hui: NonSendSync<UniqueViewMut<UiState>>,
ren: UniqueView<Renderer>,
) {
Container::default()
.with_size(size!(100%, 100%))
.with_align((Alignment::Center, Alignment::End))
.with_padding(30.)
.with_children(|ui| {
Container::default()
.with_background(rect_frame! {
color: (0.1, 0.1, 0.1),
corner_radius: 10.,
})
.with_padding((30., 5.))
.with_size(size!(auto, 50))
.with_align(Alignment::Center)
.with_children(|ui| {
Text::new("Back to the Main Menu")
.with_text_size(24)
.add_child(ui);
})
.on_click(|| MainMenuSignal::GotoPage(MainMenuPage::TopMenu))
.add_child(ui);
})
.add_root(&mut hui.hui, ren.size_vec2());
}
pub fn settings_overlay_logic() -> Workload {
(
render_settings_ui2,
show_settings_back_button,
).into_sequential_workload().run_if(settings_ui_shown)
}

View file

@ -19,7 +19,7 @@ enum SettingsSignal {
SetRenderDistance(u8), SetRenderDistance(u8),
SetEnableDynamicCrosshair(bool), SetEnableDynamicCrosshair(bool),
SetEnableVsync(bool), SetEnableVsync(bool),
SetEnableDebugChunkBorder(bool), // SetEnableDebugChunkBorder(bool),
SetMouseSensitivity(f32), SetMouseSensitivity(f32),
} }
@ -68,18 +68,19 @@ fn checkbox(
.add_child(ui); .add_child(ui);
} }
pub fn f1_held_settings_condition(
kbd: UniqueView<RawKbmInputState>,
) -> bool {
//f1 must be held down to open settings
//TODO implement ModalManager instead of this
kbd.keyboard_state.contains(KeyCode::F1 as u32)
}
pub fn render_settings_ui( pub fn render_settings_ui(
mut ui: NonSendSync<UniqueViewMut<UiState>>, mut ui: NonSendSync<UniqueViewMut<UiState>>,
mut ren: UniqueViewMut<Renderer>, mut ren: UniqueViewMut<Renderer>,
mut settings: UniqueViewMut<GameSettings>, mut settings: UniqueViewMut<GameSettings>,
kbd: UniqueView<RawKbmInputState>,
) { ) {
//f1 must be held down to open settings
//TODO implement ModalManager instead of this
if !kbd.keyboard_state.contains(KeyCode::F1 as u32) {
return
}
Container::default() Container::default()
.with_size(size!(100%)) .with_size(size!(100%))
.with_background((0., 0., 0., 0.5)) .with_background((0., 0., 0., 0.5))
@ -132,13 +133,13 @@ pub fn render_settings_ui(
); );
Break.add_child(ui); Break.add_child(ui);
checkbox( // checkbox(
ui, // ui,
"Debug Chunk Border", // "Debug Chunk Border",
settings.debug_draw_current_chunk_border, // settings.debug_draw_current_chunk_border,
SettingsSignal::SetEnableDebugChunkBorder // SettingsSignal::SetEnableDebugChunkBorder
); // );
Break.add_child(ui); // Break.add_child(ui);
Text::new("Mouse Sensitivity") Text::new("Mouse Sensitivity")
.add_child(ui); .add_child(ui);
@ -160,7 +161,16 @@ pub fn render_settings_ui(
settings.vsync = value; settings.vsync = value;
ren.reload_settings(&settings); ren.reload_settings(&settings);
}, },
SettingsSignal::SetEnableDebugChunkBorder(value) => settings.debug_draw_current_chunk_border = value && cfg!(not(target_os = "android")), // SettingsSignal::SetEnableDebugChunkBorder(value) => settings.debug_draw_current_chunk_border = value && cfg!(not(target_os = "android")),
SettingsSignal::SetMouseSensitivity(value) => settings.mouse_sensitivity = value, SettingsSignal::SetMouseSensitivity(value) => settings.mouse_sensitivity = value,
}); });
} }
#[allow(clippy::just_underscores_and_digits)]
pub fn render_settings_ui2(
_0: NonSendSync<UniqueViewMut<UiState>>,
_1: UniqueViewMut<Renderer>,
_2: UniqueViewMut<GameSettings>,
) {
render_settings_ui(_0, _1, _2);
}