From 15b433732687f344c39f378aae9fe74236476ba3 Mon Sep 17 00:00:00 2001 From: ItsEthra <107059409+ItsEthra@users.noreply.github.com> Date: Wed, 9 Nov 2022 11:08:52 +0300 Subject: [PATCH 1/5] Fixed color edit popup going outside the screen --- crates/egui/src/widgets/color_picker.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/crates/egui/src/widgets/color_picker.rs b/crates/egui/src/widgets/color_picker.rs index 36231efedc90..80d9c41f389c 100644 --- a/crates/egui/src/widgets/color_picker.rs +++ b/crates/egui/src/widgets/color_picker.rs @@ -350,13 +350,29 @@ pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Res if button_response.clicked() { ui.memory().toggle_popup(popup_id); } + + const COLOR_SLIDER_WIDTH: f32 = 210.0; + // TODO(ItsEthra): find a more precise way to evaluate color edit popup height + const WIDTH_TO_HIGHT: f32 = 1.3666667; + + let screen_max = ui.input().screen_rect.max; + let mut anchor_pos = button_response.rect.max; + + if anchor_pos.x + COLOR_SLIDER_WIDTH > screen_max.x { + anchor_pos.x = screen_max.x - COLOR_SLIDER_WIDTH - ui.spacing().window_margin.right * 2.; + } + + if anchor_pos.y + COLOR_SLIDER_WIDTH * WIDTH_TO_HIGHT > screen_max.y { + anchor_pos.y = screen_max.y - COLOR_SLIDER_WIDTH * WIDTH_TO_HIGHT; + } + // TODO(emilk): make it easier to show a temporary popup that closes when you click outside it if ui.memory().is_popup_open(popup_id) { let area_response = Area::new(popup_id) .order(Order::Foreground) - .fixed_pos(button_response.rect.max) + .fixed_pos(anchor_pos) .show(ui.ctx(), |ui| { - ui.spacing_mut().slider_width = 210.0; + ui.spacing_mut().slider_width = COLOR_SLIDER_WIDTH; Frame::popup(ui.style()).show(ui, |ui| { if color_picker_hsva_2d(ui, hsva, alpha) { button_response.mark_changed(); From acfa78c3bf8a26f6c823d992177cfcfeaa3b7a16 Mon Sep 17 00:00:00 2001 From: ItsEthra <107059409+ItsEthra@users.noreply.github.com> Date: Thu, 10 Nov 2022 00:30:37 +0300 Subject: [PATCH 2/5] Added option to constrain areas --- crates/egui/src/containers/area.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crates/egui/src/containers/area.rs b/crates/egui/src/containers/area.rs index 17ecea5ba544..d42b5a3c8e94 100644 --- a/crates/egui/src/containers/area.rs +++ b/crates/egui/src/containers/area.rs @@ -48,6 +48,7 @@ pub struct Area { movable: bool, interactable: bool, enabled: bool, + constrain: bool, order: Order, default_pos: Option, anchor: Option<(Align2, Vec2)>, @@ -61,6 +62,7 @@ impl Area { id: Id::new(id_source), movable: true, interactable: true, + constrain: false, enabled: true, order: Order::Middle, default_pos: None, @@ -122,6 +124,12 @@ impl Area { self } + /// Constrains this area to the screen bounds. + pub fn constrain(mut self, constrain: bool) -> Self { + self.constrain = constrain; + self + } + /// Positions the window and prevents it from being moved pub fn fixed_pos(mut self, fixed_pos: impl Into) -> Self { self.new_pos = Some(fixed_pos.into()); @@ -204,6 +212,7 @@ impl Area { new_pos, anchor, drag_bounds, + constrain, } = self; let layer_id = LayerId::new(order, id); @@ -276,6 +285,12 @@ impl Area { state.pos = ctx.round_pos_to_pixels(state.pos); + if constrain { + state.pos = ctx + .constrain_window_rect_to_area(state.rect(), drag_bounds) + .min; + } + Prepared { layer_id, state, From 59ff2ea0a275c413e76794fb703ac0c4e78da586 Mon Sep 17 00:00:00 2001 From: ItsEthra <107059409+ItsEthra@users.noreply.github.com> Date: Thu, 10 Nov 2022 00:34:29 +0300 Subject: [PATCH 3/5] Constrain color picker area --- crates/egui/src/widgets/color_picker.rs | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/crates/egui/src/widgets/color_picker.rs b/crates/egui/src/widgets/color_picker.rs index 80d9c41f389c..a9935f4d5454 100644 --- a/crates/egui/src/widgets/color_picker.rs +++ b/crates/egui/src/widgets/color_picker.rs @@ -352,25 +352,13 @@ pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Res } const COLOR_SLIDER_WIDTH: f32 = 210.0; - // TODO(ItsEthra): find a more precise way to evaluate color edit popup height - const WIDTH_TO_HIGHT: f32 = 1.3666667; - - let screen_max = ui.input().screen_rect.max; - let mut anchor_pos = button_response.rect.max; - - if anchor_pos.x + COLOR_SLIDER_WIDTH > screen_max.x { - anchor_pos.x = screen_max.x - COLOR_SLIDER_WIDTH - ui.spacing().window_margin.right * 2.; - } - - if anchor_pos.y + COLOR_SLIDER_WIDTH * WIDTH_TO_HIGHT > screen_max.y { - anchor_pos.y = screen_max.y - COLOR_SLIDER_WIDTH * WIDTH_TO_HIGHT; - } // TODO(emilk): make it easier to show a temporary popup that closes when you click outside it if ui.memory().is_popup_open(popup_id) { let area_response = Area::new(popup_id) .order(Order::Foreground) - .fixed_pos(anchor_pos) + .fixed_pos(button_response.rect.max) + .constrain(true) .show(ui.ctx(), |ui| { ui.spacing_mut().slider_width = COLOR_SLIDER_WIDTH; Frame::popup(ui.style()).show(ui, |ui| { From ad2a03bf3f4a89cbec5fd5695e6d4849bdb982f3 Mon Sep 17 00:00:00 2001 From: ItsEthra <107059409+ItsEthra@users.noreply.github.com> Date: Thu, 10 Nov 2022 00:37:36 +0300 Subject: [PATCH 4/5] Constrain popups --- crates/egui/src/containers/popup.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/egui/src/containers/popup.rs b/crates/egui/src/containers/popup.rs index 9742ac43542c..5b391ed9bd7c 100644 --- a/crates/egui/src/containers/popup.rs +++ b/crates/egui/src/containers/popup.rs @@ -298,6 +298,7 @@ pub fn popup_below_widget( if ui.memory().is_popup_open(popup_id) { let inner = Area::new(popup_id) .order(Order::Foreground) + .constrain(true) .fixed_pos(widget_response.rect.left_bottom()) .show(ui.ctx(), |ui| { // Note: we use a separate clip-rect for this area, so the popup can be outside the parent. From 0771de1a1b40c5e7a958942e9eee04ff6fae719a Mon Sep 17 00:00:00 2001 From: ItsEthra <107059409+ItsEthra@users.noreply.github.com> Date: Fri, 11 Nov 2022 14:01:23 +0300 Subject: [PATCH 5/5] Updated changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b3cf0b8daa4..fb7b5521e07d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG * Added `egui::gui_zoom` module with helpers for scaling the whole GUI of an app ([#2239](https://github.com/emilk/egui/pull/2239)). * You can now put one interactive widget on top of another, and only one will get interaction at a time ([#2244](https://github.com/emilk/egui/pull/2244)). * Add `ui.centered`. +* Added `Area::constrain` which constrains area to the screen bounds. ([#2270](https://github.com/emilk/egui/pull/2270)). ### Changed 🔧 * Panels always have a separator line, but no stroke on other sides. Their spacing has also changed slightly ([#2261](https://github.com/emilk/egui/pull/2261)). @@ -26,6 +27,7 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG * ⚠️ BREAKING: Fix text being too small ([#2069](https://github.com/emilk/egui/pull/2069)). * Improved text rendering ([#2071](https://github.com/emilk/egui/pull/2071)). * Less jitter when calling `Context::set_pixels_per_point` ([#2239](https://github.com/emilk/egui/pull/2239)). +* Fixed popups and color edit going outside the screen. ## 0.19.0 - 2022-08-20