use crate::solar_system::SolarSystem; use crate::fleet::FleetsManager; use crate::ui::contact::MapContact; pub struct ContactsListWidget<'f> { contacts: Vec<(MapContact, &'f String)>, selected: &'f mut Option } pub struct FocusedContactWidget<'f> { contact: Option, star_system: &'f SolarSystem, fleets_man: &'f FleetsManager } impl<'f> ContactsListWidget<'f> { pub fn new( selected: &'f mut Option, star_system: &'f SolarSystem, fleets_man: &'f FleetsManager) -> Self { let system_fleets = fleets_man.all_in_system(star_system.id()); let system_bodies = star_system.bodies(); let mut contacts = system_fleets.iter().map(|id| { let fleet = fleets_man.fleet(*id); (MapContact::from_fleet(*id), fleet.unwrap().name()) }).collect::>(); contacts.extend(system_bodies.iter().map(|body| { (MapContact::from_body(body.id()), body.name()) })); Self { contacts: contacts, selected } } pub fn show_ui( mut self, ui: &mut egui::Ui) -> egui::InnerResponse> { self.show_entries_box(ui) } fn show_entries_box( &mut self, ui: &mut egui::Ui) -> egui::InnerResponse> { let mut ret = None; egui::Frame::default() .stroke(egui::Stroke::NONE) .fill(egui::Color32::from_rgb(48, 48, 48)) .outer_margin(egui::Margin::same(4)) .inner_margin(egui::Margin::same(4)) .show(ui, |frame| { frame.take_available_width(); frame.set_max_height(frame.available_height() / 2.0); frame.vertical(|vertical| { let mut table = egui_extras::TableBuilder::new(vertical) .striped(true) .resizable(false) .auto_shrink(false) .column(egui_extras::Column::remainder()) .body( |body| { let row_height = 20.0; body.rows(row_height, self.contacts.len(), |mut row| { let resp = self.show_contact(&mut row); if resp.is_some() { ret = resp; } }); }); }); ret }) } fn show_contact( &mut self, row: &mut egui_extras::TableRow) -> Option { let contact = &self.contacts[row.index()]; let selected = self.selected.is_some_and(|sel| { sel == contact.0 }); let mut ret = None; row.col(|col| { let resp = col.selectable_label(selected, contact.1); if resp.double_clicked() { ret = Some(contact.0); }else if resp.clicked() { *self.selected = match selected { true => None, false => Some(contact.0) }; } }); ret } } impl<'f> FocusedContactWidget<'f> { pub fn new( contact: Option, star_system: &'f SolarSystem, fleets_man: &'f FleetsManager) -> Self { Self { contact, star_system, fleets_man } } } impl egui::Widget for FocusedContactWidget<'_> { fn ui(self, ui: &mut egui::Ui) -> egui::Response { ui.vertical(|vertical| { vertical.label("Focused contact"); vertical.shrink_width_to_current(); egui::Frame::new() .fill(egui::Color32::from_gray(48)) .stroke(egui::Stroke::NONE) .inner_margin(egui::Margin::same(2)) .show(vertical, |frame| { frame.take_available_width(); match self.contact { Some(contact) => frame.label(contact.name(self.star_system, self.fleets_man)), None => frame.label("None") } }).inner }).inner } }