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

Add UiBuilder::layer_id, and remove layer_id from Ui::new #5195

Merged
merged 7 commits into from
Oct 1, 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
3 changes: 2 additions & 1 deletion crates/egui/src/containers/area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
18 changes: 9 additions & 9 deletions crates/egui/src/containers/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,14 +375,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());

Expand Down Expand Up @@ -868,15 +868,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());

Expand Down Expand Up @@ -1135,14 +1135,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());

Expand Down
3 changes: 3 additions & 0 deletions crates/egui/src/painter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
22 changes: 14 additions & 8 deletions crates/egui/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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"
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -247,6 +250,7 @@ impl Ui {
let UiBuilder {
id_salt,
ui_stack_info,
layer_id,
max_rect,
layout,
disabled,
Expand All @@ -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();
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 9 additions & 1 deletion crates/egui/src/ui_builder.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions crates/egui/src/widget_rect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion tests/test_viewports/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Loading