diff options
| author | Jon Santmyer <jon@jonsantmyer.com> | 2026-05-07 08:50:05 -0400 |
|---|---|---|
| committer | Jon Santmyer <jon@jonsantmyer.com> | 2026-05-07 08:50:05 -0400 |
| commit | c1adf64c1aaecd5a2b9d532d707ef35971f1aa18 (patch) | |
| tree | fc1050becd0576d75a8d6afb8be09fae80c91541 /src/ui/bodies_window.rs | |
| parent | 9788d9037ad7199701b1710c28559cb96bce5aec (diff) | |
| download | systemic4x-c1adf64c1aaecd5a2b9d532d707ef35971f1aa18.tar.gz systemic4x-c1adf64c1aaecd5a2b9d532d707ef35971f1aa18.tar.bz2 systemic4x-c1adf64c1aaecd5a2b9d532d707ef35971f1aa18.zip | |
begin work on body info window
Diffstat (limited to 'src/ui/bodies_window.rs')
| -rw-r--r-- | src/ui/bodies_window.rs | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/src/ui/bodies_window.rs b/src/ui/bodies_window.rs new file mode 100644 index 0000000..6300f5f --- /dev/null +++ b/src/ui/bodies_window.rs @@ -0,0 +1,180 @@ +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}; + + +#[derive(Default, Clone)] +pub struct BodiesWindowState +{ + last_system: Option<SystemId>, + system_heirarchy: NTree<SystemId>, + selected_body: Option<BodyId> +} + +#[derive(Default, Clone)] +pub struct BodiesWindowAction +{ + pub focus_body: Option<BodyId> +} + +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( + &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) + -> 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(); + + egui::Window::new("Bodies") + .resizable(true) + .show(eguictx.context(), |ui| { + + ui.horizontal(|ui| { + self.paint_bodies_list(current_system, ui); + self.paint_body_info_panel(&mut action, current_system, ui); + }); + }); + action + } + + fn paint_bodies_node_rec( + &self, + star_system: &SolarSystem, + node: &NTreeNode<BodyId>, + ui: &mut egui::Ui) + -> Option<BodyId> + { + let body = star_system.body(*node.value()); + let children = node.children(); + + let selected = self.selected_body.is_some_and(|v| { v == *node.value() }); + let mut new_selected = None; + + if children.is_empty() { + if ui.selectable_label(selected, body.name()).clicked() { + new_selected = Some(*node.value()); + } + }else{ + egui::collapsing_header::CollapsingState::load_with_default_open( + ui.ctx(), + ui.make_persistent_id(format!("bodies_window_body_{}", body.id())), + true) + .show_header(ui, |ui| { + if ui.selectable_label(selected, body.name()).clicked() { + new_selected = Some(*node.value()); + } + }) + .body(|ui| { + for child in children { + let child_selected = self.paint_bodies_node_rec(star_system, child, ui); + if child_selected.is_some() { + new_selected = child_selected; + } + } + }); + }; + new_selected + } + + fn paint_bodies_list( + &mut self, + star_system: &SolarSystem, + ui: &mut egui::Ui) + -> Option<egui::Response> + { + let resp = egui::ScrollArea::vertical() + .auto_shrink(true) + .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); + if new_sel.is_some() { + self.selected_body = new_sel; + } + }).response + }); + Some(resp.inner) + } + + fn paint_body_info_panel( + &mut self, + action: &mut BodiesWindowAction, + star_system: &SolarSystem, + ui: &mut egui::Ui) + { + let selected_body = match self.selected_body { + Some(id) => { star_system.body(id) }, + None => { return; } + }; + + ui.separator(); + egui::Frame::canvas(ui.style()) + .show(ui, |ui| { + ui.set_width(200.0); + ui.vertical_centered(|ui| { + ui.label( + egui::RichText::new(selected_body.name()) + .heading()); + }); + + ui.horizontal(|ui| { + let focus_resp = ui.button("Focus"); + + if focus_resp.clicked() { + action.focus_body = Some(selected_body.id()); + } + }); + }); + } +} |
