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);
match state {
ResizeState::Room(state) => resize_room(app, &state, cell),
ResizeState::Text(state) => resize_text(app, &state, cell),
ResizeState::Staircase(state) => resize_staircase(app, &state, cell),
ResizeState::Room(ref state) => update_room_ghost(app, state, cell),
ResizeState::Text(ref state) => update_text_ghost(app, state, cell),
ResizeState::Staircase(ref state) => update_staircase_ghost(app, state, cell),
}
}
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;
}
return true;
@@ -85,6 +90,7 @@ pub fn start_text_resize(app: &DungeonApp, text_idx: usize) -> Option<TextResize
text_idx,
origin_cell: label.cell,
original_font_size: label.font_size,
current_font_size: label.font_size,
})
}
@@ -116,7 +122,8 @@ pub fn start_resize(
Some(RoomResizeState {
room_idx,
original_room,
original_room: original_room.clone(),
current_room: original_room,
resize_corner,
})
}
@@ -149,18 +156,18 @@ pub fn start_staircase_resize(
Some(StaircaseResizeState {
stair_idx,
original_stair,
original_stair: original_stair.clone(),
current_stair: original_stair,
resize_corner,
})
}
// Resizes a room and reroutes affected corridors.
pub fn resize_room(app: &mut DungeonApp, state: &RoomResizeState, target_cell: (usize, usize)) {
if app.settings.active_level_index >= app.levels.len() {
return;
}
let layout = &mut app.levels[app.settings.active_level_index];
// Updates room ghost dimensions during resize.
pub fn update_room_ghost(
app: &mut DungeonApp,
state: &RoomResizeState,
target_cell: (usize, usize),
) {
let cols = app.settings.cols.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;
}
if let Some(layout) = app.levels.get(app.settings.active_level_index) {
if layout
.rooms
.iter()
@@ -202,46 +210,65 @@ pub fn resize_room(app: &mut DungeonApp, state: &RoomResizeState, target_cell: (
{
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.y = new_room.y;
room.width = new_room.width;
room.height = new_room.height;
reroute_corridors_for_room(app, state.room_idx);
reroute_corridors_for_room(app, room_idx);
app.refresh_doors();
}
}
// Resizes a text label based on the drag target cell.
pub fn resize_text(app: &mut DungeonApp, state: &TextResizeState, target_cell: (usize, usize)) {
if app.settings.active_level_index >= app.levels.len() {
return;
}
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;
};
// Updates text ghost font size.
pub fn update_text_ghost(
app: &mut DungeonApp,
state: &TextResizeState,
target_cell: (usize, usize),
) {
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 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);
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.
pub fn resize_staircase(
// Applies final text resize.
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,
state: &StaircaseResizeState,
target_cell: (usize, usize),
) {
if app.settings.active_level_index >= app.levels.len() {
return;
}
let cols = app.settings.cols.max(1);
let rows = app.settings.rows.max(1);
@@ -269,7 +296,7 @@ pub fn resize_staircase(
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)| {
idx != state.stair_idx
&& rects_overlap(
@@ -285,6 +312,20 @@ pub fn resize_staircase(
}) {
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 {
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.
@@ -338,24 +373,56 @@ pub fn draw_resize_overlay(app: &DungeonApp, painter: &egui::Painter, geometry:
match state {
ResizeState::Text(state) => {
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(
rect,
0.0,
Stroke::new(2.0, Color32::from_gray(180)),
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) => {
if let Some(room) = layout.rooms.get(state.room_idx) {
draw_room_resize_visuals(painter, geometry, room, true);
}
crate::rendering::draw_layout(
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) => {
if let Some(stair) = layout.stairs.get(state.stair_idx) {
draw_staircase_resize_visuals(painter, geometry, stair, true);
}
crate::rendering::draw_staircase(
painter,
geometry,
&state.current_stair,
app.settings.colorblind_mode,
false,
0.5,
);
draw_staircase_resize_visuals(painter, geometry, &state.current_stair, true);
}
}
return;
+3
View File
@@ -73,6 +73,7 @@ pub enum HoverMarker {
pub struct RoomResizeState {
pub room_idx: usize,
pub original_room: layout::Room,
pub current_room: layout::Room,
pub resize_corner: ResizeCorner,
}
@@ -98,12 +99,14 @@ pub struct TextResizeState {
pub text_idx: usize,
pub origin_cell: (usize, usize),
pub original_font_size: u16,
pub current_font_size: u16,
}
#[derive(Debug, Clone)]
pub struct StaircaseResizeState {
pub stair_idx: usize,
pub original_stair: layout::Staircase,
pub current_stair: layout::Staircase,
pub resize_corner: ResizeCorner,
}