made placed text changeable
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "desktop_dungeon_generator"
|
name = "desktop_dungeon_generator"
|
||||||
version = "0.8.1"
|
version = "0.9.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
+64
-5
@@ -9,16 +9,17 @@ use std::sync::mpsc;
|
|||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use crate::exporter;
|
use crate::exporter;
|
||||||
use crate::interact::{MultiDragState, MultiResizeState, SelectedItem, SelectionBoxDrag,
|
use crate::interact::{
|
||||||
AddCorridorDrag, AddDoorDrag, DragState, HoverMarker, ResizeState, draw_grid,
|
draw_grid, AddCorridorDrag, AddDoorDrag, DragState, HoverMarker, MultiDragState,
|
||||||
|
MultiResizeState, ResizeState, SelectedItem, SelectionBoxDrag,
|
||||||
};
|
};
|
||||||
use crate::layout::{
|
use crate::layout::{
|
||||||
self, DoorSettings, DungeonLayout, WindowSettings, populate_random_markers, populate_stairs,
|
self, populate_random_markers, populate_stairs, DoorSettings, DungeonLayout, WindowSettings,
|
||||||
};
|
};
|
||||||
use crate::rendering::draw_layout;
|
use crate::rendering::draw_layout;
|
||||||
use crate::saveandload;
|
use crate::saveandload;
|
||||||
use crate::settings;
|
use crate::settings;
|
||||||
use crate::ui::{AddTool, UiSettings, draw_legend_panel, draw_level_tabs, draw_side_panel};
|
use crate::ui::{draw_legend_panel, draw_level_tabs, draw_side_panel, AddTool, UiSettings};
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
@@ -57,6 +58,7 @@ pub struct DungeonApp {
|
|||||||
pub hover_level_idx: Option<usize>,
|
pub hover_level_idx: Option<usize>,
|
||||||
pub hover_stair_idx: Option<usize>,
|
pub hover_stair_idx: Option<usize>,
|
||||||
pub rename_level_state: Option<(usize, String)>,
|
pub rename_level_state: Option<(usize, String)>,
|
||||||
|
pub rename_text_state: Option<(usize, String)>,
|
||||||
pub selection: Vec<SelectedItem>,
|
pub selection: Vec<SelectedItem>,
|
||||||
pub selection_box_drag: Option<SelectionBoxDrag>,
|
pub selection_box_drag: Option<SelectionBoxDrag>,
|
||||||
pub multi_drag_state: Option<MultiDragState>,
|
pub multi_drag_state: Option<MultiDragState>,
|
||||||
@@ -88,6 +90,7 @@ impl Default for DungeonApp {
|
|||||||
hover_level_idx: None,
|
hover_level_idx: None,
|
||||||
hover_stair_idx: None,
|
hover_stair_idx: None,
|
||||||
rename_level_state: None,
|
rename_level_state: None,
|
||||||
|
rename_text_state: None,
|
||||||
selection: Vec::new(),
|
selection: Vec::new(),
|
||||||
selection_box_drag: None,
|
selection_box_drag: None,
|
||||||
multi_drag_state: None,
|
multi_drag_state: None,
|
||||||
@@ -294,7 +297,10 @@ impl eframe::App for DungeonApp {
|
|||||||
&& ui.input(|i| i.key_pressed(egui::Key::Enter)))
|
&& ui.input(|i| i.key_pressed(egui::Key::Enter)))
|
||||||
{
|
{
|
||||||
if level_idx < self.levels.len() {
|
if level_idx < self.levels.len() {
|
||||||
|
if self.levels[level_idx].name != name {
|
||||||
|
self.push_undo_snapshot();
|
||||||
self.levels[level_idx].name = name.clone();
|
self.levels[level_idx].name = name.clone();
|
||||||
|
}
|
||||||
self.rename_level_state = None;
|
self.rename_level_state = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,12 +312,63 @@ impl eframe::App for DungeonApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some((text_idx, mut text)) = self.rename_text_state.take() {
|
||||||
|
let mut open = true;
|
||||||
|
egui::Window::new("Rename Text")
|
||||||
|
.collapsible(false)
|
||||||
|
.resizable(false)
|
||||||
|
.open(&mut open)
|
||||||
|
.show(ctx, |ui| {
|
||||||
|
ui.horizontal(|ui| {
|
||||||
|
ui.label("Text:");
|
||||||
|
let res = ui.text_edit_singleline(&mut text);
|
||||||
|
if ui.button("Rename").clicked()
|
||||||
|
|| (res.lost_focus()
|
||||||
|
&& ui.input(|i| i.key_pressed(egui::Key::Enter)))
|
||||||
|
{
|
||||||
|
let changed = self
|
||||||
|
.levels
|
||||||
|
.get(self.settings.active_level_index)
|
||||||
|
.and_then(|l| l.text_labels.get(text_idx))
|
||||||
|
.map(|l| l.text != text)
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
if changed {
|
||||||
|
self.push_undo_snapshot();
|
||||||
|
if let Some(layout) =
|
||||||
|
self.levels.get_mut(self.settings.active_level_index)
|
||||||
|
{
|
||||||
|
if text_idx < layout.text_labels.len() {
|
||||||
|
layout.text_labels[text_idx].text = text.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.rename_text_state = None;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if open {
|
||||||
|
self.rename_text_state = Some((text_idx, text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let available = ui.available_size_before_wrap();
|
let available = ui.available_size_before_wrap();
|
||||||
let (response, painter) = ui.allocate_painter(available, egui::Sense::click_and_drag());
|
let (response, painter) = ui.allocate_painter(available, egui::Sense::click_and_drag());
|
||||||
let canvas = response.rect.shrink(12.0);
|
let canvas = response.rect.shrink(12.0);
|
||||||
let geometry = draw_grid(&painter, canvas, self.settings.cols, self.settings.rows);
|
let geometry = draw_grid(&painter, canvas, self.settings.cols, self.settings.rows);
|
||||||
crate::interact::update_hover_targets(self, ctx, &geometry);
|
crate::interact::update_hover_targets(self, ctx, &geometry);
|
||||||
|
|
||||||
|
if response.double_clicked() {
|
||||||
|
if let Some(text_idx) = self.hover_text_idx {
|
||||||
|
if let Some(layout) = self.levels.get(self.settings.active_level_index) {
|
||||||
|
if let Some(label) = layout.text_labels.get(text_idx) {
|
||||||
|
self.rename_text_state = Some((text_idx, label.text.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let level_delete_requested = ctx.input(|i| {
|
let level_delete_requested = ctx.input(|i| {
|
||||||
(i.key_pressed(egui::Key::Delete) || i.key_pressed(egui::Key::Backspace))
|
(i.key_pressed(egui::Key::Delete) || i.key_pressed(egui::Key::Backspace))
|
||||||
&& self.hover_level_idx.is_some()
|
&& self.hover_level_idx.is_some()
|
||||||
@@ -320,7 +377,8 @@ impl eframe::App for DungeonApp {
|
|||||||
self.delete_level(level_idx);
|
self.delete_level(level_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
let multi_consumed = crate::interact::handle_multi_select(self, ctx, &response, &geometry);
|
let multi_consumed =
|
||||||
|
crate::interact::handle_multi_select(self, ctx, &response, &geometry);
|
||||||
let resizing = if !multi_consumed {
|
let resizing = if !multi_consumed {
|
||||||
crate::interact::handle_resize(self, ctx, &response, &geometry)
|
crate::interact::handle_resize(self, ctx, &response, &geometry)
|
||||||
} else {
|
} else {
|
||||||
@@ -510,6 +568,7 @@ impl DungeonApp {
|
|||||||
self.selection_box_drag = None;
|
self.selection_box_drag = None;
|
||||||
self.multi_drag_state = None;
|
self.multi_drag_state = None;
|
||||||
self.multi_resize_state = None;
|
self.multi_resize_state = None;
|
||||||
|
self.rename_text_state = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Captures the current app state for undo history.
|
// Captures the current app state for undo history.
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
CorridorDragState, GridGeometry, HoverMarker, MarkerDragState, MarkerKind, StaircaseDragState,
|
|
||||||
door_edges_for, marker_contains_cell, normalized_edge, pointer_to_grid, resize_hit_cells,
|
door_edges_for, marker_contains_cell, normalized_edge, pointer_to_grid, resize_hit_cells,
|
||||||
|
CorridorDragState, GridGeometry, HoverMarker, MarkerDragState, MarkerKind, StaircaseDragState,
|
||||||
};
|
};
|
||||||
use crate::app::DungeonApp;
|
use crate::app::DungeonApp;
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
@@ -179,17 +179,19 @@ pub fn text_at_pointer(
|
|||||||
pointer_pos: egui::Pos2,
|
pointer_pos: egui::Pos2,
|
||||||
geometry: &GridGeometry,
|
geometry: &GridGeometry,
|
||||||
) -> Option<usize> {
|
) -> Option<usize> {
|
||||||
let (grid_x, grid_y) = pointer_to_grid(pointer_pos, geometry)?;
|
|
||||||
let clicked = (grid_x.floor() as usize, grid_y.floor() as usize);
|
|
||||||
if app.settings.active_level_index >= app.levels.len() {
|
if app.settings.active_level_index >= app.levels.len() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let layout = &app.levels[app.settings.active_level_index];
|
let layout = &app.levels[app.settings.active_level_index];
|
||||||
|
|
||||||
layout
|
for (idx, label) in layout.text_labels.iter().enumerate().rev() {
|
||||||
.text_labels
|
let rect = crate::rendering::text_label_rect(geometry, label);
|
||||||
.iter()
|
if rect.contains(pointer_pos) {
|
||||||
.position(|label| label.cell == clicked)
|
return Some(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computes at pointer.
|
// Computes at pointer.
|
||||||
|
|||||||
Reference in New Issue
Block a user