diff --git a/src/app.rs b/src/app.rs index 6cea5a1..62650cc 100644 --- a/src/app.rs +++ b/src/app.rs @@ -56,6 +56,7 @@ pub struct DungeonApp { pub hover_marker: Option, pub hover_level_idx: Option, pub hover_stair_idx: Option, + pub rename_level_state: Option<(usize, String)>, } impl Default for DungeonApp { @@ -82,6 +83,7 @@ impl Default for DungeonApp { hover_marker: None, hover_level_idx: None, hover_stair_idx: None, + rename_level_state: None, }; if app.settings.composition_mode { app.enter_composition_layout(); @@ -170,9 +172,9 @@ impl eframe::App for DungeonApp { } else if panel_result.new_level_clicked { self.push_undo_snapshot(); if self.settings.composition_mode { - self.levels.push(DungeonLayout::empty( - self.settings.pack_rooms_without_corridors, - )); + let mut layout = DungeonLayout::empty(self.settings.pack_rooms_without_corridors); + layout.name = format!("Level {}", self.levels.len() + 1); + self.levels.push(layout); } else { self.levels .push(generate_level(&self.settings, self.levels.len())); @@ -257,10 +259,41 @@ impl eframe::App for DungeonApp { } egui::CentralPanel::default().show(ctx, |ui| { - self.hover_level_idx = - draw_level_tabs(ui, self.levels.len(), &mut self.settings.active_level_index); + self.hover_level_idx = draw_level_tabs( + ui, + &self.levels, + &mut self.settings.active_level_index, + &mut self.rename_level_state, + ); ui.separator(); + if let Some((level_idx, mut name)) = self.rename_level_state.take() { + let mut open = true; + egui::Window::new("Rename Level") + .collapsible(false) + .resizable(false) + .open(&mut open) + .show(ctx, |ui| { + ui.horizontal(|ui| { + ui.label("Name:"); + let res = ui.text_edit_singleline(&mut name); + if ui.button("Rename").clicked() + || (res.lost_focus() + && ui.input(|i| i.key_pressed(egui::Key::Enter))) + { + if level_idx < self.levels.len() { + self.levels[level_idx].name = name.clone(); + self.rename_level_state = None; + } + } + }); + }); + + if open { + self.rename_level_state = Some((level_idx, name)); + } + } + let available = ui.available_size_before_wrap(); let (response, painter) = ui.allocate_painter(available, egui::Sense::click_and_drag()); let canvas = response.rect.shrink(12.0); @@ -364,7 +397,7 @@ pub fn generate_all_levels(settings: &UiSettings) -> Vec { // Generates a single dungeon level from the UI settings. pub fn generate_level(settings: &UiSettings, level_index: usize) -> DungeonLayout { let level_seed = crate::seed::derive_seed(settings.seed, level_index as u64); - let layout = layout::generate_layout( + let mut layout = layout::generate_layout( settings.cols, settings.rows, settings.room_count, @@ -380,6 +413,7 @@ pub fn generate_level(settings: &UiSettings, level_index: usize) -> DungeonLayou door_settings_from_ui(settings), window_settings_from_ui(settings), ); + layout.name = format!("Level {}", level_index + 1); populate_random_markers(layout, settings) } diff --git a/src/layout/types.rs b/src/layout/types.rs index ac8d8ee..750f91c 100644 --- a/src/layout/types.rs +++ b/src/layout/types.rs @@ -213,6 +213,7 @@ pub struct WindowSettings { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] pub struct DungeonLayout { + pub name: String, pub rooms: Vec, pub corridors: Vec, pub doors: Vec, diff --git a/src/ui/panels.rs b/src/ui/panels.rs index 2942380..9e30ad9 100644 --- a/src/ui/panels.rs +++ b/src/ui/panels.rs @@ -169,16 +169,23 @@ pub fn draw_legend_panel(ctx: &egui::Context, settings: &mut UiSettings) -> bool composition_mode_changed } +use crate::layout::DungeonLayout; + // Draws level tabs. pub fn draw_level_tabs( ui: &mut egui::Ui, - level_count: usize, + levels: &[DungeonLayout], active_level_index: &mut usize, + rename_level_state: &mut Option<(usize, String)>, ) -> Option { let mut hovered_level_idx = None; ui.horizontal(|ui| { - for level_idx in 0..level_count { - let label = format!("Level {}", level_idx + 1); + for (level_idx, level) in levels.iter().enumerate() { + let label = if level.name.is_empty() { + format!("Level {}", level_idx + 1) + } else { + level.name.clone() + }; let is_active = *active_level_index == level_idx; let response = ui.selectable_label(is_active, label); if response.hovered() { @@ -187,6 +194,9 @@ pub fn draw_level_tabs( if response.clicked() { *active_level_index = level_idx; } + if response.double_clicked() { + *rename_level_state = Some((level_idx, level.name.clone())); + } } }); hovered_level_idx