pub struct Ui { /* private fields */ }
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.

Create a new Ui at a specific region with a specific id.

A unique identity of this Ui.

Style options for this Ui and its children.

Note that this may be a different Style than that of Context::style.

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().override_text_style = Some(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);

Get a reference to the parent Context.

Use this to paint stuff within this Ui.

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.

Usually it is more convenient to use Self::add_enabled_ui or Self::add_enabled.

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.

👎Deprecated: Renamed is_visible

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.

Use this to paint stuff within this Ui.

The InputState of the Context associated with this Ui. Equivalent to .ctx().input().

Note that this locks the Context, so be careful with if-let bindings:

if let Some(pos) = { ui.input().pointer.hover_pos() } {
    // This is fine!
}

let pos = ui.input().pointer.hover_pos();
if let Some(pos) = pos {
    // This is also fine!
}

if let Some(pos) = ui.input().pointer.hover_pos() {
    // ⚠️ Using `ui` again here will lead to a dead-lock!
}

The InputState of the Context associated with this Ui. Equivalent to .ctx().input_mut().

Note that this locks the Context, so be careful with if-let bindings like for Self::input().

ui.input_mut().consume_key(egui::Modifiers::default(), egui::Key::Enter);

The Memory of the Context associated with this ui. Equivalent to .ctx().memory().

Stores superficial widget state.

The PlatformOutput of the Context associated with this ui. Equivalent to .ctx().output().

if ui.button("📋").clicked() {
    ui.output().copied_text = "some_text".to_string();
}

The Fonts of the Context associated with this ui. Equivalent to .ctx().fonts().

The height of text of this text style

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.

Can be used for culling: if false, then no part of rect will be visible on screen.

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.

Size of content; same as min_rect().size()

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.

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);.

ui.set_height_range(min..=max); is equivalent to ui.set_min_height(min); ui.set_max_height(max);.

Set both the minimum and maximum width.

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.

Ensure we are big enough to contain the given y-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?

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())

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 Ui::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 Ui::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.

Where the next widget will be put.

One side of this will always be infinite: the direction in which new widgets will be added. The opposing side is what is incremented. The crossing sides are initialized to max_rect.

So one can think of cursor as a constraint on the available region.

If something has already been added, this will point to style.spacing.item_spacing beyond the latest child. The cursor can thus be style.spacing.item_spacing pixels outside of the min_rect.

Where do we expect a zero-sized widget to be placed?

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.

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.

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);

Adjust the scroll position of any parent ScrollArea so that the given Rect becomes visible.

If align is None, it’ll scroll enough to bring the cursor into view.

See also: Response::scroll_to_me, Ui::scroll_to_cursor. Ui::scroll_with_delta..

egui::ScrollArea::vertical().show(ui, |ui| {
    // …
    let response = ui.button("Center on me.");
    if response.clicked() {
        ui.scroll_to_rect(response.rect, Some(Align::Center));
    }
});

Adjust the scroll position of any parent ScrollArea so that the cursor (where the next widget goes) becomes visible.

If align is not provided, it’ll scroll enough to bring the cursor into view.

See also: Response::scroll_to_me, Ui::scroll_to_rect. Ui::scroll_with_delta.

egui::ScrollArea::vertical().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(Some(Align::BOTTOM));
    }
});

Scroll this many points in the given direction, in the parent ScrollArea.

The delta dictates how the content (i.e. this UI) should move.

A positive X-value indicates the content is being moved right, as when swiping right on a touch-screen or track-pad with natural scrolling.

A positive Y-value indicates the content is being moved down, as when swiping down on a touch-screen or track-pad with natural scrolling.

/// See also: Response::scroll_to_me, Ui::scroll_to_rect, Ui::scroll_to_cursor

let mut scroll_delta = Vec2::ZERO;
if ui.button("Scroll down").clicked() {
    scroll_delta.y -= 64.0; // move content up
}
egui::ScrollArea::vertical().show(ui, |ui| {
    ui.scroll_with_delta(scroll_delta);
    for i in 0..1000 {
        ui.label(format!("Item {}", i));
    }
});

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 a single Widget that is possibly disabled, i.e. greyed out and non-interactive.

If you call add_enabled from within an already disabled Ui, the widget will always be disabled, even if the enabled argument is true.

See also Self::add_enabled_ui and Self::is_enabled.

ui.add_enabled(false, egui::Button::new("Can't click this"));

Add a section that is possibly disabled, i.e. greyed out and non-interactive.

If you call add_enabled_ui from within an already disabled Ui, the result will always be disabled, even if the enabled argument is true.

See also Self::add_enabled and Self::is_enabled.

Example
ui.checkbox(&mut enabled, "Enable subsection");
ui.add_enabled_ui(enabled, |ui| {
    if ui.button("Button that is not always clickable").clicked() {
        /* … */
    }
});

Add a single Widget that is possibly invisible.

An invisible widget still takes up the same space as if it were visible.

If you call add_visible from within an already invisible Ui, the widget will always be invisible, even if the visible argument is true.

See also Self::add_visible_ui, Self::set_visible and Self::is_visible.

ui.add_visible(false, egui::Label::new("You won't see me!"));

Add a section that is possibly invisible, i.e. greyed out and non-interactive.

An invisible ui still takes up the same space as if it were visible.

If you call add_visible_ui from within an already invisible Ui, the result will always be invisible, even if the visible argument is true.

See also Self::add_visible, Self::set_visible and Self::is_visible.

Example
ui.checkbox(&mut visible, "Show subsection");
ui.add_visible_ui(visible, |ui| {
    ui.label("Maybe you see this, maybe you don't!");
});

Add extra space before the next widget.

The direction is dependent on the layout. This will be in addition to the crate::style::Spacing::item_spacing.

Self::min_rect will expand to contain the space.

Show some text.

Shortcut for add(Label::new(text))

See also Label.

Example
use egui::{RichText, FontId, Color32};
ui.label("Normal text");
ui.label(RichText::new("Large text").font(FontId::proportional(40.0)));
ui.label(RichText::new("Red text").color(Color32::RED));

Show colored text.

Shortcut for ui.label(RichText::new(text).color(color))

Show large text.

Shortcut for ui.label(RichText::new(text).heading())

Show monospace (fixed width) text.

Shortcut for ui.label(RichText::new(text).monospace())

Show text as monospace with a gray background.

Shortcut for ui.label(RichText::new(text).code())

Show small text.

Shortcut for ui.label(RichText::new(text).small())

Show text that stand out a bit (e.g. slightly brighter).

Shortcut for ui.label(RichText::new(text).strong())

Show text that is weaker (fainter color).

Shortcut for ui.label(RichText::new(text).weak())

Looks like a hyperlink.

Shortcut for add(Link::new(text)).

if ui.link("Documentation").clicked() {
    // …
}

See also Link.

Link to a web page.

Shortcut for add(Hyperlink::new(url)).

ui.hyperlink("https://www.egui.rs/");

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.

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.

if ui.button("Click me!").clicked() {
    // …
}

if ui.button(RichText::new("delete").color(Color32::RED)).clicked() {
    // …
}

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.

See also Self::toggle_value.

Acts like a checkbox, but looks like a SelectableLabel.

Click to toggle to bool.

See also Self::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 and Self::toggle_value.

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 and Self::toggle_value.

Shortcut for add(Separator::default())

See also Separator.

Shortcut for add(Spinner::new())

See also Spinner.

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°)

Show an image here with the given size.

In order to display an image you must first acquire a TextureHandle. This is best done with egui_extras::RetainedImage or Context::load_texture.

struct MyImage {
    texture: Option<egui::TextureHandle>,
}

impl MyImage {
    fn ui(&mut self, ui: &mut egui::Ui) {
        let texture: &egui::TextureHandle = self.texture.get_or_insert_with(|| {
            // Load the texture only once.
            ui.ctx().load_texture(
                "my-image",
                egui::ColorImage::example(),
                egui::TextureFilter::Linear
            )
        });

        // Show the image:
        ui.image(texture, texture.size_vec2());
    }
}

Se also crate::Image and crate::ImageButton.

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 child Ui with an explicit Id.

for i in 0..10 {
    // ui.collapsing("Same header", |ui| { }); // this will cause an ID clash because of the same title!

    ui.push_id(i, |ui| {
        ui.collapsing("Same header", |ui| { }); // this is fine!
    });
}

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
    // …
});

Redirect shapes to another paint layer.

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.

If you don’t want the contents to be centered, use Self::horizontal_top instead.

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");
});

See also Self::with_layout for more options.

Like Self::horizontal, but allocates the full vertical height and then centers elements vertically.

Like Self::horizontal, but aligns content with top.

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.

See also Self::with_layout for more options.

Start a ui with vertical layout. Widgets will be left-justified.

ui.vertical(|ui| {
    ui.label("over");
    ui.label("under");
});

See also Self::with_layout for more options.

Start a ui with vertical layout. Widgets will be horizontally centered.

ui.vertical_centered(|ui| {
    ui.label("over");
    ui.label("under");
});

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");
});

The new layout will take up all available space.

ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
    ui.label("world!");
    ui.label("Hello");
});

If you don’t want to use up all available space, use Self::allocate_ui_with_layout.

See also the helpers Self::horizontal, Self::vertical, etc.

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.

Temporarily split split an Ui into several columns.

ui.columns(2, |columns| {
    columns[0].label("First column");
    columns[1].label("Second column");
});

Close the menu we are in (including submenus), if any.

See also: Self::menu_button and Response::context_menu.

Create a menu button that when clicked will show the given menu.

If called from within a menu this will instead create a button for a sub-menu.

ui.menu_button("My menu", |ui| {
    ui.menu_button("My sub-menu", |ui| {
        if ui.button("Close the menu").clicked() {
            ui.close_menu();
        }
    });
});

See also: Self::close_menu and Response::context_menu.

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.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Should always be Self
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.