added a ghosts for resizing

This commit is contained in:
grimsace
2026-05-21 10:08:16 -05:00
parent ef5a0d4952
commit 336a91fbe9
2 changed files with 138 additions and 68 deletions
+114 -47
View File
@@ -58,13 +58,18 @@ pub fn handle_resize(
{ {
let cell = (grid_x.floor() as usize, grid_y.floor() as usize); let cell = (grid_x.floor() as usize, grid_y.floor() as usize);
match state { match state {
ResizeState::Room(state) => resize_room(app, &state, cell), ResizeState::Room(ref state) => update_room_ghost(app, state, cell),
ResizeState::Text(state) => resize_text(app, &state, cell), ResizeState::Text(ref state) => update_text_ghost(app, state, cell),
ResizeState::Staircase(state) => resize_staircase(app, &state, cell), ResizeState::Staircase(ref state) => update_staircase_ghost(app, state, cell),
} }
} }
if ctx.input(|i| i.pointer.button_released(egui::PointerButton::Secondary)) { if ctx.input(|i| i.pointer.button_released(egui::PointerButton::Secondary)) {
match state {
ResizeState::Room(ref state) => apply_room_resize(app, state),
ResizeState::Text(ref state) => apply_text_resize(app, state),
ResizeState::Staircase(ref state) => apply_staircase_resize(app, state),
}
app.resize_state = None; app.resize_state = None;
} }
return true; return true;
@@ -85,6 +90,7 @@ pub fn start_text_resize(app: &DungeonApp, text_idx: usize) -> Option<TextResize
text_idx, text_idx,
origin_cell: label.cell, origin_cell: label.cell,
original_font_size: label.font_size, original_font_size: label.font_size,
current_font_size: label.font_size,
}) })
} }
@@ -116,7 +122,8 @@ pub fn start_resize(
Some(RoomResizeState { Some(RoomResizeState {
room_idx, room_idx,
original_room, original_room: original_room.clone(),
current_room: original_room,
resize_corner, resize_corner,
}) })
} }
@@ -149,18 +156,18 @@ pub fn start_staircase_resize(
Some(StaircaseResizeState { Some(StaircaseResizeState {
stair_idx, stair_idx,
original_stair, original_stair: original_stair.clone(),
current_stair: original_stair,
resize_corner, resize_corner,
}) })
} }
// Resizes a room and reroutes affected corridors. // Updates room ghost dimensions during resize.
pub fn resize_room(app: &mut DungeonApp, state: &RoomResizeState, target_cell: (usize, usize)) { pub fn update_room_ghost(
if app.settings.active_level_index >= app.levels.len() { app: &mut DungeonApp,
return; state: &RoomResizeState,
} target_cell: (usize, usize),
let layout = &mut app.levels[app.settings.active_level_index]; ) {
let cols = app.settings.cols.max(1); let cols = app.settings.cols.max(1);
let rows = app.settings.rows.max(1); let rows = app.settings.rows.max(1);
@@ -194,6 +201,7 @@ pub fn resize_room(app: &mut DungeonApp, state: &RoomResizeState, target_cell: (
return; return;
} }
if let Some(layout) = app.levels.get(app.settings.active_level_index) {
if layout if layout
.rooms .rooms
.iter() .iter()
@@ -202,46 +210,65 @@ pub fn resize_room(app: &mut DungeonApp, state: &RoomResizeState, target_cell: (
{ {
return; return;
} }
}
if let Some(room) = layout.rooms.get_mut(state.room_idx) { if let Some(ResizeState::Room(ref mut s)) = app.resize_state {
s.current_room = new_room;
}
}
// Applies final room resize.
pub fn apply_room_resize(app: &mut DungeonApp, state: &RoomResizeState) {
if app.settings.active_level_index >= app.levels.len() {
return;
}
let room_idx = state.room_idx;
let new_room = state.current_room.clone();
let layout = &mut app.levels[app.settings.active_level_index];
if let Some(room) = layout.rooms.get_mut(room_idx) {
room.x = new_room.x; room.x = new_room.x;
room.y = new_room.y; room.y = new_room.y;
room.width = new_room.width; room.width = new_room.width;
room.height = new_room.height; room.height = new_room.height;
reroute_corridors_for_room(app, state.room_idx); reroute_corridors_for_room(app, room_idx);
app.refresh_doors(); app.refresh_doors();
} }
} }
// Resizes a text label based on the drag target cell. // Updates text ghost font size.
pub fn resize_text(app: &mut DungeonApp, state: &TextResizeState, target_cell: (usize, usize)) { pub fn update_text_ghost(
if app.settings.active_level_index >= app.levels.len() { app: &mut DungeonApp,
return; state: &TextResizeState,
} target_cell: (usize, usize),
let layout = &mut app.levels[app.settings.active_level_index]; ) {
let Some(label) = layout.text_labels.get_mut(state.text_idx) else {
app.resize_state = None;
return;
};
let dx = target_cell.0 as isize - state.origin_cell.0 as isize; let dx = target_cell.0 as isize - state.origin_cell.0 as isize;
let dy = target_cell.1 as isize - state.origin_cell.1 as isize; let dy = target_cell.1 as isize - state.origin_cell.1 as isize;
let delta_cells = if dx.abs() >= dy.abs() { dx } else { -dy }; let delta_cells = if dx.abs() >= dy.abs() { dx } else { -dy };
let new_size = (state.original_font_size as isize + (delta_cells * 4)).clamp(8, 96); let new_size = (state.original_font_size as isize + (delta_cells * 4)).clamp(8, 96);
label.font_size = new_size as u16;
if let Some(ResizeState::Text(ref mut s)) = app.resize_state {
s.current_font_size = new_size as u16;
}
} }
// Resizes a staircase while clamping it to the grid. // Applies final text resize.
pub fn resize_staircase( pub fn apply_text_resize(app: &mut DungeonApp, state: &TextResizeState) {
if app.settings.active_level_index >= app.levels.len() {
return;
}
let layout = &mut app.levels[app.settings.active_level_index];
if let Some(label) = layout.text_labels.get_mut(state.text_idx) {
label.font_size = state.current_font_size;
}
}
// Updates staircase ghost dimensions.
pub fn update_staircase_ghost(
app: &mut DungeonApp, app: &mut DungeonApp,
state: &StaircaseResizeState, state: &StaircaseResizeState,
target_cell: (usize, usize), target_cell: (usize, usize),
) { ) {
if app.settings.active_level_index >= app.levels.len() {
return;
}
let cols = app.settings.cols.max(1); let cols = app.settings.cols.max(1);
let rows = app.settings.rows.max(1); let rows = app.settings.rows.max(1);
@@ -269,7 +296,7 @@ pub fn resize_staircase(
return; return;
} }
let active_layout = &app.levels[app.settings.active_level_index]; if let Some(active_layout) = app.levels.get(app.settings.active_level_index) {
if active_layout.stairs.iter().enumerate().any(|(idx, stair)| { if active_layout.stairs.iter().enumerate().any(|(idx, stair)| {
idx != state.stair_idx idx != state.stair_idx
&& rects_overlap( && rects_overlap(
@@ -285,6 +312,20 @@ pub fn resize_staircase(
}) { }) {
return; return;
} }
}
if let Some(ResizeState::Staircase(ref mut s)) = app.resize_state {
s.current_stair.cell = new_stair_cell;
s.current_stair.width = new_stair_width;
s.current_stair.height = new_stair_height;
}
}
// Applies final staircase resize.
pub fn apply_staircase_resize(app: &mut DungeonApp, state: &StaircaseResizeState) {
let new_stair_cell = state.current_stair.cell;
let new_stair_width = state.current_stair.width;
let new_stair_height = state.current_stair.height;
if app.settings.sync_stairs_across_levels { if app.settings.sync_stairs_across_levels {
for layout in &mut app.levels { for layout in &mut app.levels {
@@ -319,12 +360,6 @@ pub fn resize_staircase(
} }
} }
} }
if let Some(ResizeState::Staircase(ref mut s)) = app.resize_state {
s.original_stair.cell = new_stair_cell;
s.original_stair.width = new_stair_width;
s.original_stair.height = new_stair_height;
}
} }
// Draws resize overlay. // Draws resize overlay.
@@ -338,24 +373,56 @@ pub fn draw_resize_overlay(app: &DungeonApp, painter: &egui::Painter, geometry:
match state { match state {
ResizeState::Text(state) => { ResizeState::Text(state) => {
if let Some(label) = layout.text_labels.get(state.text_idx) { if let Some(label) = layout.text_labels.get(state.text_idx) {
let rect = crate::rendering::text_label_rect(geometry, label).expand(3.0); let mut ghost_label = label.clone();
ghost_label.font_size = state.current_font_size;
let rect =
crate::rendering::text_label_rect(geometry, &ghost_label).expand(3.0);
painter.rect_stroke( painter.rect_stroke(
rect, rect,
0.0, 0.0,
Stroke::new(2.0, Color32::from_gray(180)), Stroke::new(2.0, Color32::from_gray(180)),
egui::StrokeKind::Middle, egui::StrokeKind::Middle,
); );
let pos = crate::interact::cell_center(
geometry,
ghost_label.cell.0,
ghost_label.cell.1,
);
painter.text(
pos,
egui::Align2::CENTER_CENTER,
&ghost_label.text,
egui::FontId::proportional(ghost_label.font_size as f32),
Color32::from_gray(200).gamma_multiply(0.5),
);
} }
} }
ResizeState::Room(state) => { ResizeState::Room(state) => {
if let Some(room) = layout.rooms.get(state.room_idx) { crate::rendering::draw_layout(
draw_room_resize_visuals(painter, geometry, room, true); painter,
} geometry,
&crate::layout::DungeonLayout {
rooms: vec![state.current_room.clone()],
..crate::layout::DungeonLayout::empty(false)
},
app.settings.colorblind_mode,
None,
None,
None,
0.5,
);
draw_room_resize_visuals(painter, geometry, &state.current_room, true);
} }
ResizeState::Staircase(state) => { ResizeState::Staircase(state) => {
if let Some(stair) = layout.stairs.get(state.stair_idx) { crate::rendering::draw_staircase(
draw_staircase_resize_visuals(painter, geometry, stair, true); painter,
} geometry,
&state.current_stair,
app.settings.colorblind_mode,
false,
0.5,
);
draw_staircase_resize_visuals(painter, geometry, &state.current_stair, true);
} }
} }
return; return;
+3
View File
@@ -73,6 +73,7 @@ pub enum HoverMarker {
pub struct RoomResizeState { pub struct RoomResizeState {
pub room_idx: usize, pub room_idx: usize,
pub original_room: layout::Room, pub original_room: layout::Room,
pub current_room: layout::Room,
pub resize_corner: ResizeCorner, pub resize_corner: ResizeCorner,
} }
@@ -98,12 +99,14 @@ pub struct TextResizeState {
pub text_idx: usize, pub text_idx: usize,
pub origin_cell: (usize, usize), pub origin_cell: (usize, usize),
pub original_font_size: u16, pub original_font_size: u16,
pub current_font_size: u16,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct StaircaseResizeState { pub struct StaircaseResizeState {
pub stair_idx: usize, pub stair_idx: usize,
pub original_stair: layout::Staircase, pub original_stair: layout::Staircase,
pub current_stair: layout::Staircase,
pub resize_corner: ResizeCorner, pub resize_corner: ResizeCorner,
} }