Struct egui::Ui [−][src]
pub struct Ui { /* fields omitted */ }
Expand description
This is what you use to place widgets.
Represents a region of the screen with a type of layout (horizontal or vertical).
ui.add(egui::Label::new("Hello World!"));
ui.label("A shorter and more convenient way to add a label.");
ui.horizontal(|ui| {
ui.label("Add widgets");
if ui.button("on the same row!").clicked() {
/* … */
}
});
Implementations
Create a new Ui
.
Normally you would not use this directly, but instead use
SidePanel
, TopBottomPanel
, CentralPanel
, Window
or Area
.
Create a new Ui
at a specific region.
Mutably borrow internal Style
.
Changes apply to this Ui
and its subsequent children.
To set the style of all Ui
:s, use Context::set_style
.
Example:
ui.style_mut().body_text_style = egui::TextStyle::Heading;
Changes apply to this Ui
and its subsequent children.
To set the visuals of all Ui
:s, use Context::set_visuals
.
Reset to the default style set in Context
.
The current spacing options for this Ui
.
Short for ui.style().spacing
.
Mutably borrow internal Spacing
.
Changes apply to this Ui
and its subsequent children.
Example:
ui.spacing_mut().item_spacing = egui::vec2(10.0, 2.0);
The current visuals settings of this Ui
.
Short for ui.style().visuals
.
Mutably borrow internal visuals
.
Changes apply to this Ui
and its subsequent children.
To set the visuals of all Ui
:s, use Context::set_visuals
.
Example:
ui.visuals_mut().override_text_color = Some(egui::Color32::RED);
If false
, the Ui
does not allow any interaction and
the widgets in it will draw with a gray look.
Calling set_enabled(false)
will cause the Ui
to deny all future interaction
and all the widgets will draw with a gray look.
Calling set_enabled(true)
has no effect - it will NOT re-enable the Ui
once disabled.
Example
ui.group(|ui|{
ui.checkbox(&mut enabled, "Enable subsection");
ui.set_enabled(enabled);
if ui.button("Button that is not always clickable").clicked() {
/* … */
}
});
If false
, any widgets added to the Ui
will be invisible and non-interactive.
Calling set_visible(false)
will cause all further widgets to be invisible,
yet still allocate space.
The widgets will not be interactive (set_visible(false)
implies set_enabled(false)
).
Calling set_visible(true)
has no effect.
Example
ui.group(|ui|{
ui.checkbox(&mut visible, "Show subsection");
ui.set_visible(visible);
if ui.button("Button that is not always shown").clicked() {
/* … */
}
});
Should text wrap in this Ui
?
This is determined first by Style::wrap
, and then by the layout of this Ui
.
Create a painter for a sub-region of this Ui.
The clip-rect of the returned Painter
will be the intersection
of the given rectangle and the clip_rect()
of this Ui
.
The Input
of the Context
associated with the Ui
.
Equivalent to .ctx().input()
.
The Memory
of the Context
associated with the Ui
.
Equivalent to .ctx().memory()
.
The Output
of the Context
associated with the Ui
.
Equivalent to .ctx().output()
.
The Fonts
of the Context
associated with the Ui
.
Equivalent to .ctx().fonts()
.
Screen-space rectangle for clipping what we paint in this ui. This is used, for instance, to avoid painting outside a window that is smaller than its contents.
Screen-space rectangle for clipping what we paint in this ui. This is used, for instance, to avoid painting outside a window that is smaller than its contents.
Where and how large the Ui
is already.
All widgets that have been added ot this Ui
fits within this rectangle.
No matter what, the final Ui will be at least this large.
This will grow as new widgets are added, but never shrink.
New widgets will try to fit within this rectangle.
Text labels will wrap to fit within max_rect
.
Separator lines will span the max_rect
.
If a new widget doesn’t fit within the max_rect
then the
Ui
will make room for it by expanding both min_rect
and max_rect
.
This is like max_rect()
, but will never be infinite.
This can be useful for widgets that expand to fit the available space.
Set the maximum size of the ui. You won’t be able to shrink it below the current minimum size.
Set the maximum width of the ui. You won’t be able to shrink it below the current minimum size.
Set the maximum height of the ui. You won’t be able to shrink it below the current minimum size.
Set the minimum size of the ui. This can’t shrink the ui, only make it larger.
Set the minimum width of the ui. This can’t shrink the ui, only make it larger.
Set the minimum height of the ui. This can’t shrink the ui, only make it larger.
Helper: shrinks the max width to the current width, so further widgets will try not to be wider than previous widgets. Useful for normal vertical layouts.
Helper: shrinks the max height to the current height, so further widgets will try not to be wider than previous widgets.
Expand the min_rect
and max_rect
of this ui to include a child at the given rect.
ui.set_width_range(min..=max);
is equivalent to ui.set_min_width(min); ui.set_max_width(max);
.
Set both the minimum and maximum height.
Ensure we are big enough to contain the given x-coordinate. This is sometimes useful to expand an ui to stretch to a certain place.
The available space at the moment, given the current cursor. This how much more space we can take up without overflowing our parent. Shrinks as widgets allocate space and the cursor moves. A small size should be interpreted as “as little as possible”. An infinite size should be interpreted as “as much as you want”.
In case of a wrapping layout, how much space is left on this row/column?
This is like available_size_before_wrap()
, but will never be infinite.
This can be useful for widgets that expand to fit the available space.
In most layouts the next widget will be put in the top left corner of this Rect
.
This is like available_rect_before_wrap()
, but will never be infinite.
This can be useful for widgets that expand to fit the available space.
In most layouts the next widget will be put in the top left corner of this Rect
.
pub fn make_persistent_id<IdSource>(&self, id_source: IdSource) -> Id where
IdSource: Hash + Debug,
pub fn make_persistent_id<IdSource>(&self, id_source: IdSource) -> Id where
IdSource: Hash + Debug,
Use this to generate widget ids for widgets that have persistent state in Memory
.
Check for clicks, drags and/or hover on a specific region of this Ui
.
Is the pointer (mouse/touch) above this rectangle in this Ui
?
The clip_rect
and layer of this Ui
will be respected, so, for instance,
if this Ui
is behind some other window, this will always return false
.
Is the pointer (mouse/touch) above this Ui
?
Equivalent to ui.rect_contains_pointer(ui.min_rect())
renamed rect_contains_pointer
renamed ui_contains_pointer
Use: interact(rect, id, Sense::hover())
Use: rect_contains_pointer()
Allocate space for a widget and check for interaction in the space.
Returns a Response
which contains a rectangle, id, and interaction info.
How sizes are negotiated
Each widget should have a minimum desired size and a desired size.
When asking for space, ask AT LEAST for your minimum, and don’t ask for more than you need.
If you want to fill the space, ask about available().size()
and use that.
You may get MORE space than you asked for, for instance for justified layouts, like in menus.
You will never get a rectangle that is smaller than the amount of space you asked for.
let response = ui.allocate_response(egui::vec2(100.0, 200.0), egui::Sense::click());
if response.clicked() { /* … */ }
ui.painter().rect_stroke(response.rect, 0.0, (1.0, egui::Color32::WHITE));
Returns a Rect
with exactly what you asked for.
The response rect will be larger if this is part of a justified layout or similar.
This means that if this is a narrow widget in a wide justified layout, then
the widget will react to interactions outside the returned Rect
.
Allocate at least as much space as needed, and interact with that rect.
The returned Rect
will be the same size as Response::rect
.
Reserve this much space and move the cursor. Returns where to put the widget.
How sizes are negotiated
Each widget should have a minimum desired size and a desired size.
When asking for space, ask AT LEAST for your minimum, and don’t ask for more than you need.
If you want to fill the space, ask about available().size()
and use that.
You may get MORE space than you asked for, for instance for justified layouts, like in menus.
You will never get a rectangle that is smaller than the amount of space you asked for.
Returns an automatic Id
(which you can use for interaction) and the Rect
of where to put your widget.
let (id, rect) = ui.allocate_space(egui::vec2(100.0, 200.0));
let response = ui.interact(rect, id, egui::Sense::click());
Allocate a specific part of the Ui
.
Ignore the layout of the Ui
: just put my widget here!
The layout cursor will advance to past this rect
.
pub fn allocate_ui<R>(
&mut self,
desired_size: Vec2,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
pub fn allocate_ui<R>(
&mut self,
desired_size: Vec2,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
Allocated the given space and then adds content to that space.
If the contents overflow, more space will be allocated.
When finished, the amount of space actually used (min_rect
) will be allocated.
So you can request a lot of space and then use less.
pub fn allocate_ui_with_layout<R>(
&mut self,
desired_size: Vec2,
layout: Layout,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
pub fn allocate_ui_with_layout<R>(
&mut self,
desired_size: Vec2,
layout: Layout,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
Allocated the given space and then adds content to that space.
If the contents overflow, more space will be allocated.
When finished, the amount of space actually used (min_rect
) will be allocated.
So you can request a lot of space and then use less.
pub fn allocate_ui_at_rect<R>(
&mut self,
max_rect: Rect,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
pub fn allocate_ui_at_rect<R>(
&mut self,
max_rect: Rect,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
Allocated the given rectangle and then adds content to that rectangle.
If the contents overflow, more space will be allocated.
When finished, the amount of space actually used (min_rect
) will be allocated.
So you can request a lot of space and then use less.
Convenience function to get a region to paint on.
Note that egui uses screen coordinates for everything.
let size = Vec2::splat(16.0);
let (response, painter) = ui.allocate_painter(size, Sense::hover());
let rect = response.rect;
let c = rect.center();
let r = rect.width() / 2.0 - 1.0;
let color = Color32::from_gray(128);
let stroke = Stroke::new(1.0, color);
painter.circle_stroke(c, r, stroke);
painter.line_segment([c - vec2(0.0, r), c + vec2(0.0, r)], stroke);
painter.line_segment([c, c + r * Vec2::angled(TAU * 1.0 / 8.0)], stroke);
painter.line_segment([c, c + r * Vec2::angled(TAU * 3.0 / 8.0)], stroke);
Move the scroll to this cursor position with the specified alignment.
egui::ScrollArea::auto_sized().show(ui, |ui| {
let scroll_bottom = ui.button("Scroll to bottom.").clicked();
for i in 0..1000 {
ui.label(format!("Item {}", i));
}
if scroll_bottom {
ui.scroll_to_cursor(Align::BOTTOM);
}
});
Add a Widget
to this Ui
at a location dependent on the current Layout
.
The returned Response
can be used to check for interactions,
as well as adding tooltips using Response::on_hover_text
.
See also Self::add_sized
and Self::put
.
let response = ui.add(egui::Slider::new(&mut my_value, 0..=100));
response.on_hover_text("Drag me!");
Add a Widget
to this Ui
with a given size.
The widget will attempt to fit within the given size, but some widgets may overflow.
To fill all remaining area, use ui.add_sized(ui.available_size(), widget);
See also Self::add
and Self::put
.
ui.add_sized([40.0, 20.0], egui::DragValue::new(&mut my_value));
Add a Widget
to this Ui
at a specific location (manual layout).
See also Self::add
and Self::add_sized
.
Add extra space before the next widget.
The direction is dependent on the layout.
This will be in addition to the [Spacing::item_spacing
}.
Self::min_rect
will expand to contain the space.
Use add_space instead
Shortcut for add(Label::new(text))
See also Label
.
Shortcut for add(Label::new(text).text_color(color))
Shortcut for add(Label::new(text).heading())
Shortcut for add(Label::new(text).monospace())
Show text as monospace with a gray background.
Shortcut for add(Label::new(text).code())
Shortcut for add(Label::new(text).small())
Shortcut for add(Hyperlink::new(url))
See also Hyperlink
.
Shortcut for add(Hyperlink::new(url).text(label))
ui.hyperlink_to("egui on GitHub", "https://www.github.com/emilk/egui/");
See also Hyperlink
.
Use text_edit_singleline
or text_edit_multiline
No newlines (\n
) allowed. Pressing enter key will result in the TextEdit
losing focus (response.lost_focus
).
See also TextEdit
.
A TextEdit
for multiple lines. Pressing enter key will create a new line.
See also TextEdit
.
A TextEdit
for code editing.
This will be multiline, monospace, and will insert tabs instead of moving focus.
See also TextEdit::code_editor
.
Usage: if ui.button("Click me").clicked() { … }
Shortcut for add(Button::new(text))
See also Button
.
A button as small as normal body text.
Usage: if ui.small_button("Click me").clicked() { … }
Shortcut for add(Button::new(text).small())
Show a checkbox.
Show a RadioButton
.
Often you want to use Self::radio_value
instead.
Show a RadioButton
. It is selected if *current_value == selected_value
.
If clicked, selected_value
is assigned to *current_value
.
#[derive(PartialEq)]
enum Enum { First, Second, Third }
let mut my_enum = Enum::First;
ui.radio_value(&mut my_enum, Enum::First, "First");
// is equivalent to:
if ui.add(egui::RadioButton::new(my_enum == Enum::First, "First")).clicked() {
my_enum = Enum::First
}
Show a label which can be selected or not.
See also SelectableLabel
.
Show selectable text. It is selected if *current_value == selected_value
.
If clicked, selected_value
is assigned to *current_value
.
Example: ui.selectable_value(&mut my_enum, Enum::Alternative, "Alternative")
.
See also SelectableLabel
.
Modify an angle. The given angle should be in radians, but is shown to the user in degrees. The angle is NOT wrapped, so the user may select, for instance 720° = 2𝞃 = 4π
Modify an angle. The given angle should be in radians, but is shown to the user in fractions of one Tau (i.e. fractions of one turn). The angle is NOT wrapped, so the user may select, for instance 2𝞃 (720°)
Shows a button with the given color. If the user clicks the button, a full color picker is shown.
Shows a button with the given color. If the user clicks the button, a full color picker is shown.
Shows a button with the given color.
If the user clicks the button, a full color picker is shown.
The given color is in sRGB
space.
Shows a button with the given color. If the user clicks the button, a full color picker is shown. The given color is in linear RGB space.
Shows a button with the given color.
If the user clicks the button, a full color picker is shown.
The given color is in sRGBA
space with premultiplied alpha
Shows a button with the given color.
If the user clicks the button, a full color picker is shown.
The given color is in sRGBA
space without premultiplied alpha.
If unsure, what “premultiplied alpha” is, then this is probably the function you want to use.
Shows a button with the given color. If the user clicks the button, a full color picker is shown. The given color is in linear RGBA space with premultiplied alpha
Shows a button with the given color. If the user clicks the button, a full color picker is shown. The given color is in linear RGBA space without premultiplied alpha. If unsure, what “premultiplied alpha” is, then this is probably the function you want to use.
Put into a Frame::group
, visually grouping the contents together
ui.group(|ui|{
ui.label("Within a frame");
});
Se also Self::scope
.
Create a scoped child ui.
You can use this to temporarily change the Style
of a sub-region, for instance:
ui.scope(|ui|{
ui.spacing_mut().slider_width = 200.0; // Temporary change
// …
});
Renamed scope()
pub fn with_layer_id<R>(
&mut self,
layer_id: LayerId,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
pub fn with_layer_id<R>(
&mut self,
layer_id: LayerId,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
Redirect shapes to another paint layer.
pub fn add_custom_contents(
&mut self,
desired_size: Vec2,
add_contents: impl FnOnce(&mut Ui)
) -> Rect
Use ui.allocate_ui
instead
pub fn collapsing<R>(
&mut self,
heading: impl ToString,
add_contents: impl FnOnce(&mut Ui) -> R
) -> CollapsingResponse<R>
pub fn collapsing<R>(
&mut self,
heading: impl ToString,
add_contents: impl FnOnce(&mut Ui) -> R
) -> CollapsingResponse<R>
A CollapsingHeader
that starts out collapsed.
Create a child ui which is indented to the right.
The id_source
here be anything at all.
Start a ui with horizontal layout. After you have called this, the function registers the contents as any other widget.
Elements will be centered on the Y axis, i.e.
adjusted up and down to lie in the center of the horizontal layout.
The initial height is style.spacing.interact_size.y
.
Centering is almost always what you want if you are
planning to to mix widgets or use different types of text.
The returned Response
will only have checked for mouse hover
but can be used for tooltips (on_hover_text
).
It also contains the Rect
used by the horizontal layout.
ui.horizontal(|ui|{
ui.label("Same");
ui.label("row");
});
pub fn horizontal_for_text<R>(
&mut self,
text_style: TextStyle,
add_contents: impl FnOnce(&mut Ui) -> R
) -> InnerResponse<R>
👎 Deprecated: Use horizontal instead and set the desired spacing manually with ui.spacing_mut().item_spacing
pub fn horizontal_for_text<R>(
&mut self,
text_style: TextStyle,
add_contents: impl FnOnce(&mut Ui) -> R
) -> InnerResponse<R>
Use horizontal instead and set the desired spacing manually with ui.spacing_mut().item_spacing
Like horizontal
, but will set up the spacing to match that of a normal label.
In particular, the space between widgets is the same width as the space character.
You can still add any widgets to the layout (not only Labels).
pub fn horizontal_wrapped<R>(
&mut self,
add_contents: impl FnOnce(&mut Ui) -> R
) -> InnerResponse<R>
pub fn horizontal_wrapped<R>(
&mut self,
add_contents: impl FnOnce(&mut Ui) -> R
) -> InnerResponse<R>
Start a ui with horizontal layout that wraps to a new row
when it reaches the right edge of the max_size
.
After you have called this, the function registers the contents as any other widget.
Elements will be centered on the Y axis, i.e.
adjusted up and down to lie in the center of the horizontal layout.
The initial height is style.spacing.interact_size.y
.
Centering is almost always what you want if you are
planning to to mix widgets or use different types of text.
The returned Response
will only have checked for mouse hover
but can be used for tooltips (on_hover_text
).
It also contains the Rect
used by the horizontal layout.
pub fn horizontal_wrapped_for_text<R>(
&mut self,
text_style: TextStyle,
add_contents: impl FnOnce(&mut Ui) -> R
) -> InnerResponse<R>
👎 Deprecated: Use horizontal_wrapped instead and set the desired spacing manually with ui.spacing_mut().item_spacing
pub fn horizontal_wrapped_for_text<R>(
&mut self,
text_style: TextStyle,
add_contents: impl FnOnce(&mut Ui) -> R
) -> InnerResponse<R>
Use horizontal_wrapped instead and set the desired spacing manually with ui.spacing_mut().item_spacing
Like horizontal_wrapped
, but will set up the spacing and
line size to match that of a normal label.
In particular, the space between widgets is the same width as the space character and the line spacing is the same as that for text.
You can still add any widgets to the layout (not only Labels).
Start a ui with vertical layout. Widgets will be left-justified.
ui.vertical(|ui|{
ui.label("over");
ui.label("under");
});
pub fn vertical_centered<R>(
&mut self,
add_contents: impl FnOnce(&mut Ui) -> R
) -> InnerResponse<R>
pub fn vertical_centered<R>(
&mut self,
add_contents: impl FnOnce(&mut Ui) -> R
) -> InnerResponse<R>
Start a ui with vertical layout. Widgets will be horizontally centered.
ui.vertical_centered(|ui|{
ui.label("over");
ui.label("under");
});
pub fn vertical_centered_justified<R>(
&mut self,
add_contents: impl FnOnce(&mut Ui) -> R
) -> InnerResponse<R>
pub fn vertical_centered_justified<R>(
&mut self,
add_contents: impl FnOnce(&mut Ui) -> R
) -> InnerResponse<R>
Start a ui with vertical layout. Widgets will be horizontally centered and justified (fill full width).
ui.vertical_centered_justified(|ui|{
ui.label("over");
ui.label("under");
});
pub fn with_layout<R>(
&mut self,
layout: Layout,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
pub fn with_layout<R>(
&mut self,
layout: Layout,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
The new layout will take up all available space.
Consider using Self::allocate_ui_with_layout
instead,
or the helpers [Self::horizontal]
, Self::vertical
, etc.
pub fn centered_and_justified<R>(
&mut self,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
pub fn centered_and_justified<R>(
&mut self,
add_contents: impl FnOnce(&mut Self) -> R
) -> InnerResponse<R>
This will make the next added widget centered and justified in the available space.
Move to the next row in a grid layout or wrapping layout. Otherwise does nothing.
Set row height in horizontal wrapping layout.
pub fn columns<F, R>(&mut self, num_columns: usize, add_contents: F) -> R where
F: FnOnce(&mut [Self]) -> R,
pub fn columns<F, R>(&mut self, num_columns: usize, add_contents: F) -> R where
F: FnOnce(&mut [Self]) -> R,
Temporarily split split an Ui into several columns.
ui.columns(2, |columns| {
columns[0].label("First column");
columns[1].label("Second column");
});
Shows where the next widget is going to be placed
Shows the given text where the next widget is to be placed
if when Context::set_debug_on_hover
has been turned on and the mouse is hovering the Ui.