summaryrefslogtreecommitdiffstats
path: root/src/ui/fleets_widget.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/fleets_widget.rs')
-rw-r--r--src/ui/fleets_widget.rs246
1 files changed, 246 insertions, 0 deletions
diff --git a/src/ui/fleets_widget.rs b/src/ui/fleets_widget.rs
new file mode 100644
index 0000000..b31a04b
--- /dev/null
+++ b/src/ui/fleets_widget.rs
@@ -0,0 +1,246 @@
+use std::str::FromStr;
+
+use crate::GameState;
+use crate::fleet::FleetsManager;
+use crate::solar_system::body::{BodyId, OrbitalBody};
+use crate::solar_system::{Kilometers, SolarSystem, SystemId};
+use crate::ui::contact::MapContact;
+
+pub struct FleetsListWidget<'f>
+{
+ fleets_man: &'f FleetsManager,
+ selected: &'f mut Option<MapContact>,
+}
+
+pub struct FleetsListResponse
+{
+ pub response: egui::Response,
+ pub refocus: Option<(SystemId, MapContact)>
+}
+
+pub struct FleetsControlPanel
+{
+ new_fleet_modal: Option<NewFleetModal>
+}
+
+pub struct FleetsControlResponse
+{
+ pub new_fleet: Option<NewFleetModal>
+}
+
+#[derive(Clone)]
+pub struct NewFleetModal
+{
+ pub name: String,
+ pub sma: Kilometers,
+}
+
+impl<'f> FleetsListWidget<'f>
+{
+ pub fn new(
+ fleets_man: &'f FleetsManager,
+ selected: &'f mut Option<MapContact>)
+ -> Self
+ {
+ Self {
+ fleets_man,
+ selected
+ }
+ }
+
+ pub fn show_ui(
+ mut self,
+ ui: &mut egui::Ui)
+ -> FleetsListResponse
+ {
+ let frame_resp = egui::Frame::new()
+ .fill(egui::Color32::from_gray(48))
+ .outer_margin(egui::Margin::same(4))
+ .inner_margin(egui::Margin::same(4))
+ .show(ui,
+ |frame| {
+ frame.set_max_height(frame.available_height() / 2.0);
+ self.show_fleets_list(frame)
+ });
+
+ FleetsListResponse {
+ response: frame_resp.response,
+ refocus: frame_resp.inner
+ }
+ }
+
+ fn show_fleets_list(
+ &mut self,
+ ui: &mut egui::Ui)
+ -> Option<(SystemId, MapContact)>
+ {
+ egui::ScrollArea::vertical()
+ .auto_shrink(false)
+ .show(ui,
+ |scrollarea| {
+ let mut refocus: Option<(SystemId, MapContact)> = None;
+ for id in self.fleets_man.all() {
+ let fleet = match self.fleets_man.fleet(id) {
+ Some(v) => v,
+ None => { continue; }
+ };
+ let contact = MapContact::from_fleet(id);
+ let selected = self.selected.is_some_and(|v| { v == contact });
+ let resp = scrollarea.selectable_label(selected, fleet.name());
+
+ if resp.double_clicked() {
+ refocus = Some((fleet.system(), contact));
+ }else if resp.clicked() {
+ *self.selected = if selected { None } else { Some(contact) };
+ }
+ }
+ refocus
+ }).inner
+ }
+} // impl FleetsListWidget
+
+impl FleetsControlPanel
+{
+ pub fn show(
+ &mut self,
+ selected_contact: &Option<MapContact>,
+ fleets_man: &FleetsManager,
+ star_system: &SolarSystem,
+ ui: &mut egui::Ui)
+ -> FleetsControlResponse
+ {
+ let mut response = FleetsControlResponse {
+ new_fleet: None
+ };
+
+ egui::Frame::new()
+ .inner_margin(egui::Margin::same(4))
+ .outer_margin(egui::Margin::same(4))
+ .fill(egui::Color32::from_gray(48))
+ .show(ui,
+ |frame| {
+ frame.horizontal(|horizontal| {
+ horizontal.take_available_width();
+ if horizontal.button("New Fleet").clicked() {
+ self.new_fleet_modal = Some(NewFleetModal::default());
+ }
+ });
+ });
+
+ if let Some(new_fleet_modal) = &mut self.new_fleet_modal {
+ let modal = new_fleet_modal.show(
+ selected_contact,
+ fleets_man,
+ star_system,
+ ui.ctx());
+
+ if modal.inner {
+ response.new_fleet = self.new_fleet_modal.take();
+ }
+
+ if modal.should_close() {
+ self.new_fleet_modal = None;
+ }
+ }
+
+ response
+ }
+}
+
+impl Default for FleetsControlPanel
+{
+ fn default()
+ -> Self
+ {
+ Self {
+ new_fleet_modal: None
+ }
+ }
+}
+
+impl NewFleetModal
+{
+ pub fn show(
+ &mut self,
+ selected_contact: &Option<MapContact>,
+ fleets_man: &FleetsManager,
+ star_system: &SolarSystem,
+ ctx: &egui::Context)
+ -> egui::ModalResponse<bool>
+ {
+ let sma_min = match selected_contact.unwrap_or(MapContact::from_body(0)).body() {
+ Some(id) => star_system.body(id).radius(),
+ None => 0.0
+ };
+
+ egui::Modal::new(egui::Id::new("NewFleetModal")).show(ctx, |ui| {
+ ui.set_width(256.0);
+ ui.heading("Create new debug fleet");
+
+ ui.horizontal(|ui| {
+ ui.label("Name: ");
+ ui.text_edit_singleline(&mut self.name);
+ });
+
+ ui.horizontal(|ui| {
+ ui.label("Orbiting: ");
+ ui.label(selected_contact.unwrap_or(MapContact::from_body(0)).name(star_system, fleets_man));
+ ui.label(" above ");
+ ui.add(
+ egui::DragValue::new(&mut self.sma).range(sma_min..=f32::MAX).suffix("km")
+ );
+ });
+
+ if ui.button("Create").clicked() {
+ ui.close();
+ return true;
+ }
+ false
+ })
+ }
+}
+
+impl Default for NewFleetModal
+{
+ fn default()
+ -> Self
+ {
+ Self {
+ name: String::from_str("New Fleet").unwrap(),
+ sma: 0.0
+ }
+ }
+}
+
+impl GameState
+{
+ pub fn new_fleet_from_modal(
+ &mut self,
+ modal: NewFleetModal,
+ star_system: SystemId,
+ contact: Option<MapContact>)
+ {
+ let contact = contact.unwrap_or(MapContact::from_body(0));
+ let star_system = &self.solar_systems[star_system];
+ let body = match contact.body() {
+ Some(id) => id,
+ None => 0
+ };
+ self.fleets.new_fleet_from_modal(modal, star_system, body);
+ }
+}
+
+impl FleetsManager
+{
+ pub fn new_fleet_from_modal(
+ &mut self,
+ modal: NewFleetModal,
+ star_system: &SolarSystem,
+ body: BodyId)
+ {
+ let id = self.new_fleet(modal.name, star_system.id());
+ let fleet = self.fleet_mut(id).unwrap();
+
+ fleet.make_orbit(star_system, body, modal.sma);
+ }
+}