/* * This file is part of laurelin/client * Copyright (C) 2023 Jonni Liljamo * * Licensed under GPL-3.0-only. * See LICENSE for licensing information. */ use bevy::prelude::*; use bevy_egui::{egui, EguiContexts}; use laurelin_shared::types::{ game::{GamePub, GAMESTATE_FINISHED, GAMESTATE_FORMING, GAMESTATE_INPROGRESS}, user::UserPub, }; use crate::{ cfg::CfgUser, plugins::{ menu::MenuState, networking::send::game::{GameAllFormingEvent, GameCreateEvent, GameMyGamesEvent}, }, util::egui::menuwindow, Global, }; use super::{PlayScreenBrowseState, PlayScreenData, PlayScreenState}; pub fn ui( mut commands: Commands, mut egui_contexts: EguiContexts, mut data: ResMut, cfg_user: Res, mut global: ResMut, mut creategame_ev_w: EventWriter, mut allforming_ev_w: EventWriter, mut mygames_ev_w: EventWriter, ) { menuwindow( egui_contexts.ctx_mut(), data.state.clone().display(), &egui::Vec2::new(800., 600.), |ui| match data.state { PlayScreenState::Main => { egui::SidePanel::left("play_side_panel") .resizable(false) .show_inside(ui, |ui| { ui.vertical_centered(|ui| { if ui.button("Create").clicked() { data.state = PlayScreenState::CreateGame; } if ui.button("Back").clicked() { commands.insert_resource(NextState(Some(MenuState::Menu))); } }); }); egui::TopBottomPanel::top("play_top_panel") .resizable(false) .show_inside(ui, |ui| { ui.horizontal(|ui| { ui.label(egui::RichText::new("Browse: ").size(24.)); ui.selectable_value( &mut data.browse_state, PlayScreenBrowseState::Forming, "Forming", ); ui.selectable_value( &mut data.browse_state, PlayScreenBrowseState::InProgress, "In Progress", ); ui.selectable_value( &mut data.browse_state, PlayScreenBrowseState::Finished, "Finished", ); ui.with_layout( egui::Layout::right_to_left(egui::Align::Center), |ui| { if ui.button("Refresh").clicked() { match data.browse_state { PlayScreenBrowseState::Forming => { if !data.waiting_for_all_forming { allforming_ev_w.send(GameAllFormingEvent); } } PlayScreenBrowseState::InProgress => { if !data.waiting_for_my_games { mygames_ev_w.send(GameMyGamesEvent); } } PlayScreenBrowseState::Finished => { if !data.waiting_for_my_games { mygames_ev_w.send(GameMyGamesEvent); } } } } }, ); }); }); ui.vertical_centered(|ui| { egui::ScrollArea::vertical().show(ui, |ui| match data.browse_state { PlayScreenBrowseState::Forming => { browse_forming(ui, &mut data, &cfg_user, &mut global); } PlayScreenBrowseState::InProgress => { browse_inprogress(ui, &mut data, &mut global, &cfg_user); } PlayScreenBrowseState::Finished => { browse_finished(ui, &mut data, &global, &cfg_user); } }); }); } PlayScreenState::CreateGame => { ui.vertical_centered(|ui| { ui.add_enabled_ui(!data.waiting_for_create_game, |ui| { if ui.button("Confirm").clicked() { data.waiting_for_create_game = true; creategame_ev_w.send(GameCreateEvent); } if ui.button("Cancel").clicked() { data.state = PlayScreenState::Main; } }); }); } PlayScreenState::InLobbyHost => { ui.label(egui::RichText::new(format!( "Host: {}", global .users_cache .get(&global.cur_game.as_ref().unwrap().host_id) .unwrap_or(&UserPub { id: "".to_string(), created_at: "".to_string(), username: "N/A".to_string() }) .username ))); ui.label(egui::RichText::new(format!( "Guest: {}", global .users_cache .get( global .cur_game .as_ref() .unwrap() .guest_id .as_ref() .unwrap_or(&"".to_string()) ) .unwrap_or(&UserPub { id: "".to_string(), created_at: "".to_string(), username: "N/A".to_string() }) .username ))); if ui.button("Start").clicked() { //startgame_ev_w.send(StartGameEvent); } if ui.button("Back").clicked() { data.state = PlayScreenState::Main; } } PlayScreenState::InLobbyGuest => { ui.label(egui::RichText::new(format!( "Host: {}", global .users_cache .get(&global.cur_game.as_ref().unwrap().host_id) .unwrap_or(&UserPub { id: "".to_string(), created_at: "".to_string(), username: "N/A".to_string() }) .username ))); ui.label(egui::RichText::new(format!( "Guest: {}", global .users_cache .get( global .cur_game .as_ref() .unwrap() .guest_id .as_ref() .unwrap_or(&"".to_string()) ) .unwrap_or(&UserPub { id: "".to_string(), created_at: "".to_string(), username: "N/A".to_string() }) .username ))); if ui.button("Back").clicked() { data.state = PlayScreenState::Main; } } }, ); } fn browse_forming( ui: &mut egui::Ui, data: &mut PlayScreenData, cfg_user: &CfgUser, global: &mut Global, ) { if data.waiting_for_all_forming { ui.horizontal(|ui| { ui.spinner(); ui.label("loading..."); }); return; } let mut all_forming: Vec<&GamePub> = global .games_cache .values() .filter(|g| g.state == GAMESTATE_FORMING) .collect(); // sort by created_at, and reverse so it's the right way round all_forming.sort_by_key(|&g| &g.created_at); all_forming = all_forming.into_iter().rev().collect(); if all_forming.is_empty() { ui.label("No forming games found."); } else { for game in all_forming { egui::Frame::none() .fill(egui::Color32::BLACK) .rounding(4.) .outer_margin(4.) .inner_margin(4.) .show(ui, |ui| { ui.horizontal(|ui| { ui.label(format!( "Host: {}", global .users_cache .get(&game.host_id) .unwrap_or(&UserPub { id: "".to_string(), created_at: "".to_string(), username: "".to_string() }) .username )); ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { if game.guest_id.clone().unwrap_or_default() == cfg_user.id { ui.add_enabled(false, egui::Button::new("Joined")); if ui.button("Inspect").clicked() { global.cur_game = Some(game.clone()); data.state = PlayScreenState::InLobbyGuest; } } else if game.host_id == cfg_user.id { ui.add_enabled(false, egui::Button::new("Host")); if ui.button("Inspect").clicked() { global.cur_game = Some(game.clone()); data.state = PlayScreenState::InLobbyHost; } } else if ui.button("Join").clicked() { //data.cur_game = Some(game.clone()); //joingame_ev_w.send(JoinGameEvent); } }); }); }); } } } fn browse_inprogress( ui: &mut egui::Ui, data: &mut PlayScreenData, global: &mut Global, cfg_user: &CfgUser, ) { if data.waiting_for_my_games { ui.horizontal(|ui| { ui.spinner(); ui.label("loading..."); }); return; } let my_games_inprogress: Vec<&GamePub> = global .games_cache .values() .filter(|g| { g.state == GAMESTATE_INPROGRESS && (g.host_id == cfg_user.id || g.guest_id.clone().unwrap_or("".to_string()) == cfg_user.id) }) .collect(); if my_games_inprogress.is_empty() { ui.label("No games found."); } else { for game in my_games_inprogress { egui::Frame::none() .fill(egui::Color32::BLACK) .rounding(4.) .outer_margin(4.) .inner_margin(4.) .show(ui, |ui| { ui.horizontal(|ui| { ui.label(format!( "Host: {}", global .users_cache .get(&game.host_id) .unwrap_or(&UserPub { id: "".to_string(), created_at: "".to_string(), username: "N/A".to_string() }) .username )); ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { if ui.button("Resume").clicked() { global.cur_game = Some(game.clone()); //resumegame_ev_w.send(ResumeGameEvent); } }); }); }); } } } fn browse_finished( ui: &mut egui::Ui, data: &mut PlayScreenData, global: &Global, cfg_user: &CfgUser, ) { if data.waiting_for_my_games { ui.horizontal(|ui| { ui.spinner(); ui.label("loading..."); }); return; } let my_games_finished: Vec<&GamePub> = global .games_cache .values() .filter(|g| { g.state == GAMESTATE_FINISHED && (g.host_id == cfg_user.id || g.guest_id.clone().unwrap_or("".to_string()) == cfg_user.id) }) .collect(); if my_games_finished.is_empty() { ui.label("No games found."); } else { for game in my_games_finished { egui::Frame::none() .fill(egui::Color32::BLACK) .rounding(4.) .outer_margin(4.) .inner_margin(4.) .show(ui, |ui| { ui.horizontal(|ui| { ui.label(format!( "Host: {}", global .users_cache .get(&game.host_id) .unwrap_or(&UserPub { id: "".to_string(), created_at: "".to_string(), username: "".to_string() }) .username )); }); }); } } }