Fixed color edit popup going outside the screen (#2270)

* Fixed color edit popup going outside the screen

* Added option to constrain areas

* Constrain color picker area

* Constrain popups

* Updated changelog
This commit is contained in:
ItsEthra 2022-11-11 16:09:54 +03:00 committed by GitHub
parent 8ff139687a
commit f790e248e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 23 additions and 1 deletions

View file

@ -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)). * 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)). * 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`. * Add `ui.centered`.
* Added `Area::constrain` which constrains area to the screen bounds. ([#2270](https://github.com/emilk/egui/pull/2270)).
### Changed 🔧 ### 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)). * 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)).
@ -27,6 +28,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)). * ⚠️ 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)). * 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)). * 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 ## 0.19.0 - 2022-08-20

View file

@ -46,6 +46,7 @@ pub struct Area {
movable: bool, movable: bool,
interactable: bool, interactable: bool,
enabled: bool, enabled: bool,
constrain: bool,
order: Order, order: Order,
default_pos: Option<Pos2>, default_pos: Option<Pos2>,
anchor: Option<(Align2, Vec2)>, anchor: Option<(Align2, Vec2)>,
@ -59,6 +60,7 @@ impl Area {
id: id.into(), id: id.into(),
movable: true, movable: true,
interactable: true, interactable: true,
constrain: false,
enabled: true, enabled: true,
order: Order::Middle, order: Order::Middle,
default_pos: None, default_pos: None,
@ -120,6 +122,12 @@ impl Area {
self 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 /// Positions the window and prevents it from being moved
pub fn fixed_pos(mut self, fixed_pos: impl Into<Pos2>) -> Self { pub fn fixed_pos(mut self, fixed_pos: impl Into<Pos2>) -> Self {
self.new_pos = Some(fixed_pos.into()); self.new_pos = Some(fixed_pos.into());
@ -202,6 +210,7 @@ impl Area {
new_pos, new_pos,
anchor, anchor,
drag_bounds, drag_bounds,
constrain,
} = self; } = self;
let layer_id = LayerId::new(order, id); let layer_id = LayerId::new(order, id);
@ -274,6 +283,12 @@ impl Area {
state.pos = ctx.round_pos_to_pixels(state.pos); 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 { Prepared {
layer_id, layer_id,
state, state,

View file

@ -325,6 +325,7 @@ pub fn popup_below_widget<R>(
if ui.memory().is_popup_open(popup_id) { if ui.memory().is_popup_open(popup_id) {
let inner = Area::new(popup_id) let inner = Area::new(popup_id)
.order(Order::Foreground) .order(Order::Foreground)
.constrain(true)
.fixed_pos(widget_response.rect.left_bottom()) .fixed_pos(widget_response.rect.left_bottom())
.show(ui.ctx(), |ui| { .show(ui.ctx(), |ui| {
// Note: we use a separate clip-rect for this area, so the popup can be outside the parent. // Note: we use a separate clip-rect for this area, so the popup can be outside the parent.

View file

@ -350,13 +350,17 @@ pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Res
if button_response.clicked() { if button_response.clicked() {
ui.memory().toggle_popup(popup_id); ui.memory().toggle_popup(popup_id);
} }
const COLOR_SLIDER_WIDTH: f32 = 210.0;
// TODO(emilk): make it easier to show a temporary popup that closes when you click outside it // 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) { if ui.memory().is_popup_open(popup_id) {
let area_response = Area::new(popup_id) let area_response = Area::new(popup_id)
.order(Order::Foreground) .order(Order::Foreground)
.fixed_pos(button_response.rect.max) .fixed_pos(button_response.rect.max)
.constrain(true)
.show(ui.ctx(), |ui| { .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| { Frame::popup(ui.style()).show(ui, |ui| {
if color_picker_hsva_2d(ui, hsva, alpha) { if color_picker_hsva_2d(ui, hsva, alpha) {
button_response.mark_changed(); button_response.mark_changed();