diff --git a/crates/egui/src/containers/area.rs b/crates/egui/src/containers/area.rs index 33e3fae9783..07f9b3a06ab 100644 --- a/crates/egui/src/containers/area.rs +++ b/crates/egui/src/containers/area.rs @@ -228,7 +228,7 @@ impl Area { self } - /// Constrains this area to the screen bounds. + /// Constrains this area to [`Context::screen_rect`]? #[inline] pub fn constrain(mut self, constrain: bool) -> Self { self.constrain = constrain; @@ -306,7 +306,7 @@ pub(crate) struct Prepared { move_response: Response, enabled: bool, constrain: bool, - constrain_rect: Option, + constrain_rect: Rect, /// We always make windows invisible the first frame to hide "first-frame-jitters". /// @@ -349,6 +349,8 @@ impl Area { fade_in, } = self; + let constrain_rect = constrain_rect.unwrap_or_else(|| ctx.screen_rect()); + let layer_id = LayerId::new(order, id); let state = AreaState::load(ctx, id).map(|mut state| { @@ -373,7 +375,6 @@ impl Area { } if constrain { - let constrain_rect = constrain_rect.unwrap_or_else(|| ctx.screen_rect()); size = size.at_most(constrain_rect.size()); } @@ -396,9 +397,11 @@ impl Area { } if let Some((anchor, offset)) = anchor { - let screen = ctx.available_rect(); state.set_left_top_pos( - anchor.align_size_within_rect(state.size, screen).left_top() + offset, + anchor + .align_size_within_rect(state.size, constrain_rect) + .left_top() + + offset, ); } @@ -478,29 +481,14 @@ impl Prepared { self.constrain } - pub(crate) fn constrain_rect(&self) -> Option { + pub(crate) fn constrain_rect(&self) -> Rect { self.constrain_rect } pub(crate) fn content_ui(&self, ctx: &Context) -> Ui { - let screen_rect = ctx.screen_rect(); - - let constrain_rect = if let Some(constrain_rect) = self.constrain_rect { - constrain_rect.intersect(screen_rect) // protect against infinite bounds - } else { - let central_area = ctx.available_rect(); - - let is_within_central_area = central_area.contains_rect(self.state.rect().shrink(1.0)); - if is_within_central_area { - central_area // let's try to not cover side panels - } else { - screen_rect - } - }; - let max_rect = Rect::from_min_size(self.state.left_top_pos(), self.state.size); - let clip_rect = constrain_rect; // Don't paint outside our bounds + let clip_rect = self.constrain_rect; // Don't paint outside our bounds let mut ui = Ui::new( ctx.clone(), @@ -563,6 +551,8 @@ fn automatic_area_position(ctx: &Context) -> Pos2 { }); existing.sort_by_key(|r| r.left().round() as i32); + // NOTE: for the benefit of the egui demo, we position the windows so they don't + // cover the side panels, which means we use `available_rect` here instead of `constrain_rect` or `screen_rect`. let available_rect = ctx.available_rect(); let spacing = 16.0; diff --git a/crates/egui/src/containers/window.rs b/crates/egui/src/containers/window.rs index cc6cea3f9e3..2a9b676638b 100644 --- a/crates/egui/src/containers/window.rs +++ b/crates/egui/src/containers/window.rs @@ -220,7 +220,7 @@ impl<'open> Window<'open> { self } - /// Constrains this window to the screen bounds. + /// Constrains this window to [`Context::screen_rect`]. /// /// To change the area to constrain to, use [`Self::constrain_to`]. /// @@ -471,11 +471,10 @@ impl<'open> Window<'open> { }; { - // Prevent window from becoming larger than the constraint rect and/or screen rect. - let screen_rect = ctx.screen_rect(); - let max_rect = area.constrain_rect().unwrap_or(screen_rect); - let max_width = max_rect.width(); - let max_height = max_rect.height() - title_bar_height; + // Prevent window from becoming larger than the constrain rect. + let constrain_rect = area.constrain_rect(); + let max_width = constrain_rect.width(); + let max_height = constrain_rect.height() - title_bar_height; resize.max_size.x = resize.max_size.x.min(max_width); resize.max_size.y = resize.max_size.y.min(max_height); } diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 9884de41fff..9471349999c 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -1776,23 +1776,7 @@ impl Context { // --------------------------------------------------------------------- /// Constrain the position of a window/area so it fits within the provided boundary. - /// - /// If area is `None`, will constrain to [`Self::available_rect`]. - pub(crate) fn constrain_window_rect_to_area(&self, window: Rect, area: Option) -> Rect { - let mut area = area.unwrap_or_else(|| self.available_rect()); - - if window.width() > area.width() { - // Allow overlapping side bars. - // This is important for small screens, e.g. mobiles running the web demo. - let screen_rect = self.screen_rect(); - (area.min.x, area.max.x) = (screen_rect.min.x, screen_rect.max.x); - } - if window.height() > area.height() { - // Allow overlapping top/bottom bars: - let screen_rect = self.screen_rect(); - (area.min.y, area.max.y) = (screen_rect.min.y, screen_rect.max.y); - } - + pub(crate) fn constrain_window_rect_to_area(&self, window: Rect, area: Rect) -> Rect { let mut pos = window.min; // Constrain to screen, unless window is too large to fit: