From 0ab82bd85c7128a977286a89d64d0b694e68ea2e Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Sat, 30 Mar 2024 10:54:32 +0100 Subject: [PATCH] Change the resize cursor when you reach the resize limit (#4275) For panels and `DragValue`: if you cannot resize more in one direction, reflect that in the choice of mouse cursor ![resize-cursor-2](https://github.com/emilk/egui/assets/1148717/f95176d3-eab9-48cf-b7bd-3182312551d9) --- crates/egui/src/containers/panel.rs | 40 ++++++++++++++++++--------- crates/egui/src/containers/window.rs | 1 + crates/egui/src/widgets/drag_value.rs | 12 ++++++-- 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/crates/egui/src/containers/panel.rs b/crates/egui/src/containers/panel.rs index 11e69b8289cb..27be59996d42 100644 --- a/crates/egui/src/containers/panel.rs +++ b/crates/egui/src/containers/panel.rs @@ -228,8 +228,8 @@ impl SidePanel { let available_rect = ui.available_rect_before_wrap(); let mut panel_rect = available_rect; + let mut width = default_width; { - let mut width = default_width; if let Some(state) = PanelState::load(ui.ctx(), id) { width = state.rect.width(); } @@ -249,9 +249,8 @@ impl SidePanel { if is_resizing { if let Some(pointer) = resize_response.interact_pointer_pos() { - let width = (pointer.x - side.side_x(panel_rect)).abs(); - let width = - clamp_to_range(width, width_range).at_most(available_rect.width()); + width = (pointer.x - side.side_x(panel_rect)).abs(); + width = clamp_to_range(width, width_range).at_most(available_rect.width()); side.set_rect_width(&mut panel_rect, width); } } @@ -296,7 +295,14 @@ impl SidePanel { } if resize_hover || is_resizing { - ui.ctx().set_cursor_icon(CursorIcon::ResizeHorizontal); + let cursor_icon = if width <= width_range.min { + CursorIcon::ResizeEast + } else if width < width_range.max { + CursorIcon::ResizeHorizontal + } else { + CursorIcon::ResizeWest + }; + ui.ctx().set_cursor_icon(cursor_icon); } PanelState { rect }.store(ui.ctx(), id); @@ -684,12 +690,13 @@ impl TopBottomPanel { let available_rect = ui.available_rect_before_wrap(); let mut panel_rect = available_rect; + + let mut height = if let Some(state) = PanelState::load(ui.ctx(), id) { + state.rect.height() + } else { + default_height.unwrap_or_else(|| ui.style().spacing.interact_size.y) + }; { - let mut height = if let Some(state) = PanelState::load(ui.ctx(), id) { - state.rect.height() - } else { - default_height.unwrap_or_else(|| ui.style().spacing.interact_size.y) - }; height = clamp_to_range(height, height_range).at_most(available_rect.height()); side.set_rect_height(&mut panel_rect, height); ui.ctx() @@ -707,8 +714,8 @@ impl TopBottomPanel { if is_resizing { if let Some(pointer) = resize_response.interact_pointer_pos() { - let height = (pointer.y - side.side_y(panel_rect)).abs(); - let height = + height = (pointer.y - side.side_y(panel_rect)).abs(); + height = clamp_to_range(height, height_range).at_most(available_rect.height()); side.set_rect_height(&mut panel_rect, height); } @@ -755,7 +762,14 @@ impl TopBottomPanel { } if resize_hover || is_resizing { - ui.ctx().set_cursor_icon(CursorIcon::ResizeVertical); + let cursor_icon = if height <= height_range.min { + CursorIcon::ResizeSouth + } else if height < height_range.max { + CursorIcon::ResizeVertical + } else { + CursorIcon::ResizeNorth + }; + ui.ctx().set_cursor_icon(cursor_icon); } PanelState { rect }.store(ui.ctx(), id); diff --git a/crates/egui/src/containers/window.rs b/crates/egui/src/containers/window.rs index af6f6b16c312..619675ca8a55 100644 --- a/crates/egui/src/containers/window.rs +++ b/crates/egui/src/containers/window.rs @@ -697,6 +697,7 @@ impl ResizeInteraction { let top = self.top.any(); let bottom = self.bottom.any(); + // TODO(emilk): use one-sided cursors for when we reached the min/max size. if (left && top) || (right && bottom) { ctx.set_cursor_icon(CursorIcon::ResizeNwSe); } else if (right && top) || (left && bottom) { diff --git a/crates/egui/src/widgets/drag_value.rs b/crates/egui/src/widgets/drag_value.rs index f0875ba30553..8a7f19028b66 100644 --- a/crates/egui/src/widgets/drag_value.rs +++ b/crates/egui/src/widgets/drag_value.rs @@ -525,8 +525,16 @@ impl<'a> Widget for DragValue<'a> { .sense(Sense::click_and_drag()) .min_size(ui.spacing().interact_size); // TODO(emilk): find some more generic solution to `min_size` + let cursor_icon = if value <= *clamp_range.start() { + CursorIcon::ResizeEast + } else if value < *clamp_range.end() { + CursorIcon::ResizeHorizontal + } else { + CursorIcon::ResizeWest + }; + let response = ui.add(button); - let mut response = response.on_hover_cursor(CursorIcon::ResizeHorizontal); + let mut response = response.on_hover_cursor(cursor_icon); if ui.style().explanation_tooltips { response = response.on_hover_text(format!( @@ -552,7 +560,7 @@ impl<'a> Widget for DragValue<'a> { ))); state.store(ui.ctx(), response.id); } else if response.dragged() { - ui.ctx().set_cursor_icon(CursorIcon::ResizeHorizontal); + ui.ctx().set_cursor_icon(cursor_icon); let mdelta = response.drag_delta(); let delta_points = mdelta.x - mdelta.y; // Increase to the right and up