mirror of
https://github.com/emilk/egui.git
synced 2026-08-29 04:40:03 -04:00
Rework Window margins and set clip_rect_margin to zero (#7725)
* Follows https://github.com/emilk/egui/pull/7722 * Part of https://github.com/emilk/egui/issues/5605 * Closes https://github.com/emilk/egui/issues/3385 ## What Sets `clip_rect_margin` to zero, and moves the margin of `Window`s with `ScrollAreas`, so that the scroll bars are now on the very edge of the windows they are in. Windows with a bulit-in scroll area now lets the content go all the way to the edges (left image). However, if you just manually add a `ScrollArea` to a `Window`, you won't get this effect (right image). <img width="763" height="345" alt="Screenshot 2026-05-18 at 22 04 01" src="https://github.com/user-attachments/assets/e41cdfcb-b0a6-4e5e-9691-d132a602d6a7" /> ## Required * #7803 * #7804 * #7805 * #7806 * https://github.com/emilk/egui/pull/7807 * https://github.com/emilk/egui/pull/7808
This commit is contained in:
@@ -192,6 +192,7 @@ impl Frame {
|
|||||||
Self::new().inner_margin(8).fill(style.visuals.panel_fill)
|
Self::new().inner_margin(8).fill(style.visuals.panel_fill)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The default frame for an [`crate::Window`].
|
||||||
pub fn window(style: &Style) -> Self {
|
pub fn window(style: &Style) -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
.inner_margin(style.spacing.window_margin)
|
.inner_margin(style.spacing.window_margin)
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ impl<'a> Window<'a> {
|
|||||||
.with_stroke(false)
|
.with_stroke(false)
|
||||||
.min_size([96.0, 32.0])
|
.min_size([96.0, 32.0])
|
||||||
.default_size([340.0, 420.0]), // Default outer size of a window (includes frame margins, stroke, and title bar)
|
.default_size([340.0, 420.0]), // Default outer size of a window (includes frame margins, stroke, and title bar)
|
||||||
scroll: ScrollArea::neither().auto_shrink(false),
|
scroll: ScrollArea::neither().auto_shrink(false).content_margin(0.0),
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
default_open: true,
|
default_open: true,
|
||||||
with_title_bar: true,
|
with_title_bar: true,
|
||||||
@@ -493,6 +493,10 @@ impl Window<'_> {
|
|||||||
|
|
||||||
let window_frame = frame.unwrap_or_else(|| Frame::window(&style));
|
let window_frame = frame.unwrap_or_else(|| Frame::window(&style));
|
||||||
|
|
||||||
|
// We apply the window margin by using the `ScrollArea::content_margin`.
|
||||||
|
let window_margin = window_frame.inner_margin;
|
||||||
|
let window_frame = window_frame.inner_margin(0.0);
|
||||||
|
|
||||||
let is_explicitly_closed = matches!(open, Some(false));
|
let is_explicitly_closed = matches!(open, Some(false));
|
||||||
let is_open = !is_explicitly_closed || ctx.memory(|mem| mem.everything_is_visible());
|
let is_open = !is_explicitly_closed || ctx.memory(|mem| mem.everything_is_visible());
|
||||||
let opacity = ctx.animate_bool_with_easing(
|
let opacity = ctx.animate_bool_with_easing(
|
||||||
@@ -564,7 +568,7 @@ impl Window<'_> {
|
|||||||
title_ui(
|
title_ui(
|
||||||
ui,
|
ui,
|
||||||
title,
|
title,
|
||||||
window_frame,
|
window_frame.inner_margin(window_margin),
|
||||||
&mut collapsing,
|
&mut collapsing,
|
||||||
collapsible,
|
collapsible,
|
||||||
on_top,
|
on_top,
|
||||||
@@ -575,9 +579,15 @@ impl Window<'_> {
|
|||||||
collapsing
|
collapsing
|
||||||
.show_body_unindented(ui, |ui| {
|
.show_body_unindented(ui, |ui| {
|
||||||
if scroll.is_any_scroll_enabled() {
|
if scroll.is_any_scroll_enabled() {
|
||||||
scroll.show(ui, add_contents).inner
|
scroll
|
||||||
|
.content_margin(window_margin)
|
||||||
|
.show(ui, add_contents)
|
||||||
|
.inner
|
||||||
} else {
|
} else {
|
||||||
add_contents(ui)
|
crate::Frame::NONE
|
||||||
|
.inner_margin(window_margin)
|
||||||
|
.show(ui, add_contents)
|
||||||
|
.inner
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|inner| inner.inner)
|
.map(|inner| inner.inner)
|
||||||
@@ -1179,7 +1189,10 @@ fn title_ui(
|
|||||||
let mut layout = AtomLayout::new(atoms)
|
let mut layout = AtomLayout::new(atoms)
|
||||||
.gap(spacing)
|
.gap(spacing)
|
||||||
.fallback_font(TextStyle::Heading)
|
.fallback_font(TextStyle::Heading)
|
||||||
.wrap_mode(TextWrapMode::Truncate);
|
.wrap_mode(TextWrapMode::Truncate)
|
||||||
|
.frame(Frame::NONE.inner_margin(frame.inner_margin));
|
||||||
|
|
||||||
|
let frame = frame.inner_margin(0); // Only applied to the atoms; done above.
|
||||||
|
|
||||||
if expanded {
|
if expanded {
|
||||||
let min_width = if auto_sized {
|
let min_width = if auto_sized {
|
||||||
@@ -1244,18 +1257,18 @@ fn title_ui(
|
|||||||
collapsing.toggle(&child_ui);
|
collapsing.toggle(&child_ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
child_ui.set_clip_rect(Rect::EVERYTHING);
|
{
|
||||||
let mut header_frame = frame.shadow(Shadow::NONE);
|
let mut header_frame = frame.shadow(Shadow::NONE);
|
||||||
if active {
|
if active {
|
||||||
header_frame = header_frame.fill(ui.visuals().widgets.open.weak_bg_fill);
|
header_frame = header_frame.fill(ui.visuals().widgets.open.weak_bg_fill);
|
||||||
|
}
|
||||||
|
if expanded {
|
||||||
|
header_frame.corner_radius.sw = 0;
|
||||||
|
header_frame.corner_radius.se = 0;
|
||||||
|
}
|
||||||
|
ui.painter()
|
||||||
|
.set(shape_idx, header_frame.paint(layout_response.rect));
|
||||||
}
|
}
|
||||||
if expanded {
|
|
||||||
header_frame.corner_radius.sw = 0;
|
|
||||||
header_frame.corner_radius.se = 0;
|
|
||||||
}
|
|
||||||
child_ui
|
|
||||||
.painter()
|
|
||||||
.set(shape_idx, header_frame.paint(layout_response.rect));
|
|
||||||
|
|
||||||
let mut advance_rect = child_ui.min_rect();
|
let mut advance_rect = child_ui.min_rect();
|
||||||
|
|
||||||
|
|||||||
@@ -1074,7 +1074,10 @@ pub struct Visuals {
|
|||||||
/// How the text cursor acts.
|
/// How the text cursor acts.
|
||||||
pub text_cursor: TextCursorStyle,
|
pub text_cursor: TextCursorStyle,
|
||||||
|
|
||||||
/// Allow child widgets to be just on the border and still have a stroke with some thickness
|
/// Allow widgets to paint this much outside the scroll area rect.
|
||||||
|
///
|
||||||
|
/// Legacy. Should not be used anymore.
|
||||||
|
/// Use [`crate::ScrollArea::content_margin`] instead.
|
||||||
pub clip_rect_margin: f32,
|
pub clip_rect_margin: f32,
|
||||||
|
|
||||||
/// Show a background behind buttons.
|
/// Show a background behind buttons.
|
||||||
@@ -1500,7 +1503,7 @@ impl Visuals {
|
|||||||
|
|
||||||
text_cursor: Default::default(),
|
text_cursor: Default::default(),
|
||||||
|
|
||||||
clip_rect_margin: 3.0, // should be at least half the size of the widest frame stroke + max WidgetVisuals::expansion
|
clip_rect_margin: 0.0,
|
||||||
button_frame: true,
|
button_frame: true,
|
||||||
collapsing_header_frame: false,
|
collapsing_header_frame: false,
|
||||||
indent_has_left_vline: true,
|
indent_has_left_vline: true,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ impl Custom3d {
|
|||||||
|
|
||||||
impl crate::DemoApp for Custom3d {
|
impl crate::DemoApp for Custom3d {
|
||||||
fn demo_ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
fn demo_ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
||||||
// TODO(emilk): Use `ScrollArea::inner_margin`
|
// TODO(emilk): Use `ScrollArea::content_margin`
|
||||||
egui::CentralPanel::default().show_inside(ui, |ui| {
|
egui::CentralPanel::default().show_inside(ui, |ui| {
|
||||||
egui::ScrollArea::both().auto_shrink(false).show(ui, |ui| {
|
egui::ScrollArea::both().auto_shrink(false).show(ui, |ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ impl Custom3d {
|
|||||||
|
|
||||||
impl crate::DemoApp for Custom3d {
|
impl crate::DemoApp for Custom3d {
|
||||||
fn demo_ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
fn demo_ui(&mut self, ui: &mut egui::Ui, _frame: &mut eframe::Frame) {
|
||||||
// TODO(emilk): Use `ScrollArea::inner_margin`
|
// TODO(emilk): Use `ScrollArea::content_margin`
|
||||||
egui::CentralPanel::default().show_inside(ui, |ui| {
|
egui::CentralPanel::default().show_inside(ui, |ui| {
|
||||||
egui::ScrollArea::both().auto_shrink(false).show(ui, |ui| {
|
egui::ScrollArea::both().auto_shrink(false).show(ui, |ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fa67354cfe4d9cb8774c8de614be5975853a4a817ceaf96c3ec7a968de638d8d
|
oid sha256:406fa40c9e69e353128ea3dde985148773cd0e148c24096ca55ee0cc1aab0258
|
||||||
size 169740
|
size 168849
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:157424625dbb855e116a29a008172f29697a37b03512ef06a2e92e502d5e4128
|
oid sha256:73429ec71d1ae05518352f1a99304f55647dac362092c9cd5618f709b9ba0d11
|
||||||
size 101816
|
size 99950
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:2027f21fdb132542e01fc592d3150aa876cf2ebb4a4268b8c170ff4f523657f0
|
oid sha256:d14571fdd7602ea4924d04725008433e1bb53596d8a279f310ddc6c3231b6d32
|
||||||
size 114074
|
size 114106
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:6e00e1dd95278a003c383f5a3f16d25ee4943073171d862db50cb17e90e421bc
|
oid sha256:2909f098b5edacefef1b5c4d81982b0c84ebd27f896934f0bef92ceb283bbe79
|
||||||
size 60272
|
size 60288
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:fc1d270e0171cc055fe99579d3f7ab52c63783c793c59aaf8c82027bf1dd3ab8
|
oid sha256:1cd58e9912d1db051c93a9b2ea340f3f6dfe64d38ed54aa1b8292bc6f1bf970c
|
||||||
size 216484
|
size 215502
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:10e4658168d6a93779463ebb81520f821cbf6eac59391c60d30f5d40ebdf910d
|
oid sha256:fc28830c402d3aa861a220cfc600c3ce2d7b8ca77307691b3f844a34f27afd1f
|
||||||
size 152623
|
size 151376
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:66f35217b0becce12e251c4e7063c31ac92e080340a0318891771fdff54593db
|
oid sha256:ca08bb7cd0be0b5a9d10833e5c9b65e889f78a5a8056df69d6b0006c3a228227
|
||||||
size 67388
|
size 66050
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:29e23e0e45a6e557e569358c89a34dc768ff0b33b47112f864ae8ed119ac6e6e
|
oid sha256:121c6d5ba129439d2d747da8e505cfff04a023c28d9a0e3aca324d77de1ef418
|
||||||
size 81119
|
size 79186
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:dde445e82732c45f84acbfa83761348b9b89dd2a4fec500ba5124b0c1e58dd29
|
oid sha256:3e44cef45d27ddd64b0d2f6de0b7005846147bce54a9b8b1223ba9a0a02c2416
|
||||||
size 63060
|
size 62830
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:f9c8eecaedce2bbcbdc4b7975a349b9f986463f189041c7ad6bed64809f18bcd
|
oid sha256:90c4ea93f234aded298ddeeb98e2d6a0566f07efcdaf5c990e8a47a6533db516
|
||||||
size 445367
|
size 446483
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:59939d3347679ff27c1de500a559cdc0e6387f633c86ec7ce51f2a36cd92547b
|
oid sha256:0267c21c4cbe5601263d046a56596275272fbcf727653131f7780aa51ecf6253
|
||||||
size 7511
|
size 6956
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:df2578c198b29950254ec62c6cc615a4b1c003e7ae3ea027da22fc868b392c74
|
oid sha256:46a498433ede5b71abccb5bbeed5788e4ba80949b96f3371b107bd45d5dee28a
|
||||||
size 8342
|
size 7964
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:6f2a57ad8dbdd121cb181e74d76db68d800aba8fdc980d8de4e962e1e85fe8f6
|
oid sha256:4b0af10fca47b33752aed2549528dba6b6e8c4818f2fc2b9de60451afdd30a2b
|
||||||
size 1803
|
size 1690
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:43dc457cac18107772dbb7e5773961cf502dd685ce1cb4e94338e6b7daedaa77
|
oid sha256:7db4a0f33da131ca69771fef974689680c802187cdd8e835131d70457aca775c
|
||||||
size 1861
|
size 1639
|
||||||
|
|||||||
Reference in New Issue
Block a user