Fix clip rectangle of windows that don't fit the central area.

This commit is contained in:
Emil Ernerfeldt 2021-09-07 19:34:34 +02:00
parent 5e3c522b6c
commit aef23753ca
2 changed files with 31 additions and 36 deletions

View file

@ -20,6 +20,7 @@ NOTE: [`eframe`](eframe/CHANGELOG.md), [`egui_web`](egui_web/CHANGELOG.md) and [
### Fixed 🐛 ### Fixed 🐛
* Fix wrongly sized multiline `TextEdit` in justified layouts. * Fix wrongly sized multiline `TextEdit` in justified layouts.
* Fix clip rectangle of windows that don't fit the central area.
## 0.14.2 - 2021-08-28 - Window resize fix ## 0.14.2 - 2021-08-28 - Window resize fix

View file

@ -174,6 +174,18 @@ pub(crate) struct Prepared {
} }
impl Area { impl Area {
pub fn show<R>(
self,
ctx: &CtxRef,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
let prepared = self.begin(ctx);
let mut content_ui = prepared.content_ui(ctx);
let inner = add_contents(&mut content_ui);
let response = prepared.end(ctx, content_ui);
InnerResponse { inner, response }
}
pub(crate) fn begin(self, ctx: &CtxRef) -> Prepared { pub(crate) fn begin(self, ctx: &CtxRef) -> Prepared {
let Area { let Area {
id, id,
@ -219,18 +231,6 @@ impl Area {
} }
} }
pub fn show<R>(
self,
ctx: &CtxRef,
add_contents: impl FnOnce(&mut Ui) -> R,
) -> InnerResponse<R> {
let prepared = self.begin(ctx);
let mut content_ui = prepared.content_ui(ctx);
let inner = add_contents(&mut content_ui);
let response = prepared.end(ctx, content_ui);
InnerResponse { inner, response }
}
pub fn show_open_close_animation(&self, ctx: &CtxRef, frame: &Frame, is_open: bool) { pub fn show_open_close_animation(&self, ctx: &CtxRef, frame: &Frame, is_open: bool) {
// must be called first so animation managers know the latest state // must be called first so animation managers know the latest state
let visibility_factor = ctx.animate_bool(self.id.with("close_animation"), is_open); let visibility_factor = ctx.animate_bool(self.id.with("close_animation"), is_open);
@ -274,35 +274,29 @@ impl Prepared {
} }
pub(crate) fn content_ui(&self, ctx: &CtxRef) -> Ui { pub(crate) fn content_ui(&self, ctx: &CtxRef) -> Ui {
let max_rect = if ctx.available_rect().contains(self.state.pos) { let bounds = self.drag_bounds.unwrap_or_else(|| {
Rect::from_min_max(self.state.pos, ctx.available_rect().max) let central_area = ctx.available_rect();
} else {
Rect::from_min_max( let is_within_central_area = central_area.contains_rect(self.state.rect().shrink(1.0));
self.state.pos, if is_within_central_area {
ctx.input() central_area // let's try to not cover side panels
.screen_rect() } else {
.max ctx.input().screen_rect()
.max(self.state.pos + Vec2::splat(32.0)), }
) });
};
let max_rect = Rect::from_min_max(
self.state.pos,
bounds.max.at_least(self.state.pos + Vec2::splat(32.0)),
);
let shadow_radius = ctx.style().visuals.window_shadow.extrusion; // hacky let shadow_radius = ctx.style().visuals.window_shadow.extrusion; // hacky
let bounds = self.drag_bounds.unwrap_or_else(|| ctx.input().screen_rect); let clip_rect_margin = ctx.style().visuals.clip_rect_margin.max(shadow_radius);
let mut clip_rect = max_rect let clip_rect = Rect::from_min_max(self.state.pos, bounds.max)
.expand(ctx.style().visuals.clip_rect_margin) .expand(clip_rect_margin)
.expand(shadow_radius)
.intersect(bounds); .intersect(bounds);
// Windows are constrained to central area,
// (except in rare cases where they don't fit).
// Adjust clip rect so we don't cast shadows on side panels:
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 {
clip_rect = clip_rect.intersect(central_area);
}
let mut ui = Ui::new( let mut ui = Ui::new(
ctx.clone(), ctx.clone(),
self.layer_id, self.layer_id,