diff --git a/crates/render/src/gpustate/render.rs b/crates/render/src/gpustate/render.rs index c3b601c..ec53eef 100644 --- a/crates/render/src/gpustate/render.rs +++ b/crates/render/src/gpustate/render.rs @@ -111,7 +111,7 @@ impl<'a> super::GPUState { 0..self.state.get_radialbar_counter(), ); - let textareas = self.ui.get_textareas_flying(input, &self.state); + let textareas = self.ui.get_textareas(input, &self.state); self.state .text_renderer .prepare( @@ -219,7 +219,7 @@ impl<'a> super::GPUState { 0..self.state.get_radialbar_counter(), ); - let textareas = self.ui.get_textareas_landed(input, &self.state); + let textareas = self.ui.get_textareas(input, &self.state); self.state .text_renderer .prepare( @@ -281,6 +281,7 @@ impl<'a> super::GPUState { ); self.state.frame_reset(); + self.ui.update_state(&input, &mut self.state); match input .phys_img diff --git a/crates/render/src/ui/manager.rs b/crates/render/src/ui/manager.rs index 462d091..1851a9b 100644 --- a/crates/render/src/ui/manager.rs +++ b/crates/render/src/ui/manager.rs @@ -1,29 +1,121 @@ +use std::fmt::Debug; + use galactica_content::Content; use galactica_system::{data::ShipState, phys::PhysSimShipHandle}; use glyphon::TextArea; +use log::info; -use super::{fpsindicator::FpsIndicator, planet::Planet, radar::Radar, status::Status}; +use super::scenes::{FlyingScene, LandedScene, OutfitterScene}; use crate::{RenderInput, RenderState}; +/// Output from a ui scene step +pub struct UiSceneStepResult { + /// If Some, switch to this scene + pub new_scene: Option, +} + +pub trait UiScene<'this> +where + Self: 'this, +{ + /// Draw this scene + fn draw(&mut self, input: &RenderInput, state: &mut RenderState); + + /// Update this scene's state for this frame. + /// Handles clicks, keys, etc. + fn step(&mut self, input: &RenderInput, state: &mut RenderState) -> UiSceneStepResult; + + fn get_textareas( + &'this self, + v: &mut Vec>, + input: &RenderInput, + state: &RenderState, + ); +} + +pub(super) enum UiScenes { + Landed(LandedScene), + Flying(FlyingScene), + Outfitter(OutfitterScene), +} + +impl Debug for UiScenes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Flying(_) => write!(f, "UiScenes::Flying"), + Self::Landed(_) => write!(f, "UiScenes::Landed"), + Self::Outfitter(_) => write!(f, "UiScenes::Outfitter"), + } + } +} + +impl UiScenes { + fn is_flying(&self) -> bool { + match self { + Self::Flying(_) => true, + _ => false, + } + } + + fn is_landed(&self) -> bool { + match self { + Self::Landed(_) => true, + _ => false, + } + } + + fn is_outfitter(&self) -> bool { + match self { + Self::Outfitter(_) => true, + _ => false, + } + } +} + +impl<'a> UiScene<'a> for UiScenes { + fn draw(&mut self, input: &RenderInput, state: &mut RenderState) { + match self { + Self::Flying(s) => s.draw(input, state), + Self::Landed(s) => s.draw(input, state), + Self::Outfitter(s) => s.draw(input, state), + } + } + + fn step(&mut self, input: &RenderInput, state: &mut RenderState) -> UiSceneStepResult { + match self { + Self::Flying(s) => s.step(input, state), + Self::Landed(s) => s.step(input, state), + Self::Outfitter(s) => s.step(input, state), + } + } + + fn get_textareas( + &'a self, + v: &mut Vec>, + input: &RenderInput, + state: &RenderState, + ) { + match self { + Self::Flying(s) => s.get_textareas(v, input, state), + Self::Landed(s) => s.get_textareas(v, input, state), + Self::Outfitter(s) => s.get_textareas(v, input, state), + } + } +} + pub struct UiManager { - radar: Radar, - status: Status, - fps: FpsIndicator, - planet: Planet, + current_scene: UiScenes, } impl UiManager { pub fn new(ct: &Content, state: &mut RenderState) -> Self { Self { - planet: Planet::new(ct, state), - radar: Radar::new(), - status: Status::new(), - fps: FpsIndicator::new(state), + current_scene: UiScenes::Flying(FlyingScene::new(ct, state)), } } - /// Draw all ui elements - pub fn draw(&mut self, input: &RenderInput, state: &mut RenderState) { + // TODO: remove this. + pub fn update_state(&mut self, input: &RenderInput, state: &mut RenderState) { let ship_handle = input.player.ship.unwrap(); let ship = &input .phys_img @@ -31,41 +123,44 @@ impl UiManager { .unwrap() .ship; - self.fps.update(input, state); - match ship.get_data().get_state() { ShipState::Collapsing | ShipState::Dead | ShipState::Flying { .. } | ShipState::Landing { .. } | ShipState::UnLanding { .. } => { - self.radar.draw(input, state); - self.status.draw(input, state); + if !self.current_scene.is_flying() { + self.current_scene = UiScenes::Flying(FlyingScene::new(input.ct, state)); + } } ShipState::Landed { .. } => { - self.planet.draw(input, state); + if !self.current_scene.is_landed() && !self.current_scene.is_outfitter() { + self.current_scene = UiScenes::Landed(LandedScene::new(input.ct, state)) + } } } } - /// Textareas to show while player is flying - pub fn get_textareas_flying( - &self, - _input: &RenderInput, - _state: &RenderState, - ) -> Vec