summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/egui/src/containers/area.rs3
-rw-r--r--crates/egui/src/containers/panel.rs18
-rw-r--r--crates/egui/src/painter.rs3
-rw-r--r--crates/egui/src/ui.rs22
-rw-r--r--crates/egui/src/ui_builder.rs10
-rw-r--r--crates/egui/src/widget_rect.rs8
-rw-r--r--tests/test_viewports/src/main.rs2
7 files changed, 46 insertions, 20 deletions
diff --git a/crates/egui/src/containers/area.rs b/crates/egui/src/containers/area.rs
index fa8e5fc2..b0cb0330 100644
--- a/crates/egui/src/containers/area.rs
+++ b/crates/egui/src/containers/area.rs
@@ -540,6 +540,7 @@ impl Prepared {
let mut ui_builder = UiBuilder::new()
.ui_stack_info(UiStackInfo::new(self.kind))
+ .layer_id(self.layer_id)
.max_rect(max_rect);
if !self.enabled {
@@ -549,7 +550,7 @@ impl Prepared {
ui_builder = ui_builder.sizing_pass().invisible();
}
- let mut ui = Ui::new(ctx.clone(), self.layer_id, self.layer_id.id, ui_builder);
+ let mut ui = Ui::new(ctx.clone(), self.layer_id.id, ui_builder);
ui.set_clip_rect(self.constrain_rect); // Don't paint outside our bounds
if self.fade_in {
diff --git a/crates/egui/src/containers/panel.rs b/crates/egui/src/containers/panel.rs
index ee510457..7cf22a69 100644
--- a/crates/egui/src/containers/panel.rs
+++ b/crates/egui/src/containers/panel.rs
@@ -372,14 +372,14 @@ impl SidePanel {
ctx: &Context,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
- let layer_id = LayerId::background();
let side = self.side;
let available_rect = ctx.available_rect();
let mut panel_ui = Ui::new(
ctx.clone(),
- layer_id,
self.id,
- UiBuilder::new().max_rect(available_rect),
+ UiBuilder::new()
+ .layer_id(LayerId::background())
+ .max_rect(available_rect),
);
panel_ui.set_clip_rect(ctx.screen_rect());
@@ -864,15 +864,15 @@ impl TopBottomPanel {
ctx: &Context,
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
- let layer_id = LayerId::background();
let available_rect = ctx.available_rect();
let side = self.side;
let mut panel_ui = Ui::new(
ctx.clone(),
- layer_id,
self.id,
- UiBuilder::new().max_rect(available_rect),
+ UiBuilder::new()
+ .layer_id(LayerId::background())
+ .max_rect(available_rect),
);
panel_ui.set_clip_rect(ctx.screen_rect());
@@ -1131,14 +1131,14 @@ impl CentralPanel {
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
) -> InnerResponse<R> {
let available_rect = ctx.available_rect();
- let layer_id = LayerId::background();
let id = Id::new((ctx.viewport_id(), "central_panel"));
let mut panel_ui = Ui::new(
ctx.clone(),
- layer_id,
id,
- UiBuilder::new().max_rect(available_rect),
+ UiBuilder::new()
+ .layer_id(LayerId::background())
+ .max_rect(available_rect),
);
panel_ui.set_clip_rect(ctx.screen_rect());
diff --git a/crates/egui/src/painter.rs b/crates/egui/src/painter.rs
index feefe47d..5b8ae77d 100644
--- a/crates/egui/src/painter.rs
+++ b/crates/egui/src/painter.rs
@@ -74,6 +74,9 @@ impl Painter {
}
/// Redirect where you are painting.
+ ///
+ /// It is undefined behavior to change the [`LayerId`]
+ /// of [`crate::Ui::painter`].
pub fn set_layer_id(&mut self, layer_id: LayerId) {
self.layer_id = layer_id;
}
diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs
index ee77888f..9db1404d 100644
--- a/crates/egui/src/ui.rs
+++ b/crates/egui/src/ui.rs
@@ -120,10 +120,11 @@ impl Ui {
///
/// Normally you would not use this directly, but instead use
/// [`crate::SidePanel`], [`crate::TopBottomPanel`], [`crate::CentralPanel`], [`crate::Window`] or [`crate::Area`].
- pub fn new(ctx: Context, layer_id: LayerId, id: Id, ui_builder: UiBuilder) -> Self {
+ pub fn new(ctx: Context, id: Id, ui_builder: UiBuilder) -> Self {
let UiBuilder {
id_salt,
ui_stack_info,
+ layer_id,
max_rect,
layout,
disabled,
@@ -133,6 +134,8 @@ impl Ui {
sense,
} = ui_builder;
+ let layer_id = layer_id.unwrap_or(LayerId::background());
+
debug_assert!(
id_salt.is_none(),
"Top-level Ui:s should not have an id_salt"
@@ -170,7 +173,7 @@ impl Ui {
};
// Register in the widget stack early, to ensure we are behind all widgets we contain:
- let start_rect = Rect::NOTHING; // This will be overwritten when/if `remember_min_rect` is called
+ let start_rect = Rect::NOTHING; // This will be overwritten when `remember_min_rect` is called
ui.ctx().create_widget(
WidgetRect {
id: ui.unique_id,
@@ -247,6 +250,7 @@ impl Ui {
let UiBuilder {
id_salt,
ui_stack_info,
+ layer_id,
max_rect,
layout,
disabled,
@@ -262,6 +266,9 @@ impl Ui {
let max_rect = max_rect.unwrap_or_else(|| self.available_rect_before_wrap());
let mut layout = layout.unwrap_or(*self.layout());
let enabled = self.enabled && !disabled && !invisible;
+ if let Some(layer_id) = layer_id {
+ painter.set_layer_id(layer_id);
+ }
if invisible {
painter.set_invisible();
}
@@ -310,7 +317,7 @@ impl Ui {
};
// Register in the widget stack early, to ensure we are behind all widgets we contain:
- let start_rect = Rect::NOTHING; // This will be overwritten when/if `remember_min_rect` is called
+ let start_rect = Rect::NOTHING; // This will be overwritten when `remember_min_rect` is called
child_ui.ctx().create_widget(
WidgetRect {
id: child_ui.unique_id,
@@ -2306,15 +2313,13 @@ impl Ui {
/// });
/// # });
/// ```
+ #[deprecated = "Use ui.scope_builder(UiBuilder::new().layer_id(…), …) instead"]
pub fn with_layer_id<R>(
&mut self,
layer_id: LayerId,
add_contents: impl FnOnce(&mut Self) -> R,
) -> InnerResponse<R> {
- self.scope(|ui| {
- ui.painter.set_layer_id(layer_id);
- add_contents(ui)
- })
+ self.scope_builder(UiBuilder::new().layer_id(layer_id), add_contents)
}
/// A [`CollapsingHeader`] that starts out collapsed.
@@ -2760,7 +2765,8 @@ impl Ui {
// Paint the body to a new layer:
let layer_id = LayerId::new(Order::Tooltip, id);
- let InnerResponse { inner, response } = self.with_layer_id(layer_id, add_contents);
+ let InnerResponse { inner, response } =
+ self.scope_builder(UiBuilder::new().layer_id(layer_id), add_contents);
// Now we move the visuals of the body to where the mouse is.
// Normally you need to decide a location for a widget first,
diff --git a/crates/egui/src/ui_builder.rs b/crates/egui/src/ui_builder.rs
index 33a48dbd..e1075a9e 100644
--- a/crates/egui/src/ui_builder.rs
+++ b/crates/egui/src/ui_builder.rs
@@ -1,6 +1,6 @@
use std::{hash::Hash, sync::Arc};
-use crate::{Id, Layout, Rect, Sense, Style, UiStackInfo};
+use crate::{Id, LayerId, Layout, Rect, Sense, Style, UiStackInfo};
#[allow(unused_imports)] // Used for doclinks
use crate::Ui;
@@ -15,6 +15,7 @@ use crate::Ui;
pub struct UiBuilder {
pub id_salt: Option<Id>,
pub ui_stack_info: UiStackInfo,
+ pub layer_id: Option<LayerId>,
pub max_rect: Option<Rect>,
pub layout: Option<Layout>,
pub disabled: bool,
@@ -48,6 +49,13 @@ impl UiBuilder {
self
}
+ /// Show the [`Ui`] in a different [`LayerId`] from its parent.
+ #[inline]
+ pub fn layer_id(mut self, layer_id: LayerId) -> Self {
+ self.layer_id = Some(layer_id);
+ self
+ }
+
/// Set the max rectangle, within which widgets will go.
///
/// New widgets will *try* to fit within this rectangle.
diff --git a/crates/egui/src/widget_rect.rs b/crates/egui/src/widget_rect.rs
index 91924352..dd900af1 100644
--- a/crates/egui/src/widget_rect.rs
+++ b/crates/egui/src/widget_rect.rs
@@ -139,6 +139,14 @@ impl WidgetRects {
// e.g. calling `response.interact(…)` to add more interaction.
let (idx_in_layer, existing) = entry.get_mut();
+ debug_assert!(
+ existing.layer_id == widget_rect.layer_id,
+ "Widget {:?} changed layer_id during the frame from {:?} to {:?}",
+ widget_rect.id,
+ existing.layer_id,
+ widget_rect.layer_id
+ );
+
// Update it:
existing.rect = widget_rect.rect; // last wins
existing.interact_rect = widget_rect.interact_rect; // last wins
diff --git a/tests/test_viewports/src/main.rs b/tests/test_viewports/src/main.rs
index 24046e04..9d06db43 100644
--- a/tests/test_viewports/src/main.rs
+++ b/tests/test_viewports/src/main.rs
@@ -433,7 +433,7 @@ fn drag_source<R>(
// Paint the body to a new layer:
let layer_id = egui::LayerId::new(egui::Order::Tooltip, id);
- let res = ui.with_layer_id(layer_id, body);
+ let res = ui.scope_builder(UiBuilder::new().layer_id(layer_id), body);
if let Some(pointer_pos) = ui.ctx().pointer_interact_pos() {
let delta = pointer_pos - res.response.rect.center();