diff options
Diffstat (limited to 'src/ui')
| -rw-r--r-- | src/ui/bodies_window.rs | 114 | ||||
| -rw-r--r-- | src/ui/fleet_window.rs | 190 | ||||
| -rw-r--r-- | src/ui/topbar.rs | 9 |
3 files changed, 179 insertions, 134 deletions
diff --git a/src/ui/bodies_window.rs b/src/ui/bodies_window.rs index 21a2060..7e24948 100644 --- a/src/ui/bodies_window.rs +++ b/src/ui/bodies_window.rs @@ -1,6 +1,3 @@ -use egui::Sense; - -use crate::eguictx::EguiCtx; use crate::ntree::{NTree, NTreeNode}; use crate::solar_system::body::{BodyId, OrbitalBody}; use crate::solar_system::{SolarSystem, SystemId}; @@ -11,8 +8,6 @@ use crate::timeman::TimeMan; pub struct BodiesWindowState { pub open: bool, - last_system: Option<SystemId>, - system_heirarchy: NTree<SystemId>, selected_body: Option<BodyId> } @@ -24,64 +19,19 @@ pub struct BodiesWindowAction impl BodiesWindowState { - fn build_system_heirarchy_rec( - bodies: &[OrbitalBody], - node: &mut NTreeNode<BodyId>) - { - for body in bodies { - let orbit = body.get_orbit(); - match orbit { - Some(orbit) => { - if orbit.parent() != *node.value() { - continue; - } - }, - None => { - continue; - } - } - let mut subnode = NTreeNode::new(body.id()); - BodiesWindowState::build_system_heirarchy_rec(bodies, &mut subnode); - node.insert_node(subnode); - } - } - - fn rebuild_system_heirarchy( + pub fn paint( &mut self, - star_system: &SolarSystem) - { - let mut root_node = NTreeNode::<BodyId>::new(0); - - let bodies = star_system.bodies(); - BodiesWindowState::build_system_heirarchy_rec(bodies, &mut root_node); - self.system_heirarchy.set_root(root_node); - } - - pub fn render( - &mut self, - current_system: &SolarSystem, - eguictx: &EguiCtx) + ui: &mut egui::Ui, + current_system: &SolarSystem) -> BodiesWindowAction { - match self.last_system { - Some(last_system) => { - if last_system != current_system.id() { - self.rebuild_system_heirarchy(current_system); - } - }, - None => { - self.rebuild_system_heirarchy(current_system); - } - } - self.last_system = Some(current_system.id()); - let mut action = BodiesWindowAction::default(); let mut bodies_window_open = self.open; egui::Window::new("Bodies") .open(&mut &mut bodies_window_open) .resizable(true) - .show(eguictx.context(), |ui| { + .show(ui.ctx(), |ui| { ui.horizontal(|ui| { self.paint_bodies_list(current_system, ui); @@ -142,8 +92,8 @@ impl BodiesWindowState .min_scrolled_height(200.0) .show(ui, |ui| { ui.vertical(|ui| { - let root = self.system_heirarchy.root(); - let new_sel = self.paint_bodies_node_rec(star_system, root.as_ref().unwrap(), ui); + let root = star_system.heirarchy(); + let new_sel = self.paint_bodies_node_rec(star_system, root, ui); if new_sel.is_some() { self.selected_body = new_sel; } @@ -176,26 +126,40 @@ impl BodiesWindowState }); ui.vertical(|ui| { - ui.vertical_centered(|ui| { - ui.label("Physical Properties"); - }); - ui.label(format!("Mass: {:.4E} kg", selected_body.mass())); - ui.label(format!("Radius: {} km", selected_body.radius())); - - if let Some(orbit) = selected_body.get_orbit() { - ui.vertical_centered(|ui| { - ui.label("Orbital Properties"); + ui.style_mut().interaction.selectable_labels = false; + egui_extras::TableBuilder::new(ui) + .column(egui_extras::Column::auto()) + .column(egui_extras::Column::remainder()) + .body(|mut body| { + body.row(16.0, |mut row| { + row.col(|col| { col.label("Mass"); }); + row.col(|col| { col.label(format!("{:.4E}", selected_body.mass())); }); }); - ui.label(format!("Orbiting {}", - star_system.body(orbit.parent()).name() - )); - ui.label(format!("Period: {}", - TimeMan::format_duration(orbit.period(selected_body)) - )); - ui.label(format!("Semi-major Axis: {:.4E} km", - orbit.sma() - )); - } + body.row(16.0, |mut row| { + row.col(|col| { col.label("Radius"); }); + row.col(|col| { col.label(format!("{:.4E}", selected_body.radius())); }); + }); + + if let Some(orbit) = selected_body.get_orbit() { + let parent = star_system.body(orbit.parent()); + body.row(16.0, |mut row| { + row.col(|col| { col.label("Orbiting"); }); + row.col(|col| { col.label(parent.name()); }); + }); + body.row(16.0, |mut row| { + row.col(|col| { col.label("Period"); }); + row.col(|col| { + col.label(format!("{}", + TimeMan::format_duration(orbit.period(selected_body)) + )); + }); + }); + body.row(16.0, |mut row| { + row.col(|col| { col.label("Semi-major Axis"); }); + row.col(|col| { col.label(format!("{:.4E} km", orbit.sma())); }); + }); + } + }); }); }); diff --git a/src/ui/fleet_window.rs b/src/ui/fleet_window.rs index eb8ccde..55e3d59 100644 --- a/src/ui/fleet_window.rs +++ b/src/ui/fleet_window.rs @@ -1,17 +1,22 @@ -use std::cell::RefCell; - use crate::GameState; -use crate::eguictx::EguiCtx; -use crate::fleet::{Fleet, FleetsManager}; +use crate::fleet::{Fleet, FleetId, FleetsManager}; +use crate::solar_system::orbit::StaticOrbiter; use crate::solar_system::{Kilometers, SolarSystem, SystemId}; use crate::solar_system::body::BodyId; +#[derive(Default, Clone, PartialEq)] +enum FleetMenuPanelSel { + #[default] + Info, + Schedule +} #[derive(Default, Clone)] pub struct FleetWindowState { pub open: bool, - pub selected_system: Option<SystemId>, + pub selected_fleet: Option<FleetId>, + pub menu_panel: FleetMenuPanelSel, pub new_fleet_window: Option<NewFleetWindowState> } @@ -33,7 +38,7 @@ pub struct NewFleetWindowState pub fleet_sma: Kilometers } -#[derive(Default, Clone)] +#[derive(Clone)] pub struct NewFleet { pub system: SystemId, @@ -46,8 +51,9 @@ impl FleetWindowState { pub fn paint( &mut self, + ui: &mut egui::Ui, game_state: &GameState, - eguictx: &EguiCtx, + focused_system: &Option<SystemId>, focused_body: &Option<BodyId>) -> FleetWindowAction { @@ -59,22 +65,30 @@ impl FleetWindowState let mut mgr_open = self.open; egui::Window::new("Fleet Manager") .open(&mut mgr_open) - .show(eguictx.context(), |ui| { + .show(ui.ctx(), |ui| { - ui.horizontal(|ui| { - self.paint_systems_list( - &mut action, - ui, - fleets_manager, - star_systems, - focused_body - ); + ui.vertical(|ui| { + ui.horizontal(|ui| { + self.paint_fleet_list(fleets_manager, ui); + self.paint_fleet_menu(star_systems, fleets_manager, ui); + }); + + if focused_system.is_some() { + if ui.button("New Fleet").clicked() { + if self.new_fleet_window.is_none() { + self.new_fleet_window = Some(NewFleetWindowState::new( + focused_system.unwrap(), + focused_body.unwrap_or(0) + )); + } + } + } }); }); match &mut self.new_fleet_window { Some(new_fleet_window) => { - action.new_fleet = new_fleet_window.paint(game_state, eguictx); + action.new_fleet = new_fleet_window.paint(ui, game_state); if action.new_fleet.is_some() || !new_fleet_window.open { self.new_fleet_window = None; } @@ -86,53 +100,106 @@ impl FleetWindowState action } - fn paint_systems_list( + fn paint_fleet_menu( &mut self, - action: &mut FleetWindowAction, - ui: &mut egui::Ui, - fleets_manager: &FleetsManager, star_systems: &[SolarSystem], - focused_body: &Option<BodyId>) - -> egui::InnerResponse<()> + fleets_man: &FleetsManager, + ui: &mut egui::Ui) { - ui.vertical(|ui| { - for system in star_systems { - self.paint_fleet_list(fleets_manager, &system, ui); + let fleet = match self.selected_fleet { + Some(id) => { fleets_man.entry(id) }, + None => { return; } + }; + let fleet = match fleet { + Some(entry) => entry, + None => { + self.selected_fleet = None; + return; } + }; - if self.selected_system.is_none() { return; } - if ui.button("New Fleet").clicked() { - if self.new_fleet_window.is_none() { - self.new_fleet_window = Some(NewFleetWindowState::new( - self.selected_system.unwrap(), - focused_body.unwrap_or(0) - )); + ui.separator(); + ui.vertical(|ui| { + ui.horizontal(|ui| { + if ui.button("Info").clicked() { + self.menu_panel = FleetMenuPanelSel::Info; } + if ui.button("Schedule").clicked() { + self.menu_panel = FleetMenuPanelSel::Schedule; + } + }); + self.paint_fleet_menu_info(star_systems, fleets_man, fleet, ui); + }); + } + + fn paint_fleet_menu_info( + &mut self, + star_systems: &[SolarSystem], + fleets_man: &FleetsManager, + fleet: &Fleet, + ui: &mut egui::Ui) + { + if self.menu_panel != FleetMenuPanelSel::Info { + return; + } + egui::Frame::canvas(ui.style()).show(ui, |ui| { + ui.set_min_width(200.0); + ui.style_mut().interaction.selectable_labels = false; + + if let Some(orbit) = fleet.orbit() { + let star_system = &star_systems[orbit.system()]; + let parent = star_system.body(orbit.parent()); + + ui.push_id("orbital_info_table", |ui| { + egui_extras::TableBuilder::new(ui) + .column(egui_extras::Column::auto()) + .column(egui_extras::Column::remainder()) + .body(|mut body| { + body.row(16.0, |mut row| { + row.col(|col| { col.label("System"); }); + row.col(|col| { col.label(star_system.name()); }); + }); + body.row(16.0, |mut row| { + row.col(|col| { col.label("Orbiting"); }); + row.col(|col| { col.label(parent.name()); }); + }); + body.row(16.0, |mut row| { + row.col(|col| { col.label("Radius"); }); + row.col(|col| { col.label(format!("{:.1}", orbit.sma())); }); + }); + }); + }); + + ui.separator(); } - }) + + let heading = fleet.heading(); + egui_extras::TableBuilder::new(ui) + .column(egui_extras::Column::auto()) + .column(egui_extras::Column::remainder()) + .body(|mut body| { + body.row(16.0, |mut row| { + row.col(|col| { col.label("Heading"); }); + row.col(|col| { + col.label(format!("{:?} by {:?}", + cgmath::Deg::<f32>::from(heading.x), + cgmath::Deg::<f32>::from(heading.y) + )); + }); + }); + }); + }); } fn paint_fleet_list( &mut self, - fleets_manager: &FleetsManager, - star_system: &SolarSystem, + fleets_man: &FleetsManager, ui: &mut egui::Ui) { - let fleet_ids = star_system.fleets(fleets_manager); - egui::collapsing_header::CollapsingState::load_with_default_open( - ui.ctx(), - ui.make_persistent_id(format!("fleet_window_star_{}", star_system.id())), - true - ) - .show_header(ui, |ui| { - let selected = self.selected_system.is_some_and(|id| { id == star_system.id() }); - if ui.selectable_label(selected, star_system.name()).clicked() { - self.selected_system = if !selected { Some(star_system.id()) } else { None }; - } - }) - .body(|ui| { + let fleet_ids = fleets_man.all(); + ui.vertical(|ui| { for id in fleet_ids { - if let Some(fleet) = fleets_manager.entry(id) { + if let Some(fleet) = fleets_man.entry(id) { self.paint_fleet_entry(fleet, ui); } } @@ -144,7 +211,10 @@ impl FleetWindowState fleet: &Fleet, ui: &mut egui::Ui) { - ui.label(fleet.name()); + let selected = self.selected_fleet.is_some_and(|id| { id == fleet.id() }); + if ui.selectable_label(selected, fleet.name()).clicked() { + self.selected_fleet = if selected { None } else { Some(fleet.id()) }; + } } } // FleetWindowAction @@ -164,8 +234,8 @@ impl NewFleetWindowState pub fn paint( &mut self, - game_state: &GameState, - eguictx: &EguiCtx) + ui: &mut egui::Ui, + game_state: &GameState,) -> Option<NewFleet> { let solar_system = &game_state.solar_systems()[self.parent_system]; @@ -174,7 +244,7 @@ impl NewFleetWindowState match egui::Window::new("New Fleet") .collapsible(false) .open(&mut self.open) - .show(eguictx.context(), |ui| { + .show(ui.ctx(), |ui| { ui.vertical(|ui| { ui.horizontal(|ui| { ui.label("Name: "); @@ -205,4 +275,16 @@ impl NewFleetWindowState None => None } } +} // impl FleetWindowState + +impl Default for NewFleet +{ + fn default() -> Self { + Self { + system: Default::default(), + orbiting: Default::default(), + name: "New Fleet".to_string(), + sma: Default::default() + } + } } diff --git a/src/ui/topbar.rs b/src/ui/topbar.rs index ba26d7c..511c67e 100644 --- a/src/ui/topbar.rs +++ b/src/ui/topbar.rs @@ -22,7 +22,7 @@ impl TopBarState { pub fn paint( &mut self, - eguictx: &EguiCtx, + ui: &mut egui::Ui, game_state: &GameState, bodies_window_state: &BodiesWindowState, fleets_window_state: &FleetWindowState) @@ -33,8 +33,8 @@ impl TopBarState let solar_systems = game_state.solar_systems(); let timeman = game_state.timeman(); - egui::TopBottomPanel::top("topbar").show( - eguictx.context(), + egui::Panel::top("topbar").show_inside( + ui, |ui| { ui.horizontal(|ui| { @@ -62,7 +62,7 @@ impl TopBarState }); }); - self.paint_tick_buttons(&mut action, timeman, ui); + self.paint_tick_buttons(&mut action, ui); }); ui.vertical_centered_justified(|ui| { @@ -95,7 +95,6 @@ impl TopBarState pub fn paint_tick_buttons( &mut self, action: &mut TopBarAction, - timeman: &TimeMan, ui: &mut egui::Ui) { let button_seconds = [ |
