fixed issues when resizing stairs in rooms

This commit is contained in:
grimsace
2026-04-28 14:23:37 -05:00
parent bd0d64b4af
commit 94d0a6db92
+76 -66
View File
@@ -588,6 +588,12 @@ impl DungeonApp {
{
self.push_undo_snapshot();
self.drag_state = Some(DragState::Staircase(stair_drag));
} else if response.drag_started()
&& let Some(pointer_pos) = response.interact_pointer_pos()
&& let Some(corridor_drag) = self.corridor_drag_at_pointer(pointer_pos, geometry)
{
self.push_undo_snapshot();
self.drag_state = Some(DragState::Corridor(corridor_drag));
} else if response.drag_started()
&& let Some(pointer_pos) = response.interact_pointer_pos()
&& let Some((room_idx, offset_x, offset_y)) =
@@ -599,12 +605,6 @@ impl DungeonApp {
offset_x,
offset_y,
}));
} else if response.drag_started()
&& let Some(pointer_pos) = response.interact_pointer_pos()
&& let Some(corridor_drag) = self.corridor_drag_at_pointer(pointer_pos, geometry)
{
self.push_undo_snapshot();
self.drag_state = Some(DragState::Corridor(corridor_drag));
}
if response.dragged()
@@ -1225,6 +1225,13 @@ impl DungeonApp {
// Update which room/corridor/door is currently hovered.
fn update_hover_targets(&mut self, ctx: &egui::Context, geometry: &GridGeometry) {
if self.drag_state.is_some()
|| self.resize_state.is_some()
|| self.add_corridor_drag.is_some()
{
return;
}
let Some(pointer_pos) = ctx.pointer_hover_pos() else {
self.clear_hover_targets();
return;
@@ -1560,12 +1567,6 @@ impl DungeonApp {
self.resize_state = Some(ResizeState::Text(state));
return true;
}
} else if let Some(room_idx) = self.resize_room_at_pointer(pointer_pos, geometry) {
if let Some(state) = self.start_resize(room_idx, pointer_pos, geometry) {
self.push_undo_snapshot();
self.resize_state = Some(ResizeState::Room(state));
return true;
}
} else if let Some(stair_idx) = self.stair_at_pointer(pointer_pos, geometry) {
if let Some(state) =
self.start_staircase_resize(stair_idx, pointer_pos, geometry)
@@ -1574,6 +1575,12 @@ impl DungeonApp {
self.resize_state = Some(ResizeState::Staircase(state));
return true;
}
} else if let Some(room_idx) = self.resize_room_at_pointer(pointer_pos, geometry) {
if let Some(state) = self.start_resize(room_idx, pointer_pos, geometry) {
self.push_undo_snapshot();
self.resize_state = Some(ResizeState::Room(state));
return true;
}
}
}
}
@@ -1822,22 +1829,8 @@ impl DungeonApp {
return;
}
// Check for collisions with other stairs or rooms on the current level.
// Check for collisions with other stairs on the current level.
let active_layout = &self.levels[self.settings.active_level_index];
if active_layout.rooms.iter().any(|room| {
rects_overlap(
new_stair_cell.0,
new_stair_cell.1,
new_stair_width,
new_stair_height,
room.x,
room.y,
room.width,
room.height,
)
}) {
return;
}
if active_layout.stairs.iter().enumerate().any(|(idx, stair)| {
idx != state.stair_idx
&& rects_overlap(
@@ -1903,15 +1896,36 @@ impl DungeonApp {
}
let layout = &self.levels[self.settings.active_level_index];
if let Some(text_idx) = self
.resize_state
.as_ref()
.and_then(|s| match s {
ResizeState::Text(state) => Some(state.text_idx),
_ => None,
})
.or(self.hover_text_idx)
{
// 1. Check active ResizeState first to lock visual feedback to the being-resized object.
if let Some(state) = &self.resize_state {
match state {
ResizeState::Text(state) => {
if let Some(label) = layout.text_labels.get(state.text_idx) {
let rect = text_label_rect(geometry, label).expand(3.0);
painter.rect_stroke(
rect,
0.0,
Stroke::new(2.0, Color32::from_gray(180)),
egui::StrokeKind::Middle,
);
}
}
ResizeState::Room(state) => {
if let Some(room) = layout.rooms.get(state.room_idx) {
self.draw_room_resize_visuals(painter, geometry, room, true);
}
}
ResizeState::Staircase(state) => {
if let Some(stair) = layout.stairs.get(state.stair_idx) {
self.draw_staircase_resize_visuals(painter, geometry, stair, true);
}
}
}
return;
}
// 2. Fall back to hover state if not resizing.
if let Some(text_idx) = self.hover_text_idx {
if let Some(label) = layout.text_labels.get(text_idx) {
let rect = text_label_rect(geometry, label).expand(3.0);
painter.rect_stroke(
@@ -1920,21 +1934,25 @@ impl DungeonApp {
Stroke::new(2.0, Color32::from_gray(180)),
egui::StrokeKind::Middle,
);
return;
}
}
let room_idx = self
.resize_state
.as_ref()
.and_then(|s| match s {
ResizeState::Room(state) => Some(state.room_idx),
_ => None,
})
.or(self.hover_room_idx);
if let Some(room_idx) = room_idx {
} else if let Some(room_idx) = self.hover_room_idx {
if let Some(room) = layout.rooms.get(room_idx) {
self.draw_room_resize_visuals(painter, geometry, room, false);
}
} else if let Some(stair_idx) = self.hover_stair_idx {
if let Some(stair) = layout.stairs.get(stair_idx) {
self.draw_staircase_resize_visuals(painter, geometry, stair, false);
}
}
}
fn draw_room_resize_visuals(
&self,
painter: &egui::Painter,
geometry: &GridGeometry,
room: &layout::Room,
show_handles: bool,
) {
let color = Color32::from_gray(170);
let stroke = Stroke::new(1.5, color);
@@ -1965,27 +1983,21 @@ impl DungeonApp {
);
painter.text(center_left, egui::Align2::CENTER_CENTER, "^v", font, color);
if matches!(self.resize_state, Some(ResizeState::Room(_))) {
if show_handles {
draw_resize_handle(painter, tl, ResizeCorner::TopLeft, color);
draw_resize_handle(painter, tr, ResizeCorner::TopRight, color);
draw_resize_handle(painter, br, ResizeCorner::BottomRight, color);
draw_resize_handle(painter, bl, ResizeCorner::BottomLeft, color);
}
return;
}
}
let stair_idx = self
.resize_state
.as_ref()
.and_then(|s| match s {
ResizeState::Staircase(state) => Some(state.stair_idx),
_ => None,
})
.or(self.hover_stair_idx);
if let Some(stair_idx) = stair_idx {
if let Some(stair) = layout.stairs.get(stair_idx) {
fn draw_staircase_resize_visuals(
&self,
painter: &egui::Painter,
geometry: &GridGeometry,
stair: &layout::Staircase,
show_handles: bool,
) {
let color = Color32::from_gray(170);
let stroke = Stroke::new(1.5, color);
@@ -2004,15 +2016,13 @@ impl DungeonApp {
draw_dashed_line(painter, br, bl, stroke, 6.0, 6.0);
draw_dashed_line(painter, bl, tl, stroke, 6.0, 6.0);
if matches!(self.resize_state, Some(ResizeState::Staircase(_))) {
if show_handles {
draw_resize_handle(painter, tl, ResizeCorner::TopLeft, color);
draw_resize_handle(painter, tr, ResizeCorner::TopRight, color);
draw_resize_handle(painter, br, ResizeCorner::BottomRight, color);
draw_resize_handle(painter, bl, ResizeCorner::BottomLeft, color);
}
}
}
}
// Draw a dashed overlay along the hovered corridor path.
fn draw_corridor_hover_overlay(&self, painter: &egui::Painter, geometry: &GridGeometry) {