1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-26 14:49:06 -04:00

Add Group container

This commit is contained in:
lucasmerlin
2026-03-11 11:13:35 +01:00
parent 8b90dc60c6
commit f7e3a0c317
5 changed files with 158 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
use emath::NumExt;
use crate::{Align2, Id, Rect, Ui, UiBuilder, Vec2};
pub struct Group {
id: Id,
rect: Option<Rect>,
size: Option<Vec2>,
align2: Align2,
}
impl Group {
pub fn new(id: impl Into<Id>) -> Self {
Self {
id: id.into(),
rect: None,
size: None,
align2: Align2::CENTER_CENTER,
}
}
pub fn align2(mut self, align2: Align2) -> Self {
self.align2 = align2;
self
}
pub fn rect(mut self, rect: Rect) -> Self {
self.rect = Some(rect);
self
}
pub fn ui<T>(self, ui: &mut Ui, content: impl FnOnce(&mut Ui) -> T) -> T {
let id = ui.id().with(self.id);
let data_id = id.with("group");
let rect = if let Some(rect) = self.rect {
rect
} else if let Some(size) = self.size {
let pos = ui.next_widget_position();
Rect::from_min_size(pos, size)
} else {
ui.available_rect_before_wrap()
};
let last_size = ui.ctx().data(|mem| mem.get_temp(data_id));
let mut content_rect = if let Some(size) = last_size {
let left_top = self.align2.align_size_within_rect(size, rect).left_top();
Rect::from_min_size(left_top, rect.size())
} else {
rect
};
// Clamp the content_rect so it doesn't exceed the top left corner
let offset = (rect.min - content_rect.min).at_least(Vec2::ZERO);
content_rect = content_rect.translate(offset);
let mut builder = UiBuilder::new().id_salt(id);
if last_size.is_none() {
builder = builder.invisible();
}
let response = ui.scope_builder(builder.max_rect(content_rect), content);
let size = response.response.rect.size();
if last_size != Some(size) {
ui.ctx().request_discard("Group size changed");
ui.ctx().request_repaint();
}
ui.ctx().data_mut(|mem| {
mem.insert_temp(data_id, size);
});
response.inner
}
}

View File

@@ -18,7 +18,9 @@ pub mod scroll_area;
mod sides;
mod tooltip;
pub(crate) mod window;
mod group;
pub use group::Group;
pub use {
area::{Area, AreaState},
close_tag::ClosableTag,

View File

@@ -80,6 +80,7 @@ impl Default for DemoGroups {
Box::<super::extra_viewport::ExtraViewport>::default(),
Box::<super::font_book::FontBook>::default(),
Box::<super::frame_demo::FrameDemo>::default(),
Box::<super::group_demo::GroupDemo>::default(),
Box::<super::highlighting::Highlighting>::default(),
Box::<super::interactive_container::InteractiveContainerDemo>::default(),
Box::<super::MiscDemoWindow>::default(),

View File

@@ -0,0 +1,76 @@
use egui::{Align, Align2, Group, ScrollArea};
#[derive(PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "serde", serde(default))]
pub struct GroupDemo {
align_x: Align,
align_y: Align,
}
impl Default for GroupDemo {
fn default() -> Self {
Self {
align_x: Align::Center,
align_y: Align::Center,
}
}
}
impl crate::Demo for GroupDemo {
fn name(&self) -> &'static str {
"Group"
}
fn show(&mut self, ui: &mut egui::Ui, open: &mut bool) {
egui::Window::new(self.name())
.open(open)
.default_width(300.0)
.default_height(300.0)
.resizable(true)
.constrain_to(ui.available_rect_before_wrap())
.show(ui, |ui| {
use crate::View as _;
self.ui(ui);
});
}
}
impl crate::View for GroupDemo {
fn ui(&mut self, ui: &mut egui::Ui) {
ui.vertical_centered(|ui| {
ui.add(crate::egui_github_link_file!());
});
ui.horizontal(|ui| {
ui.label("Horizontal:");
ui.selectable_value(&mut self.align_x, Align::Min, "Left");
ui.selectable_value(&mut self.align_x, Align::Center, "Center");
ui.selectable_value(&mut self.align_x, Align::Max, "Right");
});
ui.horizontal(|ui| {
ui.label("Vertical:");
ui.selectable_value(&mut self.align_y, Align::Min, "Top");
ui.selectable_value(&mut self.align_y, Align::Center, "Center");
ui.selectable_value(&mut self.align_y, Align::Max, "Bottom");
});
ui.separator();
let align2 = Align2([self.align_x, self.align_y]);
Group::new("demo_group").align2(align2).ui(ui, |ui| {
ui.label("Hello!");
let _ = ui.button("A button");
ui.label("More text");
ScrollArea::vertical().max_height(50.0).show(ui, |ui| {
for _ in 0..100 {
ui.label("Even more text");
}
});
});
ui.set_height(ui.available_height());
}
}

View File

@@ -13,6 +13,7 @@ pub mod drag_and_drop;
pub mod extra_viewport;
pub mod font_book;
pub mod frame_demo;
pub mod group_demo;
pub mod highlighting;
pub mod interactive_container;
pub mod misc_demo_window;