egui
egui copied to clipboard
Is there a "Tab Control" in egui?
Hi guys,
I want create a tab control but don't know which one should I use?
like this
I tried SelectableLabel, but it has no close button.
It looks like, egui lacks this widget.
Looks like an interesting task to me. If no one is interested in implementing this, I can do it. @emilk is it ok? Any suggestions?
I think, it's a good inspiration from imgui for what we can implement here.
Anyway, you can see the example of how you can "emulate" TabControl with SelectableLabel
here
Check out https://github.com/lain-dono/shaderlab
It would be very nice with proper tab support in egui - please make a PR!
It would be very nice with proper tab support in egui - please make a PR!
I have a question about this: it seems that it is not possible to have an Area (which I think would be the base for the component) with a fixed size, or that grows bigger than its contents. Can that be done? A tab component that changes its size based on the selected tab would be weird, but for now, I don't see how to do it.
There is now a crate that offers tabs and docking: https://crates.io/crates/egui_dock
It would be very nice with proper tab support in egui - please make a PR!
I have a question about this: it seems that it is not possible to have an Area (which I think would be the base for the component) with a fixed size, or that grows bigger than its contents. Can that be done? A tab component that changes its size based on the selected tab would be weird, but for now, I don't see how to do it.
It seems like something like this does the trick:
diff --git a/egui/src/containers/resize.rs b/egui/src/containers/resize.rs
index 844fc758..ce57abc9 100644
--- a/egui/src/containers/resize.rs
+++ b/egui/src/containers/resize.rs
@@ -35,6 +35,7 @@ pub struct Resize {
/// If false, we are no enabled
resizable: bool,
+ allow_wrowing_bigger_than_the_contents: bool,
pub(crate) min_size: Vec2,
pub(crate) max_size: Vec2,
@@ -50,6 +51,7 @@ impl Default for Resize {
id: None,
id_source: None,
resizable: true,
+ allow_wrowing_bigger_than_the_contents: false,
min_size: Vec2::splat(16.0),
max_size: Vec2::splat(f32::INFINITY),
default_size: vec2(320.0, 128.0), // TODO(emilk): preferred size of [`Resize`] area.
@@ -134,6 +136,16 @@ impl Resize {
self.resizable
}
+ /// Whether we can make it grow bigger than the contents
+ pub fn allow_grow(mut self, allow_grow: bool) -> Self {
+ self.allow_wrowing_bigger_than_the_contents = allow_grow;
+ self
+ }
+
+ pub fn allows_grow(&self) -> bool {
+ self.allow_wrowing_bigger_than_the_contents
+ }
+
/// Not manually resizable, just takes the size of its contents.
/// Text will not wrap, but will instead make your window width expand.
pub fn auto_sized(self) -> Self {
@@ -271,7 +283,11 @@ impl Resize {
content_ui,
} = prepared;
- state.last_content_size = content_ui.min_size();
+ if self.allow_wrowing_bigger_than_the_contents {
+ state.last_content_size = content_ui.max_size();
+ } else {
+ state.last_content_size = content_ui.min_size();
+ }
// ------------------------------
diff --git a/egui/src/containers/window.rs b/egui/src/containers/window.rs
index 40aa0b0d..fb1ed400 100644
--- a/egui/src/containers/window.rs
+++ b/egui/src/containers/window.rs
@@ -185,6 +185,12 @@ impl<'open> Window<'open> {
self
}
+ /// Whether we can make it grow bigger than the contents
+ pub fn allow_grow(mut self, allow_grow: bool) -> Self {
+ self.resize = self.resize.allow_grow(allow_grow);
+ self
+ }
+
/// Can the window be collapsed by clicking on its title?
pub fn collapsible(mut self, collapsible: bool) -> Self {
self.collapsible = collapsible;
diff --git a/egui/src/ui.rs b/egui/src/ui.rs
index 413677c5..8ee9d119 100644
--- a/egui/src/ui.rs
+++ b/egui/src/ui.rs
@@ -432,6 +432,11 @@ impl Ui {
self.min_rect().size()
}
+ /// Size of content; same as `max_rect().size()`
+ pub fn max_size(&self) -> Vec2 {
+ self.max_rect().size()
+ }
+
/// New widgets will *try* to fit within this rectangle.
///
/// Text labels will wrap to fit within `max_rect`.
Then a fixed size window can be created with .fixed_size([700.0, 700.0]).allow_grow(true)
.
There is now a crate that offers tabs and docking: https://crates.io/crates/egui_dock
Will there be an official implementation of this?
I would love to have an official implementation of this as well
Some basic tabs could make sense to add to egui, but I worry that it will soon lead to feature requests:
- Scrolling of tabs when they are too many
- Drag-drop to re-arrange tabs
- Button to add more tabs
- etc
Still, we could perhaps have a simple tab container that just resists all these feature requests which are better served by external libraries, such as:
- https://crates.io/crates/egui_dock
- https://crates.io/crates/egui_tiles
depending on the implementation of the tabs, scrolling could be solved with a horizontal scroll area and a 'new tab' button could literally be that, a button that adds a tab widget to a list. For that to work though, the tab widget would have to work on its own. Not like "SelectableValue" which uses an enum that has a fixed amount of entries. Then you could just iterate over and show them.
A drag-drop feature could be possible if Sense::drag would be implemented for the widget but that might be out of scope.
If implemented that way these feature requests could easily be implemented by the programmer themselves without having to make them a core functionality.
Then again, the only thing that keeps selectable values from being used exactly like that is the enum part and maybe tabs should be something entirely unique