Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The default constrain rect for Area/Window is now ctx.screen_rect #4590

Merged
merged 1 commit into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 12 additions & 22 deletions crates/egui/src/containers/area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -306,7 +306,7 @@ pub(crate) struct Prepared {
move_response: Response,
enabled: bool,
constrain: bool,
constrain_rect: Option<Rect>,
constrain_rect: Rect,

/// We always make windows invisible the first frame to hide "first-frame-jitters".
///
Expand Down Expand Up @@ -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| {
Expand All @@ -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());
}

Expand All @@ -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,
);
}

Expand Down Expand Up @@ -478,29 +481,14 @@ impl Prepared {
self.constrain
}

pub(crate) fn constrain_rect(&self) -> Option<Rect> {
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(),
Expand Down Expand Up @@ -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;
Expand Down
11 changes: 5 additions & 6 deletions crates/egui/src/containers/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`].
///
Expand Down Expand Up @@ -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);
}
Expand Down
18 changes: 1 addition & 17 deletions crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>) -> 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:
Expand Down
Loading