Skip to content

Commit

Permalink
Introduce a UiStack
Browse files Browse the repository at this point in the history
  • Loading branch information
abey79 committed May 30, 2024
1 parent 84d2042 commit 6c5aeda
Show file tree
Hide file tree
Showing 21 changed files with 746 additions and 29 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3636,6 +3636,15 @@ dependencies = [
"env_logger",
]

[[package]]
name = "test_stack_frame"
version = "0.1.0"
dependencies = [
"eframe",
"egui_extras",
"env_logger",
]

[[package]]
name = "test_viewports"
version = "0.1.0"
Expand Down
19 changes: 19 additions & 0 deletions crates/egui/src/containers/area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ impl AreaState {
#[derive(Clone, Copy, Debug)]
pub struct Area {
pub(crate) id: Id,
kind: UiKind,
sense: Option<Sense>,
movable: bool,
interactable: bool,
Expand All @@ -105,6 +106,7 @@ impl Area {
pub fn new(id: Id) -> Self {
Self {
id,
kind: UiKind::GenericArea,
sense: None,
movable: true,
interactable: true,
Expand All @@ -130,6 +132,15 @@ impl Area {
self
}

/// Change the [`UiKind`] of the arena.
///
/// Default to [`UiKind::GenericArea`].
#[inline]
pub fn kind(mut self, kind: UiKind) -> Self {
self.kind = kind;
self
}

pub fn layer(&self) -> LayerId {
LayerId::new(self.order, self.id)
}
Expand Down Expand Up @@ -301,6 +312,7 @@ impl Area {
}

pub(crate) struct Prepared {
kind: UiKind,
layer_id: LayerId,
state: AreaState,
move_response: Response,
Expand Down Expand Up @@ -334,6 +346,7 @@ impl Area {
pub(crate) fn begin(self, ctx: &Context) -> Prepared {
let Self {
id,
kind,
sense,
movable,
order,
Expand Down Expand Up @@ -453,6 +466,7 @@ impl Area {
move_response.interact_rect = state.rect();

Prepared {
kind,
layer_id,
state,
move_response,
Expand Down Expand Up @@ -508,6 +522,10 @@ impl Prepared {
self.layer_id.id,
max_rect,
clip_rect,
UiStackInfo {
kind: Some(self.kind),
frame: Default::default(),
},
);

if self.fade_in {
Expand All @@ -530,6 +548,7 @@ impl Prepared {
#[allow(clippy::needless_pass_by_value)] // intentional to swallow up `content_ui`.
pub(crate) fn end(self, ctx: &Context, content_ui: Ui) -> Response {
let Self {
kind: _,
layer_id,
mut state,
move_response,
Expand Down
2 changes: 1 addition & 1 deletion crates/egui/src/containers/combo_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ fn button_frame(
outer_rect.set_height(outer_rect.height().at_least(interact_size.y));

let inner_rect = outer_rect.shrink2(margin);
let mut content_ui = ui.child_ui(inner_rect, *ui.layout());
let mut content_ui = ui.child_ui(inner_rect, *ui.layout(), None);
add_contents(&mut content_ui);

let mut outer_rect = content_ui.min_rect().expand2(margin);
Expand Down
9 changes: 8 additions & 1 deletion crates/egui/src/containers/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,14 @@ impl Frame {
inner_rect.max.x = inner_rect.max.x.max(inner_rect.min.x);
inner_rect.max.y = inner_rect.max.y.max(inner_rect.min.y);

let content_ui = ui.child_ui(inner_rect, *ui.layout());
let content_ui = ui.child_ui(
inner_rect,
*ui.layout(),
Some(UiStackInfo {
frame: self,
kind: Some(UiKind::Frame),
}),
);

// content_ui.set_clip_rect(outer_rect_bounds.shrink(self.stroke.width * 0.5)); // Can't do this since we don't know final size yet

Expand Down
71 changes: 65 additions & 6 deletions crates/egui/src/containers/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,18 @@ impl SidePanel {
}
}

let mut panel_ui = ui.child_ui_with_id_source(panel_rect, Layout::top_down(Align::Min), id);
let mut panel_ui = ui.child_ui_with_id_source_and_frame_data(
panel_rect,
Layout::top_down(Align::Min),
id,
Some(UiStackInfo {
kind: Some(match side {
Side::Left => UiKind::LeftPanel,
Side::Right => UiKind::RightPanel,
}),
frame: Frame::default(),
}),
);
panel_ui.expand_to_include_rect(panel_rect);
let frame = frame.unwrap_or_else(|| Frame::side_top_panel(ui.style()));
let inner_response = frame.show(&mut panel_ui, |ui| {
Expand Down Expand Up @@ -348,7 +359,17 @@ impl SidePanel {
let side = self.side;
let available_rect = ctx.available_rect();
let clip_rect = ctx.screen_rect();
let mut panel_ui = Ui::new(ctx.clone(), layer_id, self.id, available_rect, clip_rect);
let mut panel_ui = Ui::new(
ctx.clone(),
layer_id,
self.id,
available_rect,
clip_rect,
UiStackInfo {
kind: None, // set by show_inside_dyn
frame: Frame::default(),
},
);

let inner_response = self.show_inside_dyn(&mut panel_ui, add_contents);
let rect = inner_response.response.rect;
Expand Down Expand Up @@ -723,7 +744,18 @@ impl TopBottomPanel {
}
}

let mut panel_ui = ui.child_ui_with_id_source(panel_rect, Layout::top_down(Align::Min), id);
let mut panel_ui = ui.child_ui_with_id_source_and_frame_data(
panel_rect,
Layout::top_down(Align::Min),
id,
Some(UiStackInfo {
kind: Some(match side {
TopBottomSide::Top => UiKind::TopPanel,
TopBottomSide::Bottom => UiKind::BottomPanel,
}),
frame: Frame::default(),
}),
);
panel_ui.expand_to_include_rect(panel_rect);
let frame = frame.unwrap_or_else(|| Frame::side_top_panel(ui.style()));
let inner_response = frame.show(&mut panel_ui, |ui| {
Expand Down Expand Up @@ -816,7 +848,17 @@ impl TopBottomPanel {
let side = self.side;

let clip_rect = ctx.screen_rect();
let mut panel_ui = Ui::new(ctx.clone(), layer_id, self.id, available_rect, clip_rect);
let mut panel_ui = Ui::new(
ctx.clone(),
layer_id,
self.id,
available_rect,
clip_rect,
UiStackInfo {
kind: None, // set by show_inside_dyn
frame: Frame::default(),
},
);

let inner_response = self.show_inside_dyn(&mut panel_ui, add_contents);
let rect = inner_response.response.rect;
Expand Down Expand Up @@ -1045,7 +1087,14 @@ impl CentralPanel {
let Self { frame } = self;

let panel_rect = ui.available_rect_before_wrap();
let mut panel_ui = ui.child_ui(panel_rect, Layout::top_down(Align::Min));
let mut panel_ui = ui.child_ui(
panel_rect,
Layout::top_down(Align::Min),
Some(UiStackInfo {
kind: Some(UiKind::CentralPanel),
frame: Frame::default(),
}),
);

let frame = frame.unwrap_or_else(|| Frame::central_panel(ui.style()));
frame.show(&mut panel_ui, |ui| {
Expand Down Expand Up @@ -1074,7 +1123,17 @@ impl CentralPanel {
let id = Id::new((ctx.viewport_id(), "central_panel"));

let clip_rect = ctx.screen_rect();
let mut panel_ui = Ui::new(ctx.clone(), layer_id, id, available_rect, clip_rect);
let mut panel_ui = Ui::new(
ctx.clone(),
layer_id,
id,
available_rect,
clip_rect,
UiStackInfo {
kind: None, // set by show_inside_dyn
frame: Frame::default(),
},
);

let inner_response = self.show_inside_dyn(&mut panel_ui, add_contents);

Expand Down
2 changes: 2 additions & 0 deletions crates/egui/src/containers/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ fn show_tooltip_at_avoid_dyn<'c, R>(
);

let InnerResponse { inner, response } = Area::new(tooltip_area_id)
.kind(UiKind::Popup)
.order(Order::Tooltip)
.pivot(pivot)
.fixed_pos(anchor)
Expand Down Expand Up @@ -287,6 +288,7 @@ pub fn popup_above_or_below_widget<R>(
let inner_width = widget_response.rect.width() - frame_margin.sum().x;

let inner = Area::new(popup_id)
.kind(UiKind::Popup)
.order(Order::Foreground)
.constrain(true)
.fixed_pos(pos)
Expand Down
9 changes: 8 additions & 1 deletion crates/egui/src/containers/resize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,14 @@ impl Resize {

content_clip_rect = content_clip_rect.intersect(ui.clip_rect()); // Respect parent region

let mut content_ui = ui.child_ui(inner_rect, *ui.layout());
let mut content_ui = ui.child_ui(
inner_rect,
*ui.layout(),
Some(UiStackInfo {
kind: Some(UiKind::Resize),
frame: Frame::default(),
}),
);
content_ui.set_clip_rect(content_clip_rect);

Prepared {
Expand Down
9 changes: 8 additions & 1 deletion crates/egui/src/containers/scroll_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,14 @@ impl ScrollArea {
}

let content_max_rect = Rect::from_min_size(inner_rect.min - state.offset, content_max_size);
let mut content_ui = ui.child_ui(content_max_rect, *ui.layout());
let mut content_ui = ui.child_ui(
content_max_rect,
*ui.layout(),
Some(UiStackInfo {
kind: Some(UiKind::ScrollArea),
frame: Frame::default(),
}),
);

{
// Clip the content, but only when we really need to:
Expand Down
4 changes: 3 additions & 1 deletion crates/egui/src/containers/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ impl<'open> Window<'open> {
/// If you need a changing title, you must call `window.id(…)` with a fixed id.
pub fn new(title: impl Into<WidgetText>) -> Self {
let title = title.into().fallback_text_style(TextStyle::Heading);
let area = Area::new(Id::new(title.text())).constrain(true);
let area = Area::new(Id::new(title.text()))
.kind(UiKind::Window)
.constrain(true);
Self {
title,
open: None,
Expand Down
2 changes: 2 additions & 0 deletions crates/egui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,7 @@ mod sense;
pub mod style;
pub mod text_selection;
mod ui;
mod ui_stack;
pub mod util;
pub mod viewport;
mod widget_rect;
Expand Down Expand Up @@ -466,6 +467,7 @@ pub use {
style::{FontSelection, Style, TextStyle, Visuals},
text::{Galley, TextFormat},
ui::Ui,
ui_stack::*,
viewport::*,
widget_rect::{WidgetRect, WidgetRects},
widget_text::{RichText, WidgetText},
Expand Down
1 change: 1 addition & 0 deletions crates/egui/src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ fn menu_popup<'c, R>(
};

let area = Area::new(menu_id.with("__menu"))
.kind(UiKind::Menu)
.order(Order::Foreground)
.fixed_pos(pos)
.constrain_to(ctx.screen_rect())
Expand Down
Loading

0 comments on commit 6c5aeda

Please sign in to comment.