egui/
ui.rs

1#![warn(missing_docs)] // Let's keep `Ui` well-documented.
2#![allow(clippy::use_self)]
3
4use std::{any::Any, hash::Hash, sync::Arc};
5
6use epaint::mutex::RwLock;
7
8use crate::{
9    containers::{CollapsingHeader, CollapsingResponse, Frame},
10    ecolor::Hsva,
11    emath, epaint,
12    epaint::text::Fonts,
13    grid,
14    layout::{Direction, Layout},
15    menu,
16    menu::MenuState,
17    pass_state,
18    placer::Placer,
19    pos2, style,
20    util::IdTypeMap,
21    vec2, widgets,
22    widgets::{
23        color_picker, Button, Checkbox, DragValue, Hyperlink, Image, ImageSource, Label, Link,
24        RadioButton, SelectableLabel, Separator, Spinner, TextEdit, Widget,
25    },
26    Align, Color32, Context, CursorIcon, DragAndDrop, Id, InnerResponse, InputState, LayerId,
27    Memory, Order, Painter, PlatformOutput, Pos2, Rangef, Rect, Response, Rgba, RichText, Sense,
28    Style, TextStyle, TextWrapMode, UiBuilder, UiStack, UiStackInfo, Vec2, WidgetRect, WidgetText,
29};
30
31#[cfg(debug_assertions)]
32use crate::Stroke;
33// ----------------------------------------------------------------------------
34
35/// This is what you use to place widgets.
36///
37/// Represents a region of the screen with a type of layout (horizontal or vertical).
38///
39/// ```
40/// # egui::__run_test_ui(|ui| {
41/// ui.add(egui::Label::new("Hello World!"));
42/// ui.label("A shorter and more convenient way to add a label.");
43/// ui.horizontal(|ui| {
44///     ui.label("Add widgets");
45///     if ui.button("on the same row!").clicked() {
46///         /* … */
47///     }
48/// });
49/// # });
50/// ```
51pub struct Ui {
52    /// Generated based on id of parent ui together with an optional id salt.
53    ///
54    /// This should be stable from one frame to next
55    /// so it can be used as a source for storing state
56    /// (e.g. window position, or if a collapsing header is open).
57    ///
58    /// However, it is not necessarily globally unique.
59    /// For instance, sibling `Ui`s share the same [`Self::id`]
60    /// unless they where explicitly given different id salts using
61    /// [`UiBuilder::id_salt`].
62    id: Id,
63
64    /// This is a globally unique ID of this `Ui`,
65    /// based on where in the hierarchy of widgets this Ui is in.
66    ///
67    /// This means it is not _stable_, as it can change if new widgets
68    /// are added or removed prior to this one.
69    /// It should therefore only be used for transient interactions (clicks etc),
70    /// not for storing state over time.
71    unique_id: Id,
72
73    /// This is used to create a unique interact ID for some widgets.
74    ///
75    /// This value is based on where in the hierarchy of widgets this Ui is in,
76    /// and the value is increment with each added child widget.
77    /// This works as an Id source only as long as new widgets aren't added or removed.
78    /// They are therefore only good for Id:s that has no state.
79    next_auto_id_salt: u64,
80
81    /// Specifies paint layer, clip rectangle and a reference to [`Context`].
82    painter: Painter,
83
84    /// The [`Style`] (visuals, spacing, etc) of this ui.
85    /// Commonly many [`Ui`]:s share the same [`Style`].
86    /// The [`Ui`] implements copy-on-write for this.
87    style: Arc<Style>,
88
89    /// Handles the [`Ui`] size and the placement of new widgets.
90    placer: Placer,
91
92    /// If false we are unresponsive to input,
93    /// and all widgets will assume a gray style.
94    enabled: bool,
95
96    /// Set to true in special cases where we do one frame
97    /// where we size up the contents of the Ui, without actually showing it.
98    sizing_pass: bool,
99
100    /// Indicates whether this Ui belongs to a Menu.
101    menu_state: Option<Arc<RwLock<MenuState>>>,
102
103    /// The [`UiStack`] for this [`Ui`].
104    stack: Arc<UiStack>,
105
106    /// The sense for the ui background.
107    sense: Sense,
108
109    /// Whether [`Ui::remember_min_rect`] should be called when the [`Ui`] is dropped.
110    /// This is an optimization, so we don't call [`Ui::remember_min_rect`] multiple times at the
111    /// end of a [`Ui::scope`].
112    min_rect_already_remembered: bool,
113}
114
115impl Ui {
116    // ------------------------------------------------------------------------
117    // Creation:
118
119    /// Create a new top-level [`Ui`].
120    ///
121    /// Normally you would not use this directly, but instead use
122    /// [`crate::SidePanel`], [`crate::TopBottomPanel`], [`crate::CentralPanel`], [`crate::Window`] or [`crate::Area`].
123    pub fn new(ctx: Context, id: Id, ui_builder: UiBuilder) -> Self {
124        let UiBuilder {
125            id_salt,
126            ui_stack_info,
127            layer_id,
128            max_rect,
129            layout,
130            disabled,
131            invisible,
132            sizing_pass,
133            style,
134            sense,
135        } = ui_builder;
136
137        let layer_id = layer_id.unwrap_or(LayerId::background());
138
139        debug_assert!(
140            id_salt.is_none(),
141            "Top-level Ui:s should not have an id_salt"
142        );
143
144        let max_rect = max_rect.unwrap_or_else(|| ctx.screen_rect());
145        let clip_rect = max_rect;
146        let layout = layout.unwrap_or_default();
147        let disabled = disabled || invisible;
148        let style = style.unwrap_or_else(|| ctx.style());
149        let sense = sense.unwrap_or(Sense::hover());
150
151        let placer = Placer::new(max_rect, layout);
152        let ui_stack = UiStack {
153            id,
154            layout_direction: layout.main_dir,
155            info: ui_stack_info,
156            parent: None,
157            min_rect: placer.min_rect(),
158            max_rect: placer.max_rect(),
159        };
160        let mut ui = Ui {
161            id,
162            unique_id: id,
163            next_auto_id_salt: id.with("auto").value(),
164            painter: Painter::new(ctx, layer_id, clip_rect),
165            style,
166            placer,
167            enabled: true,
168            sizing_pass,
169            menu_state: None,
170            stack: Arc::new(ui_stack),
171            sense,
172            min_rect_already_remembered: false,
173        };
174
175        // Register in the widget stack early, to ensure we are behind all widgets we contain:
176        let start_rect = Rect::NOTHING; // This will be overwritten when `remember_min_rect` is called
177        ui.ctx().create_widget(
178            WidgetRect {
179                id: ui.unique_id,
180                layer_id: ui.layer_id(),
181                rect: start_rect,
182                interact_rect: start_rect,
183                sense,
184                enabled: ui.enabled,
185            },
186            true,
187        );
188
189        if disabled {
190            ui.disable();
191        }
192        if invisible {
193            ui.set_invisible();
194        }
195
196        ui
197    }
198
199    /// Create a new [`Ui`] at a specific region.
200    ///
201    /// Note: calling this function twice from the same [`Ui`] will create a conflict of id. Use
202    /// [`Self::scope`] if needed.
203    ///
204    /// When in doubt, use `None` for the `UiStackInfo` argument.
205    #[deprecated = "Use ui.new_child() instead"]
206    pub fn child_ui(
207        &mut self,
208        max_rect: Rect,
209        layout: Layout,
210        ui_stack_info: Option<UiStackInfo>,
211    ) -> Self {
212        self.new_child(
213            UiBuilder::new()
214                .max_rect(max_rect)
215                .layout(layout)
216                .ui_stack_info(ui_stack_info.unwrap_or_default()),
217        )
218    }
219
220    /// Create a new [`Ui`] at a specific region with a specific id.
221    ///
222    /// When in doubt, use `None` for the `UiStackInfo` argument.
223    #[deprecated = "Use ui.new_child() instead"]
224    pub fn child_ui_with_id_source(
225        &mut self,
226        max_rect: Rect,
227        layout: Layout,
228        id_salt: impl Hash,
229        ui_stack_info: Option<UiStackInfo>,
230    ) -> Self {
231        self.new_child(
232            UiBuilder::new()
233                .id_salt(id_salt)
234                .max_rect(max_rect)
235                .layout(layout)
236                .ui_stack_info(ui_stack_info.unwrap_or_default()),
237        )
238    }
239
240    /// Create a child `Ui` with the properties of the given builder.
241    ///
242    /// This is a very low-level function.
243    /// Usually you are better off using [`Self::scope_builder`].
244    ///
245    /// Note that calling this does not allocate any space in the parent `Ui`,
246    /// so after adding widgets to the child `Ui` you probably want to allocate
247    /// the [`Ui::min_rect`] of the child in the parent `Ui` using e.g.
248    /// [`Ui::advance_cursor_after_rect`].
249    pub fn new_child(&mut self, ui_builder: UiBuilder) -> Self {
250        let UiBuilder {
251            id_salt,
252            ui_stack_info,
253            layer_id,
254            max_rect,
255            layout,
256            disabled,
257            invisible,
258            sizing_pass,
259            style,
260            sense,
261        } = ui_builder;
262
263        let mut painter = self.painter.clone();
264
265        let id_salt = id_salt.unwrap_or_else(|| Id::from("child"));
266        let max_rect = max_rect.unwrap_or_else(|| self.available_rect_before_wrap());
267        let mut layout = layout.unwrap_or(*self.layout());
268        let enabled = self.enabled && !disabled && !invisible;
269        if let Some(layer_id) = layer_id {
270            painter.set_layer_id(layer_id);
271        }
272        if invisible {
273            painter.set_invisible();
274        }
275        let sizing_pass = self.sizing_pass || sizing_pass;
276        let style = style.unwrap_or_else(|| self.style.clone());
277        let sense = sense.unwrap_or(Sense::hover());
278
279        if sizing_pass {
280            // During the sizing pass we want widgets to use up as little space as possible,
281            // so that we measure the only the space we _need_.
282            layout.cross_justify = false;
283            if layout.cross_align == Align::Center {
284                layout.cross_align = Align::Min;
285            }
286        }
287
288        debug_assert!(!max_rect.any_nan());
289        let stable_id = self.id.with(id_salt);
290        let unique_id = stable_id.with(self.next_auto_id_salt);
291        let next_auto_id_salt = unique_id.value().wrapping_add(1);
292
293        self.next_auto_id_salt = self.next_auto_id_salt.wrapping_add(1);
294
295        let placer = Placer::new(max_rect, layout);
296        let ui_stack = UiStack {
297            id: unique_id,
298            layout_direction: layout.main_dir,
299            info: ui_stack_info,
300            parent: Some(self.stack.clone()),
301            min_rect: placer.min_rect(),
302            max_rect: placer.max_rect(),
303        };
304        let mut child_ui = Ui {
305            id: stable_id,
306            unique_id,
307            next_auto_id_salt,
308            painter,
309            style,
310            placer,
311            enabled,
312            sizing_pass,
313            menu_state: self.menu_state.clone(),
314            stack: Arc::new(ui_stack),
315            sense,
316            min_rect_already_remembered: false,
317        };
318
319        if disabled {
320            child_ui.disable();
321        }
322
323        // Register in the widget stack early, to ensure we are behind all widgets we contain:
324        let start_rect = Rect::NOTHING; // This will be overwritten when `remember_min_rect` is called
325        child_ui.ctx().create_widget(
326            WidgetRect {
327                id: child_ui.unique_id,
328                layer_id: child_ui.layer_id(),
329                rect: start_rect,
330                interact_rect: start_rect,
331                sense,
332                enabled: child_ui.enabled,
333            },
334            true,
335        );
336
337        child_ui
338    }
339
340    // -------------------------------------------------
341
342    /// Set to true in special cases where we do one frame
343    /// where we size up the contents of the Ui, without actually showing it.
344    ///
345    /// This will also turn the Ui invisible.
346    /// Should be called right after [`Self::new`], if at all.
347    #[inline]
348    #[deprecated = "Use UiBuilder.sizing_pass().invisible()"]
349    pub fn set_sizing_pass(&mut self) {
350        self.sizing_pass = true;
351        self.set_invisible();
352    }
353
354    /// Set to true in special cases where we do one frame
355    /// where we size up the contents of the Ui, without actually showing it.
356    #[inline]
357    pub fn is_sizing_pass(&self) -> bool {
358        self.sizing_pass
359    }
360
361    // -------------------------------------------------
362
363    /// Generated based on id of parent ui together with an optional id salt.
364    ///
365    /// This should be stable from one frame to next
366    /// so it can be used as a source for storing state
367    /// (e.g. window position, or if a collapsing header is open).
368    ///
369    /// However, it is not necessarily globally unique.
370    /// For instance, sibling `Ui`s share the same [`Self::id`]
371    /// unless they where explicitly given different id salts using
372    /// [`UiBuilder::id_salt`].
373    #[inline]
374    pub fn id(&self) -> Id {
375        self.id
376    }
377
378    /// This is a globally unique ID of this `Ui`,
379    /// based on where in the hierarchy of widgets this Ui is in.
380    ///
381    /// This means it is not _stable_, as it can change if new widgets
382    /// are added or removed prior to this one.
383    /// It should therefore only be used for transient interactions (clicks etc),
384    /// not for storing state over time.
385    #[inline]
386    pub fn unique_id(&self) -> Id {
387        self.unique_id
388    }
389
390    /// Style options for this [`Ui`] and its children.
391    ///
392    /// Note that this may be a different [`Style`] than that of [`Context::style`].
393    #[inline]
394    pub fn style(&self) -> &Arc<Style> {
395        &self.style
396    }
397
398    /// Mutably borrow internal [`Style`].
399    /// Changes apply to this [`Ui`] and its subsequent children.
400    ///
401    /// To set the style of all [`Ui`]:s, use [`Context::set_style_of`].
402    ///
403    /// Example:
404    /// ```
405    /// # egui::__run_test_ui(|ui| {
406    /// ui.style_mut().override_text_style = Some(egui::TextStyle::Heading);
407    /// # });
408    /// ```
409    pub fn style_mut(&mut self) -> &mut Style {
410        Arc::make_mut(&mut self.style) // clone-on-write
411    }
412
413    /// Changes apply to this [`Ui`] and its subsequent children.
414    ///
415    /// To set the visuals of all [`Ui`]:s, use [`Context::set_visuals_of`].
416    pub fn set_style(&mut self, style: impl Into<Arc<Style>>) {
417        self.style = style.into();
418    }
419
420    /// Reset to the default style set in [`Context`].
421    pub fn reset_style(&mut self) {
422        self.style = self.ctx().style();
423    }
424
425    /// The current spacing options for this [`Ui`].
426    /// Short for `ui.style().spacing`.
427    #[inline]
428    pub fn spacing(&self) -> &crate::style::Spacing {
429        &self.style.spacing
430    }
431
432    /// Mutably borrow internal [`Spacing`](crate::style::Spacing).
433    /// Changes apply to this [`Ui`] and its subsequent children.
434    ///
435    /// Example:
436    /// ```
437    /// # egui::__run_test_ui(|ui| {
438    /// ui.spacing_mut().item_spacing = egui::vec2(10.0, 2.0);
439    /// # });
440    /// ```
441    pub fn spacing_mut(&mut self) -> &mut crate::style::Spacing {
442        &mut self.style_mut().spacing
443    }
444
445    /// The current visuals settings of this [`Ui`].
446    /// Short for `ui.style().visuals`.
447    #[inline]
448    pub fn visuals(&self) -> &crate::Visuals {
449        &self.style.visuals
450    }
451
452    /// Mutably borrow internal `visuals`.
453    /// Changes apply to this [`Ui`] and its subsequent children.
454    ///
455    /// To set the visuals of all [`Ui`]:s, use [`Context::set_visuals_of`].
456    ///
457    /// Example:
458    /// ```
459    /// # egui::__run_test_ui(|ui| {
460    /// ui.visuals_mut().override_text_color = Some(egui::Color32::RED);
461    /// # });
462    /// ```
463    pub fn visuals_mut(&mut self) -> &mut crate::Visuals {
464        &mut self.style_mut().visuals
465    }
466
467    /// Get a reference to this [`Ui`]'s [`UiStack`].
468    #[inline]
469    pub fn stack(&self) -> &Arc<UiStack> {
470        &self.stack
471    }
472
473    /// Get a reference to the parent [`Context`].
474    #[inline]
475    pub fn ctx(&self) -> &Context {
476        self.painter.ctx()
477    }
478
479    /// Use this to paint stuff within this [`Ui`].
480    #[inline]
481    pub fn painter(&self) -> &Painter {
482        &self.painter
483    }
484
485    /// If `false`, the [`Ui`] does not allow any interaction and
486    /// the widgets in it will draw with a gray look.
487    #[inline]
488    pub fn is_enabled(&self) -> bool {
489        self.enabled
490    }
491
492    /// Calling `disable()` will cause the [`Ui`] to deny all future interaction
493    /// and all the widgets will draw with a gray look.
494    ///
495    /// Usually it is more convenient to use [`Self::add_enabled_ui`] or [`Self::add_enabled`].
496    ///
497    /// Note that once disabled, there is no way to re-enable the [`Ui`].
498    ///
499    /// ### Example
500    /// ```
501    /// # egui::__run_test_ui(|ui| {
502    /// # let mut enabled = true;
503    /// ui.group(|ui| {
504    ///     ui.checkbox(&mut enabled, "Enable subsection");
505    ///     if !enabled {
506    ///         ui.disable();
507    ///     }
508    ///     if ui.button("Button that is not always clickable").clicked() {
509    ///         /* … */
510    ///     }
511    /// });
512    /// # });
513    /// ```
514    pub fn disable(&mut self) {
515        self.enabled = false;
516        if self.is_visible() {
517            self.painter
518                .set_fade_to_color(Some(self.visuals().fade_out_to_color()));
519        }
520    }
521
522    /// Calling `set_enabled(false)` will cause the [`Ui`] to deny all future interaction
523    /// and all the widgets will draw with a gray look.
524    ///
525    /// Usually it is more convenient to use [`Self::add_enabled_ui`] or [`Self::add_enabled`].
526    ///
527    /// Calling `set_enabled(true)` has no effect - it will NOT re-enable the [`Ui`] once disabled.
528    ///
529    /// ### Example
530    /// ```
531    /// # egui::__run_test_ui(|ui| {
532    /// # let mut enabled = true;
533    /// ui.group(|ui| {
534    ///     ui.checkbox(&mut enabled, "Enable subsection");
535    ///     ui.set_enabled(enabled);
536    ///     if ui.button("Button that is not always clickable").clicked() {
537    ///         /* … */
538    ///     }
539    /// });
540    /// # });
541    /// ```
542    #[deprecated = "Use disable(), add_enabled_ui(), or add_enabled() instead"]
543    pub fn set_enabled(&mut self, enabled: bool) {
544        if !enabled {
545            self.disable();
546        }
547    }
548
549    /// If `false`, any widgets added to the [`Ui`] will be invisible and non-interactive.
550    ///
551    /// This is `false` if any parent had [`UiBuilder::invisible`]
552    /// or if [`Context::will_discard`].
553    #[inline]
554    pub fn is_visible(&self) -> bool {
555        self.painter.is_visible()
556    }
557
558    /// Calling `set_invisible()` will cause all further widgets to be invisible,
559    /// yet still allocate space.
560    ///
561    /// The widgets will not be interactive (`set_invisible()` implies `disable()`).
562    ///
563    /// Once invisible, there is no way to make the [`Ui`] visible again.
564    ///
565    /// Usually it is more convenient to use [`Self::add_visible_ui`] or [`Self::add_visible`].
566    ///
567    /// ### Example
568    /// ```
569    /// # egui::__run_test_ui(|ui| {
570    /// # let mut visible = true;
571    /// ui.group(|ui| {
572    ///     ui.checkbox(&mut visible, "Show subsection");
573    ///     if !visible {
574    ///         ui.set_invisible();
575    ///     }
576    ///     if ui.button("Button that is not always shown").clicked() {
577    ///         /* … */
578    ///     }
579    /// });
580    /// # });
581    /// ```
582    pub fn set_invisible(&mut self) {
583        self.painter.set_invisible();
584        self.disable();
585    }
586
587    /// Calling `set_visible(false)` will cause all further widgets to be invisible,
588    /// yet still allocate space.
589    ///
590    /// The widgets will not be interactive (`set_visible(false)` implies `set_enabled(false)`).
591    ///
592    /// Calling `set_visible(true)` has no effect.
593    ///
594    /// ### Example
595    /// ```
596    /// # egui::__run_test_ui(|ui| {
597    /// # let mut visible = true;
598    /// ui.group(|ui| {
599    ///     ui.checkbox(&mut visible, "Show subsection");
600    ///     ui.set_visible(visible);
601    ///     if ui.button("Button that is not always shown").clicked() {
602    ///         /* … */
603    ///     }
604    /// });
605    /// # });
606    /// ```
607    #[deprecated = "Use set_invisible(), add_visible_ui(), or add_visible() instead"]
608    pub fn set_visible(&mut self, visible: bool) {
609        if !visible {
610            self.painter.set_invisible();
611            self.disable();
612        }
613    }
614
615    /// Make the widget in this [`Ui`] semi-transparent.
616    ///
617    /// `opacity` must be between 0.0 and 1.0, where 0.0 means fully transparent (i.e., invisible)
618    /// and 1.0 means fully opaque.
619    ///
620    /// ### Example
621    /// ```
622    /// # egui::__run_test_ui(|ui| {
623    /// ui.group(|ui| {
624    ///     ui.set_opacity(0.5);
625    ///     if ui.button("Half-transparent button").clicked() {
626    ///         /* … */
627    ///     }
628    /// });
629    /// # });
630    /// ```
631    ///
632    /// See also: [`Self::opacity`] and [`Self::multiply_opacity`].
633    pub fn set_opacity(&mut self, opacity: f32) {
634        self.painter.set_opacity(opacity);
635    }
636
637    /// Like [`Self::set_opacity`], but multiplies the given value with the current opacity.
638    ///
639    /// See also: [`Self::set_opacity`] and [`Self::opacity`].
640    pub fn multiply_opacity(&mut self, opacity: f32) {
641        self.painter.multiply_opacity(opacity);
642    }
643
644    /// Read the current opacity of the underlying painter.
645    ///
646    /// See also: [`Self::set_opacity`] and [`Self::multiply_opacity`].
647    #[inline]
648    pub fn opacity(&self) -> f32 {
649        self.painter.opacity()
650    }
651
652    /// Read the [`Layout`].
653    #[inline]
654    pub fn layout(&self) -> &Layout {
655        self.placer.layout()
656    }
657
658    /// Which wrap mode should the text use in this [`Ui`]?
659    ///
660    /// This is determined first by [`Style::wrap_mode`], and then by the layout of this [`Ui`].
661    pub fn wrap_mode(&self) -> TextWrapMode {
662        #[allow(deprecated)]
663        if let Some(wrap_mode) = self.style.wrap_mode {
664            wrap_mode
665        }
666        // `wrap` handling for backward compatibility
667        else if let Some(wrap) = self.style.wrap {
668            if wrap {
669                TextWrapMode::Wrap
670            } else {
671                TextWrapMode::Extend
672            }
673        } else if let Some(grid) = self.placer.grid() {
674            if grid.wrap_text() {
675                TextWrapMode::Wrap
676            } else {
677                TextWrapMode::Extend
678            }
679        } else {
680            let layout = self.layout();
681            if layout.is_vertical() || layout.is_horizontal() && layout.main_wrap() {
682                TextWrapMode::Wrap
683            } else {
684                TextWrapMode::Extend
685            }
686        }
687    }
688
689    /// Should text wrap in this [`Ui`]?
690    ///
691    /// This is determined first by [`Style::wrap_mode`], and then by the layout of this [`Ui`].
692    #[deprecated = "Use `wrap_mode` instead"]
693    pub fn wrap_text(&self) -> bool {
694        self.wrap_mode() == TextWrapMode::Wrap
695    }
696
697    /// How to vertically align text
698    #[inline]
699    pub fn text_valign(&self) -> Align {
700        self.style()
701            .override_text_valign
702            .unwrap_or_else(|| self.layout().vertical_align())
703    }
704
705    /// Create a painter for a sub-region of this Ui.
706    ///
707    /// The clip-rect of the returned [`Painter`] will be the intersection
708    /// of the given rectangle and the `clip_rect()` of this [`Ui`].
709    pub fn painter_at(&self, rect: Rect) -> Painter {
710        self.painter().with_clip_rect(rect)
711    }
712
713    /// Use this to paint stuff within this [`Ui`].
714    #[inline]
715    pub fn layer_id(&self) -> LayerId {
716        self.painter().layer_id()
717    }
718
719    /// The height of text of this text style
720    pub fn text_style_height(&self, style: &TextStyle) -> f32 {
721        self.fonts(|f| f.row_height(&style.resolve(self.style())))
722    }
723
724    /// Screen-space rectangle for clipping what we paint in this ui.
725    /// This is used, for instance, to avoid painting outside a window that is smaller than its contents.
726    #[inline]
727    pub fn clip_rect(&self) -> Rect {
728        self.painter.clip_rect()
729    }
730
731    /// Constrain the rectangle in which we can paint.
732    ///
733    /// Short for `ui.set_clip_rect(ui.clip_rect().intersect(new_clip_rect))`.
734    ///
735    /// See also: [`Self::clip_rect`] and [`Self::set_clip_rect`].
736    #[inline]
737    pub fn shrink_clip_rect(&mut self, new_clip_rect: Rect) {
738        self.painter.shrink_clip_rect(new_clip_rect);
739    }
740
741    /// Screen-space rectangle for clipping what we paint in this ui.
742    /// This is used, for instance, to avoid painting outside a window that is smaller than its contents.
743    ///
744    /// Warning: growing the clip rect might cause unexpected results!
745    /// When in doubt, use [`Self::shrink_clip_rect`] instead.
746    pub fn set_clip_rect(&mut self, clip_rect: Rect) {
747        self.painter.set_clip_rect(clip_rect);
748    }
749
750    /// Can be used for culling: if `false`, then no part of `rect` will be visible on screen.
751    ///
752    /// This is false if the whole `Ui` is invisible (see [`UiBuilder::invisible`])
753    /// or if [`Context::will_discard`] is true.
754    pub fn is_rect_visible(&self, rect: Rect) -> bool {
755        self.is_visible() && rect.intersects(self.clip_rect())
756    }
757}
758
759/// # Helpers for accessing the underlying [`Context`].
760/// These functions all lock the [`Context`] owned by this [`Ui`].
761/// Please see the documentation of [`Context`] for how locking works!
762impl Ui {
763    /// Read-only access to the shared [`InputState`].
764    ///
765    /// ```
766    /// # egui::__run_test_ui(|ui| {
767    /// if ui.input(|i| i.key_pressed(egui::Key::A)) {
768    ///     // …
769    /// }
770    /// # });
771    /// ```
772    #[inline]
773    pub fn input<R>(&self, reader: impl FnOnce(&InputState) -> R) -> R {
774        self.ctx().input(reader)
775    }
776
777    /// Read-write access to the shared [`InputState`].
778    #[inline]
779    pub fn input_mut<R>(&self, writer: impl FnOnce(&mut InputState) -> R) -> R {
780        self.ctx().input_mut(writer)
781    }
782
783    /// Read-only access to the shared [`Memory`].
784    #[inline]
785    pub fn memory<R>(&self, reader: impl FnOnce(&Memory) -> R) -> R {
786        self.ctx().memory(reader)
787    }
788
789    /// Read-write access to the shared [`Memory`].
790    #[inline]
791    pub fn memory_mut<R>(&self, writer: impl FnOnce(&mut Memory) -> R) -> R {
792        self.ctx().memory_mut(writer)
793    }
794
795    /// Read-only access to the shared [`IdTypeMap`], which stores superficial widget state.
796    #[inline]
797    pub fn data<R>(&self, reader: impl FnOnce(&IdTypeMap) -> R) -> R {
798        self.ctx().data(reader)
799    }
800
801    /// Read-write access to the shared [`IdTypeMap`], which stores superficial widget state.
802    #[inline]
803    pub fn data_mut<R>(&self, writer: impl FnOnce(&mut IdTypeMap) -> R) -> R {
804        self.ctx().data_mut(writer)
805    }
806
807    /// Read-only access to the shared [`PlatformOutput`].
808    ///
809    /// This is what egui outputs each frame.
810    ///
811    /// ```
812    /// # let mut ctx = egui::Context::default();
813    /// ctx.output_mut(|o| o.cursor_icon = egui::CursorIcon::Progress);
814    /// ```
815    #[inline]
816    pub fn output<R>(&self, reader: impl FnOnce(&PlatformOutput) -> R) -> R {
817        self.ctx().output(reader)
818    }
819
820    /// Read-write access to the shared [`PlatformOutput`].
821    ///
822    /// This is what egui outputs each frame.
823    ///
824    /// ```
825    /// # let mut ctx = egui::Context::default();
826    /// ctx.output_mut(|o| o.cursor_icon = egui::CursorIcon::Progress);
827    /// ```
828    #[inline]
829    pub fn output_mut<R>(&self, writer: impl FnOnce(&mut PlatformOutput) -> R) -> R {
830        self.ctx().output_mut(writer)
831    }
832
833    /// Read-only access to [`Fonts`].
834    #[inline]
835    pub fn fonts<R>(&self, reader: impl FnOnce(&Fonts) -> R) -> R {
836        self.ctx().fonts(reader)
837    }
838}
839
840// ------------------------------------------------------------------------
841
842/// # Sizes etc
843impl Ui {
844    /// Where and how large the [`Ui`] is already.
845    /// All widgets that have been added to this [`Ui`] fits within this rectangle.
846    ///
847    /// No matter what, the final Ui will be at least this large.
848    ///
849    /// This will grow as new widgets are added, but never shrink.
850    pub fn min_rect(&self) -> Rect {
851        self.placer.min_rect()
852    }
853
854    /// Size of content; same as `min_rect().size()`
855    pub fn min_size(&self) -> Vec2 {
856        self.min_rect().size()
857    }
858
859    /// New widgets will *try* to fit within this rectangle.
860    ///
861    /// Text labels will wrap to fit within `max_rect`.
862    /// Separator lines will span the `max_rect`.
863    ///
864    /// If a new widget doesn't fit within the `max_rect` then the
865    /// [`Ui`] will make room for it by expanding both `min_rect` and `max_rect`.
866    pub fn max_rect(&self) -> Rect {
867        self.placer.max_rect()
868    }
869
870    /// Used for animation, kind of hacky
871    pub(crate) fn force_set_min_rect(&mut self, min_rect: Rect) {
872        self.placer.force_set_min_rect(min_rect);
873    }
874
875    // ------------------------------------------------------------------------
876
877    /// Set the maximum size of the ui.
878    /// You won't be able to shrink it below the current minimum size.
879    pub fn set_max_size(&mut self, size: Vec2) {
880        self.set_max_width(size.x);
881        self.set_max_height(size.y);
882    }
883
884    /// Set the maximum width of the ui.
885    /// You won't be able to shrink it below the current minimum size.
886    pub fn set_max_width(&mut self, width: f32) {
887        self.placer.set_max_width(width);
888    }
889
890    /// Set the maximum height of the ui.
891    /// You won't be able to shrink it below the current minimum size.
892    pub fn set_max_height(&mut self, height: f32) {
893        self.placer.set_max_height(height);
894    }
895
896    // ------------------------------------------------------------------------
897
898    /// Set the minimum size of the ui.
899    /// This can't shrink the ui, only make it larger.
900    pub fn set_min_size(&mut self, size: Vec2) {
901        self.set_min_width(size.x);
902        self.set_min_height(size.y);
903    }
904
905    /// Set the minimum width of the ui.
906    /// This can't shrink the ui, only make it larger.
907    pub fn set_min_width(&mut self, width: f32) {
908        debug_assert!(0.0 <= width);
909        self.placer.set_min_width(width);
910    }
911
912    /// Set the minimum height of the ui.
913    /// This can't shrink the ui, only make it larger.
914    pub fn set_min_height(&mut self, height: f32) {
915        debug_assert!(0.0 <= height);
916        self.placer.set_min_height(height);
917    }
918
919    // ------------------------------------------------------------------------
920
921    /// Helper: shrinks the max width to the current width,
922    /// so further widgets will try not to be wider than previous widgets.
923    /// Useful for normal vertical layouts.
924    pub fn shrink_width_to_current(&mut self) {
925        self.set_max_width(self.min_rect().width());
926    }
927
928    /// Helper: shrinks the max height to the current height,
929    /// so further widgets will try not to be taller than previous widgets.
930    pub fn shrink_height_to_current(&mut self) {
931        self.set_max_height(self.min_rect().height());
932    }
933
934    /// Expand the `min_rect` and `max_rect` of this ui to include a child at the given rect.
935    pub fn expand_to_include_rect(&mut self, rect: Rect) {
936        self.placer.expand_to_include_rect(rect);
937    }
938
939    /// `ui.set_width_range(min..=max);` is equivalent to `ui.set_min_width(min); ui.set_max_width(max);`.
940    pub fn set_width_range(&mut self, width: impl Into<Rangef>) {
941        let width = width.into();
942        self.set_min_width(width.min);
943        self.set_max_width(width.max);
944    }
945
946    /// `ui.set_height_range(min..=max);` is equivalent to `ui.set_min_height(min); ui.set_max_height(max);`.
947    pub fn set_height_range(&mut self, height: impl Into<Rangef>) {
948        let height = height.into();
949        self.set_min_height(height.min);
950        self.set_max_height(height.max);
951    }
952
953    /// Set both the minimum and maximum width.
954    pub fn set_width(&mut self, width: f32) {
955        self.set_min_width(width);
956        self.set_max_width(width);
957    }
958
959    /// Set both the minimum and maximum height.
960    pub fn set_height(&mut self, height: f32) {
961        self.set_min_height(height);
962        self.set_max_height(height);
963    }
964
965    /// Ensure we are big enough to contain the given x-coordinate.
966    /// This is sometimes useful to expand a ui to stretch to a certain place.
967    pub fn expand_to_include_x(&mut self, x: f32) {
968        self.placer.expand_to_include_x(x);
969    }
970
971    /// Ensure we are big enough to contain the given y-coordinate.
972    /// This is sometimes useful to expand a ui to stretch to a certain place.
973    pub fn expand_to_include_y(&mut self, y: f32) {
974        self.placer.expand_to_include_y(y);
975    }
976
977    // ------------------------------------------------------------------------
978    // Layout related measures:
979
980    /// The available space at the moment, given the current cursor.
981    ///
982    /// This how much more space we can take up without overflowing our parent.
983    /// Shrinks as widgets allocate space and the cursor moves.
984    /// A small size should be interpreted as "as little as possible".
985    /// An infinite size should be interpreted as "as much as you want".
986    pub fn available_size(&self) -> Vec2 {
987        self.placer.available_size()
988    }
989
990    /// The available width at the moment, given the current cursor.
991    ///
992    /// See [`Self::available_size`] for more information.
993    pub fn available_width(&self) -> f32 {
994        self.available_size().x
995    }
996
997    /// The available height at the moment, given the current cursor.
998    ///
999    /// See [`Self::available_size`] for more information.
1000    pub fn available_height(&self) -> f32 {
1001        self.available_size().y
1002    }
1003
1004    /// In case of a wrapping layout, how much space is left on this row/column?
1005    ///
1006    /// If the layout does not wrap, this will return the same value as [`Self::available_size`].
1007    pub fn available_size_before_wrap(&self) -> Vec2 {
1008        self.placer.available_rect_before_wrap().size()
1009    }
1010
1011    /// In case of a wrapping layout, how much space is left on this row/column?
1012    ///
1013    /// If the layout does not wrap, this will return the same value as [`Self::available_size`].
1014    pub fn available_rect_before_wrap(&self) -> Rect {
1015        self.placer.available_rect_before_wrap()
1016    }
1017}
1018
1019/// # [`Id`] creation
1020impl Ui {
1021    /// Use this to generate widget ids for widgets that have persistent state in [`Memory`].
1022    pub fn make_persistent_id<IdSource>(&self, id_salt: IdSource) -> Id
1023    where
1024        IdSource: Hash,
1025    {
1026        self.id.with(&id_salt)
1027    }
1028
1029    /// This is the `Id` that will be assigned to the next widget added to this `Ui`.
1030    pub fn next_auto_id(&self) -> Id {
1031        Id::new(self.next_auto_id_salt)
1032    }
1033
1034    /// Same as `ui.next_auto_id().with(id_salt)`
1035    pub fn auto_id_with<IdSource>(&self, id_salt: IdSource) -> Id
1036    where
1037        IdSource: Hash,
1038    {
1039        Id::new(self.next_auto_id_salt).with(id_salt)
1040    }
1041
1042    /// Pretend like `count` widgets have been allocated.
1043    pub fn skip_ahead_auto_ids(&mut self, count: usize) {
1044        self.next_auto_id_salt = self.next_auto_id_salt.wrapping_add(count as u64);
1045    }
1046}
1047
1048/// # Interaction
1049impl Ui {
1050    /// Check for clicks, drags and/or hover on a specific region of this [`Ui`].
1051    pub fn interact(&self, rect: Rect, id: Id, sense: Sense) -> Response {
1052        self.ctx().create_widget(
1053            WidgetRect {
1054                id,
1055                layer_id: self.layer_id(),
1056                rect,
1057                interact_rect: self.clip_rect().intersect(rect),
1058                sense,
1059                enabled: self.enabled,
1060            },
1061            true,
1062        )
1063    }
1064
1065    /// Deprecated: use [`Self::interact`] instead.
1066    #[deprecated = "The contains_pointer argument is ignored. Use `ui.interact` instead."]
1067    pub fn interact_with_hovered(
1068        &self,
1069        rect: Rect,
1070        _contains_pointer: bool,
1071        id: Id,
1072        sense: Sense,
1073    ) -> Response {
1074        self.interact(rect, id, sense)
1075    }
1076
1077    /// Read the [`Ui`]s background [`Response`].
1078    /// It's [`Sense`] will be based on the [`UiBuilder::sense`] used to create this [`Ui`].
1079    ///
1080    /// The rectangle of the [`Response`] (and interactive area) will be [`Self::min_rect`]
1081    /// of the last pass.
1082    ///
1083    /// The very first time when the [`Ui`] is created, this will return a [`Response`] with a
1084    /// [`Rect`] of [`Rect::NOTHING`].
1085    pub fn response(&self) -> Response {
1086        // This is the inverse of Context::read_response. We prefer a response
1087        // based on last frame's widget rect since the one from this frame is Rect::NOTHING until
1088        // Ui::interact_bg is called or the Ui is dropped.
1089        self.ctx()
1090            .viewport(|viewport| {
1091                viewport
1092                    .prev_pass
1093                    .widgets
1094                    .get(self.unique_id)
1095                    .or_else(|| viewport.this_pass.widgets.get(self.unique_id))
1096                    .copied()
1097            })
1098            .map(|widget_rect| self.ctx().get_response(widget_rect))
1099            .expect(
1100                "Since we always call Context::create_widget in Ui::new, this should never be None",
1101            )
1102    }
1103
1104    /// Update the [`WidgetRect`] created in [`Ui::new`] or [`Ui::new_child`] with the current
1105    /// [`Ui::min_rect`].
1106    fn remember_min_rect(&mut self) -> Response {
1107        self.min_rect_already_remembered = true;
1108        // We remove the id from used_ids to prevent a duplicate id warning from showing
1109        // when the ui was created with `UiBuilder::sense`.
1110        // This is a bit hacky, is there a better way?
1111        self.ctx().pass_state_mut(|fs| {
1112            fs.used_ids.remove(&self.unique_id);
1113        });
1114        // This will update the WidgetRect that was first created in `Ui::new`.
1115        self.ctx().create_widget(
1116            WidgetRect {
1117                id: self.unique_id,
1118                layer_id: self.layer_id(),
1119                rect: self.min_rect(),
1120                interact_rect: self.clip_rect().intersect(self.min_rect()),
1121                sense: self.sense,
1122                enabled: self.enabled,
1123            },
1124            false,
1125        )
1126    }
1127
1128    /// Interact with the background of this [`Ui`],
1129    /// i.e. behind all the widgets.
1130    ///
1131    /// The rectangle of the [`Response`] (and interactive area) will be [`Self::min_rect`].
1132    #[deprecated = "Use UiBuilder::sense with Ui::response instead"]
1133    pub fn interact_bg(&self, sense: Sense) -> Response {
1134        // This will update the WidgetRect that was first created in `Ui::new`.
1135        self.interact(self.min_rect(), self.unique_id, sense)
1136    }
1137
1138    /// Is the pointer (mouse/touch) above this rectangle in this [`Ui`]?
1139    ///
1140    /// The `clip_rect` and layer of this [`Ui`] will be respected, so, for instance,
1141    /// if this [`Ui`] is behind some other window, this will always return `false`.
1142    ///
1143    /// However, this will NOT check if any other _widget_ in the same layer is covering this widget. For that, use [`Response::contains_pointer`] instead.
1144    pub fn rect_contains_pointer(&self, rect: Rect) -> bool {
1145        self.ctx()
1146            .rect_contains_pointer(self.layer_id(), self.clip_rect().intersect(rect))
1147    }
1148
1149    /// Is the pointer (mouse/touch) above the current [`Ui`]?
1150    ///
1151    /// Equivalent to `ui.rect_contains_pointer(ui.min_rect())`
1152    ///
1153    /// Note that this tests against the _current_ [`Ui::min_rect`].
1154    /// If you want to test against the final `min_rect`,
1155    /// use [`Self::response`] instead.
1156    pub fn ui_contains_pointer(&self) -> bool {
1157        self.rect_contains_pointer(self.min_rect())
1158    }
1159}
1160
1161/// # Allocating space: where do I put my widgets?
1162impl Ui {
1163    /// Allocate space for a widget and check for interaction in the space.
1164    /// Returns a [`Response`] which contains a rectangle, id, and interaction info.
1165    ///
1166    /// ## How sizes are negotiated
1167    /// Each widget should have a *minimum desired size* and a *desired size*.
1168    /// When asking for space, ask AT LEAST for your minimum, and don't ask for more than you need.
1169    /// If you want to fill the space, ask about [`Ui::available_size`] and use that.
1170    ///
1171    /// You may get MORE space than you asked for, for instance
1172    /// for justified layouts, like in menus.
1173    ///
1174    /// You will never get a rectangle that is smaller than the amount of space you asked for.
1175    ///
1176    /// ```
1177    /// # egui::__run_test_ui(|ui| {
1178    /// let response = ui.allocate_response(egui::vec2(100.0, 200.0), egui::Sense::click());
1179    /// if response.clicked() { /* … */ }
1180    /// ui.painter().rect_stroke(response.rect, 0.0, (1.0, egui::Color32::WHITE));
1181    /// # });
1182    /// ```
1183    pub fn allocate_response(&mut self, desired_size: Vec2, sense: Sense) -> Response {
1184        let (id, rect) = self.allocate_space(desired_size);
1185        let mut response = self.interact(rect, id, sense);
1186        response.intrinsic_size = Some(desired_size);
1187        response
1188    }
1189
1190    /// Returns a [`Rect`] with exactly what you asked for.
1191    ///
1192    /// The response rect will be larger if this is part of a justified layout or similar.
1193    /// This means that if this is a narrow widget in a wide justified layout, then
1194    /// the widget will react to interactions outside the returned [`Rect`].
1195    pub fn allocate_exact_size(&mut self, desired_size: Vec2, sense: Sense) -> (Rect, Response) {
1196        let response = self.allocate_response(desired_size, sense);
1197        let rect = self
1198            .placer
1199            .align_size_within_rect(desired_size, response.rect);
1200        (rect, response)
1201    }
1202
1203    /// Allocate at least as much space as needed, and interact with that rect.
1204    ///
1205    /// The returned [`Rect`] will be the same size as `Response::rect`.
1206    pub fn allocate_at_least(&mut self, desired_size: Vec2, sense: Sense) -> (Rect, Response) {
1207        let response = self.allocate_response(desired_size, sense);
1208        (response.rect, response)
1209    }
1210
1211    /// Reserve this much space and move the cursor.
1212    /// Returns where to put the widget.
1213    ///
1214    /// ## How sizes are negotiated
1215    /// Each widget should have a *minimum desired size* and a *desired size*.
1216    /// When asking for space, ask AT LEAST for your minimum, and don't ask for more than you need.
1217    /// If you want to fill the space, ask about [`Ui::available_size`] and use that.
1218    ///
1219    /// You may get MORE space than you asked for, for instance
1220    /// for justified layouts, like in menus.
1221    ///
1222    /// You will never get a rectangle that is smaller than the amount of space you asked for.
1223    ///
1224    /// Returns an automatic [`Id`] (which you can use for interaction) and the [`Rect`] of where to put your widget.
1225    ///
1226    /// ```
1227    /// # egui::__run_test_ui(|ui| {
1228    /// let (id, rect) = ui.allocate_space(egui::vec2(100.0, 200.0));
1229    /// let response = ui.interact(rect, id, egui::Sense::click());
1230    /// # });
1231    /// ```
1232    pub fn allocate_space(&mut self, desired_size: Vec2) -> (Id, Rect) {
1233        #[cfg(debug_assertions)]
1234        let original_available = self.available_size_before_wrap();
1235
1236        let rect = self.allocate_space_impl(desired_size);
1237
1238        #[cfg(debug_assertions)]
1239        {
1240            let too_wide = desired_size.x > original_available.x;
1241            let too_high = desired_size.y > original_available.y;
1242
1243            let debug_expand_width = self.style().debug.show_expand_width;
1244            let debug_expand_height = self.style().debug.show_expand_height;
1245
1246            if (debug_expand_width && too_wide) || (debug_expand_height && too_high) {
1247                self.painter
1248                    .rect_stroke(rect, 0.0, (1.0, Color32::LIGHT_BLUE));
1249
1250                let stroke = Stroke::new(2.5, Color32::from_rgb(200, 0, 0));
1251                let paint_line_seg = |a, b| self.painter().line_segment([a, b], stroke);
1252
1253                if debug_expand_width && too_wide {
1254                    paint_line_seg(rect.left_top(), rect.left_bottom());
1255                    paint_line_seg(rect.left_center(), rect.right_center());
1256                    paint_line_seg(
1257                        pos2(rect.left() + original_available.x, rect.top()),
1258                        pos2(rect.left() + original_available.x, rect.bottom()),
1259                    );
1260                    paint_line_seg(rect.right_top(), rect.right_bottom());
1261                }
1262
1263                if debug_expand_height && too_high {
1264                    paint_line_seg(rect.left_top(), rect.right_top());
1265                    paint_line_seg(rect.center_top(), rect.center_bottom());
1266                    paint_line_seg(rect.left_bottom(), rect.right_bottom());
1267                }
1268            }
1269        }
1270
1271        let id = Id::new(self.next_auto_id_salt);
1272        self.next_auto_id_salt = self.next_auto_id_salt.wrapping_add(1);
1273
1274        (id, rect)
1275    }
1276
1277    /// Reserve this much space and move the cursor.
1278    /// Returns where to put the widget.
1279    fn allocate_space_impl(&mut self, desired_size: Vec2) -> Rect {
1280        let item_spacing = self.spacing().item_spacing;
1281        let frame_rect = self.placer.next_space(desired_size, item_spacing);
1282        debug_assert!(!frame_rect.any_nan());
1283        let widget_rect = self.placer.justify_and_align(frame_rect, desired_size);
1284
1285        self.placer
1286            .advance_after_rects(frame_rect, widget_rect, item_spacing);
1287
1288        register_rect(self, widget_rect);
1289
1290        widget_rect
1291    }
1292
1293    /// Allocate a specific part of the [`Ui`].
1294    ///
1295    /// Ignore the layout of the [`Ui`]: just put my widget here!
1296    /// The layout cursor will advance to past this `rect`.
1297    pub fn allocate_rect(&mut self, rect: Rect, sense: Sense) -> Response {
1298        let id = self.advance_cursor_after_rect(rect);
1299        self.interact(rect, id, sense)
1300    }
1301
1302    /// Allocate a rect without interacting with it.
1303    pub fn advance_cursor_after_rect(&mut self, rect: Rect) -> Id {
1304        debug_assert!(!rect.any_nan());
1305        let item_spacing = self.spacing().item_spacing;
1306        self.placer.advance_after_rects(rect, rect, item_spacing);
1307        register_rect(self, rect);
1308
1309        let id = Id::new(self.next_auto_id_salt);
1310        self.next_auto_id_salt = self.next_auto_id_salt.wrapping_add(1);
1311        id
1312    }
1313
1314    pub(crate) fn placer(&self) -> &Placer {
1315        &self.placer
1316    }
1317
1318    /// Where the next widget will be put.
1319    ///
1320    /// One side of this will always be infinite: the direction in which new widgets will be added.
1321    /// The opposing side is what is incremented.
1322    /// The crossing sides are initialized to `max_rect`.
1323    ///
1324    /// So one can think of `cursor` as a constraint on the available region.
1325    ///
1326    /// If something has already been added, this will point to `style.spacing.item_spacing` beyond the latest child.
1327    /// The cursor can thus be `style.spacing.item_spacing` pixels outside of the `min_rect`.
1328    pub fn cursor(&self) -> Rect {
1329        self.placer.cursor()
1330    }
1331
1332    pub(crate) fn set_cursor(&mut self, cursor: Rect) {
1333        self.placer.set_cursor(cursor);
1334    }
1335
1336    /// Where do we expect a zero-sized widget to be placed?
1337    pub fn next_widget_position(&self) -> Pos2 {
1338        self.placer.next_widget_position()
1339    }
1340
1341    /// Allocated the given space and then adds content to that space.
1342    /// If the contents overflow, more space will be allocated.
1343    /// When finished, the amount of space actually used (`min_rect`) will be allocated.
1344    /// So you can request a lot of space and then use less.
1345    #[inline]
1346    pub fn allocate_ui<R>(
1347        &mut self,
1348        desired_size: Vec2,
1349        add_contents: impl FnOnce(&mut Self) -> R,
1350    ) -> InnerResponse<R> {
1351        self.allocate_ui_with_layout(desired_size, *self.layout(), add_contents)
1352    }
1353
1354    /// Allocated the given space and then adds content to that space.
1355    /// If the contents overflow, more space will be allocated.
1356    /// When finished, the amount of space actually used (`min_rect`) will be allocated.
1357    /// So you can request a lot of space and then use less.
1358    #[inline]
1359    pub fn allocate_ui_with_layout<R>(
1360        &mut self,
1361        desired_size: Vec2,
1362        layout: Layout,
1363        add_contents: impl FnOnce(&mut Self) -> R,
1364    ) -> InnerResponse<R> {
1365        self.allocate_ui_with_layout_dyn(desired_size, layout, Box::new(add_contents))
1366    }
1367
1368    fn allocate_ui_with_layout_dyn<'c, R>(
1369        &mut self,
1370        desired_size: Vec2,
1371        layout: Layout,
1372        add_contents: Box<dyn FnOnce(&mut Self) -> R + 'c>,
1373    ) -> InnerResponse<R> {
1374        debug_assert!(desired_size.x >= 0.0 && desired_size.y >= 0.0);
1375        let item_spacing = self.spacing().item_spacing;
1376        let frame_rect = self.placer.next_space(desired_size, item_spacing);
1377        let child_rect = self.placer.justify_and_align(frame_rect, desired_size);
1378        self.allocate_new_ui(
1379            UiBuilder::new().max_rect(child_rect).layout(layout),
1380            add_contents,
1381        )
1382    }
1383
1384    /// Allocated the given rectangle and then adds content to that rectangle.
1385    ///
1386    /// If the contents overflow, more space will be allocated.
1387    /// When finished, the amount of space actually used (`min_rect`) will be allocated.
1388    /// So you can request a lot of space and then use less.
1389    #[deprecated = "Use `allocate_new_ui` instead"]
1390    pub fn allocate_ui_at_rect<R>(
1391        &mut self,
1392        max_rect: Rect,
1393        add_contents: impl FnOnce(&mut Self) -> R,
1394    ) -> InnerResponse<R> {
1395        self.allocate_new_ui(UiBuilder::new().max_rect(max_rect), add_contents)
1396    }
1397
1398    /// Allocated space (`UiBuilder::max_rect`) and then add content to it.
1399    ///
1400    /// If the contents overflow, more space will be allocated.
1401    /// When finished, the amount of space actually used (`min_rect`) will be allocated in the parent.
1402    /// So you can request a lot of space and then use less.
1403    pub fn allocate_new_ui<R>(
1404        &mut self,
1405        ui_builder: UiBuilder,
1406        add_contents: impl FnOnce(&mut Self) -> R,
1407    ) -> InnerResponse<R> {
1408        self.allocate_new_ui_dyn(ui_builder, Box::new(add_contents))
1409    }
1410
1411    fn allocate_new_ui_dyn<'c, R>(
1412        &mut self,
1413        ui_builder: UiBuilder,
1414        add_contents: Box<dyn FnOnce(&mut Self) -> R + 'c>,
1415    ) -> InnerResponse<R> {
1416        let mut child_ui = self.new_child(ui_builder);
1417        let inner = add_contents(&mut child_ui);
1418        let rect = child_ui.min_rect();
1419        let item_spacing = self.spacing().item_spacing;
1420        self.placer.advance_after_rects(rect, rect, item_spacing);
1421        register_rect(self, rect);
1422        let response = self.interact(rect, child_ui.unique_id, Sense::hover());
1423        InnerResponse::new(inner, response)
1424    }
1425
1426    /// Convenience function to get a region to paint on.
1427    ///
1428    /// Note that egui uses screen coordinates for everything.
1429    ///
1430    /// ```
1431    /// # use egui::*;
1432    /// # use std::f32::consts::TAU;
1433    /// # egui::__run_test_ui(|ui| {
1434    /// let size = Vec2::splat(16.0);
1435    /// let (response, painter) = ui.allocate_painter(size, Sense::hover());
1436    /// let rect = response.rect;
1437    /// let c = rect.center();
1438    /// let r = rect.width() / 2.0 - 1.0;
1439    /// let color = Color32::from_gray(128);
1440    /// let stroke = Stroke::new(1.0, color);
1441    /// painter.circle_stroke(c, r, stroke);
1442    /// painter.line_segment([c - vec2(0.0, r), c + vec2(0.0, r)], stroke);
1443    /// painter.line_segment([c, c + r * Vec2::angled(TAU * 1.0 / 8.0)], stroke);
1444    /// painter.line_segment([c, c + r * Vec2::angled(TAU * 3.0 / 8.0)], stroke);
1445    /// # });
1446    /// ```
1447    pub fn allocate_painter(&mut self, desired_size: Vec2, sense: Sense) -> (Response, Painter) {
1448        let response = self.allocate_response(desired_size, sense);
1449        let clip_rect = self.clip_rect().intersect(response.rect); // Make sure we don't paint out of bounds
1450        let painter = self.painter().with_clip_rect(clip_rect);
1451        (response, painter)
1452    }
1453}
1454
1455/// # Scrolling
1456impl Ui {
1457    /// Adjust the scroll position of any parent [`crate::ScrollArea`] so that the given [`Rect`] becomes visible.
1458    ///
1459    /// If `align` is [`Align::TOP`] it means "put the top of the rect at the top of the scroll area", etc.
1460    /// If `align` is `None`, it'll scroll enough to bring the cursor into view.
1461    ///
1462    /// See also: [`Response::scroll_to_me`], [`Ui::scroll_to_cursor`]. [`Ui::scroll_with_delta`]..
1463    ///
1464    /// ```
1465    /// # use egui::Align;
1466    /// # egui::__run_test_ui(|ui| {
1467    /// egui::ScrollArea::vertical().show(ui, |ui| {
1468    ///     // …
1469    ///     let response = ui.button("Center on me.");
1470    ///     if response.clicked() {
1471    ///         ui.scroll_to_rect(response.rect, Some(Align::Center));
1472    ///     }
1473    /// });
1474    /// # });
1475    /// ```
1476    pub fn scroll_to_rect(&self, rect: Rect, align: Option<Align>) {
1477        self.scroll_to_rect_animation(rect, align, self.style.scroll_animation);
1478    }
1479
1480    /// Same as [`Self::scroll_to_rect`], but allows you to specify the [`style::ScrollAnimation`].
1481    pub fn scroll_to_rect_animation(
1482        &self,
1483        rect: Rect,
1484        align: Option<Align>,
1485        animation: style::ScrollAnimation,
1486    ) {
1487        for d in 0..2 {
1488            let range = Rangef::new(rect.min[d], rect.max[d]);
1489            self.ctx().pass_state_mut(|state| {
1490                state.scroll_target[d] =
1491                    Some(pass_state::ScrollTarget::new(range, align, animation));
1492            });
1493        }
1494    }
1495
1496    /// Adjust the scroll position of any parent [`crate::ScrollArea`] so that the cursor (where the next widget goes) becomes visible.
1497    ///
1498    /// If `align` is [`Align::TOP`] it means "put the top of the rect at the top of the scroll area", etc.
1499    /// If `align` is not provided, it'll scroll enough to bring the cursor into view.
1500    ///
1501    /// See also: [`Response::scroll_to_me`], [`Ui::scroll_to_rect`]. [`Ui::scroll_with_delta`].
1502    ///
1503    /// ```
1504    /// # use egui::Align;
1505    /// # egui::__run_test_ui(|ui| {
1506    /// egui::ScrollArea::vertical().show(ui, |ui| {
1507    ///     let scroll_bottom = ui.button("Scroll to bottom.").clicked();
1508    ///     for i in 0..1000 {
1509    ///         ui.label(format!("Item {}", i));
1510    ///     }
1511    ///
1512    ///     if scroll_bottom {
1513    ///         ui.scroll_to_cursor(Some(Align::BOTTOM));
1514    ///     }
1515    /// });
1516    /// # });
1517    /// ```
1518    pub fn scroll_to_cursor(&self, align: Option<Align>) {
1519        self.scroll_to_cursor_animation(align, self.style.scroll_animation);
1520    }
1521
1522    /// Same as [`Self::scroll_to_cursor`], but allows you to specify the [`style::ScrollAnimation`].
1523    pub fn scroll_to_cursor_animation(
1524        &self,
1525        align: Option<Align>,
1526        animation: style::ScrollAnimation,
1527    ) {
1528        let target = self.next_widget_position();
1529        for d in 0..2 {
1530            let target = Rangef::point(target[d]);
1531            self.ctx().pass_state_mut(|state| {
1532                state.scroll_target[d] =
1533                    Some(pass_state::ScrollTarget::new(target, align, animation));
1534            });
1535        }
1536    }
1537
1538    /// Scroll this many points in the given direction, in the parent [`crate::ScrollArea`].
1539    ///
1540    /// The delta dictates how the _content_ (i.e. this UI) should move.
1541    ///
1542    /// A positive X-value indicates the content is being moved right,
1543    /// as when swiping right on a touch-screen or track-pad with natural scrolling.
1544    ///
1545    /// A positive Y-value indicates the content is being moved down,
1546    /// as when swiping down on a touch-screen or track-pad with natural scrolling.
1547    ///
1548    /// If this is called multiple times per frame for the same [`crate::ScrollArea`], the deltas will be summed.
1549    ///
1550    /// See also: [`Response::scroll_to_me`], [`Ui::scroll_to_rect`], [`Ui::scroll_to_cursor`]
1551    ///
1552    /// ```
1553    /// # use egui::{Align, Vec2};
1554    /// # egui::__run_test_ui(|ui| {
1555    /// let mut scroll_delta = Vec2::ZERO;
1556    /// if ui.button("Scroll down").clicked() {
1557    ///     scroll_delta.y -= 64.0; // move content up
1558    /// }
1559    /// egui::ScrollArea::vertical().show(ui, |ui| {
1560    ///     ui.scroll_with_delta(scroll_delta);
1561    ///     for i in 0..1000 {
1562    ///         ui.label(format!("Item {}", i));
1563    ///     }
1564    /// });
1565    /// # });
1566    /// ```
1567    pub fn scroll_with_delta(&self, delta: Vec2) {
1568        self.scroll_with_delta_animation(delta, self.style.scroll_animation);
1569    }
1570
1571    /// Same as [`Self::scroll_with_delta`], but allows you to specify the [`style::ScrollAnimation`].
1572    pub fn scroll_with_delta_animation(&self, delta: Vec2, animation: style::ScrollAnimation) {
1573        self.ctx().pass_state_mut(|state| {
1574            state.scroll_delta.0 += delta;
1575            state.scroll_delta.1 = animation;
1576        });
1577    }
1578}
1579
1580/// # Adding widgets
1581impl Ui {
1582    /// Add a [`Widget`] to this [`Ui`] at a location dependent on the current [`Layout`].
1583    ///
1584    /// The returned [`Response`] can be used to check for interactions,
1585    /// as well as adding tooltips using [`Response::on_hover_text`].
1586    ///
1587    /// See also [`Self::add_sized`] and [`Self::put`].
1588    ///
1589    /// ```
1590    /// # egui::__run_test_ui(|ui| {
1591    /// # let mut my_value = 42;
1592    /// let response = ui.add(egui::Slider::new(&mut my_value, 0..=100));
1593    /// response.on_hover_text("Drag me!");
1594    /// # });
1595    /// ```
1596    #[inline]
1597    pub fn add(&mut self, widget: impl Widget) -> Response {
1598        widget.ui(self)
1599    }
1600
1601    /// Add a [`Widget`] to this [`Ui`] with a given size.
1602    /// The widget will attempt to fit within the given size, but some widgets may overflow.
1603    ///
1604    /// To fill all remaining area, use `ui.add_sized(ui.available_size(), widget);`
1605    ///
1606    /// See also [`Self::add`] and [`Self::put`].
1607    ///
1608    /// ```
1609    /// # egui::__run_test_ui(|ui| {
1610    /// # let mut my_value = 42;
1611    /// ui.add_sized([40.0, 20.0], egui::DragValue::new(&mut my_value));
1612    /// # });
1613    /// ```
1614    pub fn add_sized(&mut self, max_size: impl Into<Vec2>, widget: impl Widget) -> Response {
1615        // TODO(emilk): configure to overflow to main_dir instead of centered overflow
1616        // to handle the bug mentioned at https://github.com/emilk/egui/discussions/318#discussioncomment-627578
1617        // and fixed in https://github.com/emilk/egui/commit/035166276322b3f2324bd8b97ffcedc63fa8419f
1618        //
1619        // Make sure we keep the same main direction since it changes e.g. how text is wrapped:
1620        let layout = Layout::centered_and_justified(self.layout().main_dir());
1621        self.allocate_ui_with_layout(max_size.into(), layout, |ui| ui.add(widget))
1622            .inner
1623    }
1624
1625    /// Add a [`Widget`] to this [`Ui`] at a specific location (manual layout).
1626    ///
1627    /// See also [`Self::add`] and [`Self::add_sized`].
1628    pub fn put(&mut self, max_rect: Rect, widget: impl Widget) -> Response {
1629        self.allocate_new_ui(
1630            UiBuilder::new()
1631                .max_rect(max_rect)
1632                .layout(Layout::centered_and_justified(Direction::TopDown)),
1633            |ui| ui.add(widget),
1634        )
1635        .inner
1636    }
1637
1638    /// Add a single [`Widget`] that is possibly disabled, i.e. greyed out and non-interactive.
1639    ///
1640    /// If you call `add_enabled` from within an already disabled [`Ui`],
1641    /// the widget will always be disabled, even if the `enabled` argument is true.
1642    ///
1643    /// See also [`Self::add_enabled_ui`] and [`Self::is_enabled`].
1644    ///
1645    /// ```
1646    /// # egui::__run_test_ui(|ui| {
1647    /// ui.add_enabled(false, egui::Button::new("Can't click this"));
1648    /// # });
1649    /// ```
1650    pub fn add_enabled(&mut self, enabled: bool, widget: impl Widget) -> Response {
1651        if self.is_enabled() && !enabled {
1652            let old_painter = self.painter.clone();
1653            self.disable();
1654            let response = self.add(widget);
1655            self.enabled = true;
1656            self.painter = old_painter;
1657            response
1658        } else {
1659            self.add(widget)
1660        }
1661    }
1662
1663    /// Add a section that is possibly disabled, i.e. greyed out and non-interactive.
1664    ///
1665    /// If you call `add_enabled_ui` from within an already disabled [`Ui`],
1666    /// the result will always be disabled, even if the `enabled` argument is true.
1667    ///
1668    /// See also [`Self::add_enabled`] and [`Self::is_enabled`].
1669    ///
1670    /// ### Example
1671    /// ```
1672    /// # egui::__run_test_ui(|ui| {
1673    /// # let mut enabled = true;
1674    /// ui.checkbox(&mut enabled, "Enable subsection");
1675    /// ui.add_enabled_ui(enabled, |ui| {
1676    ///     if ui.button("Button that is not always clickable").clicked() {
1677    ///         /* … */
1678    ///     }
1679    /// });
1680    /// # });
1681    /// ```
1682    pub fn add_enabled_ui<R>(
1683        &mut self,
1684        enabled: bool,
1685        add_contents: impl FnOnce(&mut Ui) -> R,
1686    ) -> InnerResponse<R> {
1687        self.scope(|ui| {
1688            if !enabled {
1689                ui.disable();
1690            }
1691            add_contents(ui)
1692        })
1693    }
1694
1695    /// Add a single [`Widget`] that is possibly invisible.
1696    ///
1697    /// An invisible widget still takes up the same space as if it were visible.
1698    ///
1699    /// If you call `add_visible` from within an already invisible [`Ui`],
1700    /// the widget will always be invisible, even if the `visible` argument is true.
1701    ///
1702    /// See also [`Self::add_visible_ui`], [`Self::set_visible`] and [`Self::is_visible`].
1703    ///
1704    /// ```
1705    /// # egui::__run_test_ui(|ui| {
1706    /// ui.add_visible(false, egui::Label::new("You won't see me!"));
1707    /// # });
1708    /// ```
1709    pub fn add_visible(&mut self, visible: bool, widget: impl Widget) -> Response {
1710        if self.is_visible() && !visible {
1711            // temporary make us invisible:
1712            let old_painter = self.painter.clone();
1713            let old_enabled = self.enabled;
1714
1715            self.set_invisible();
1716
1717            let response = self.add(widget);
1718
1719            self.painter = old_painter;
1720            self.enabled = old_enabled;
1721            response
1722        } else {
1723            self.add(widget)
1724        }
1725    }
1726
1727    /// Add a section that is possibly invisible, i.e. greyed out and non-interactive.
1728    ///
1729    /// An invisible ui still takes up the same space as if it were visible.
1730    ///
1731    /// If you call `add_visible_ui` from within an already invisible [`Ui`],
1732    /// the result will always be invisible, even if the `visible` argument is true.
1733    ///
1734    /// See also [`Self::add_visible`], [`Self::set_visible`] and [`Self::is_visible`].
1735    ///
1736    /// ### Example
1737    /// ```
1738    /// # egui::__run_test_ui(|ui| {
1739    /// # let mut visible = true;
1740    /// ui.checkbox(&mut visible, "Show subsection");
1741    /// ui.add_visible_ui(visible, |ui| {
1742    ///     ui.label("Maybe you see this, maybe you don't!");
1743    /// });
1744    /// # });
1745    /// ```
1746    #[deprecated = "Use 'ui.scope_builder' instead"]
1747    pub fn add_visible_ui<R>(
1748        &mut self,
1749        visible: bool,
1750        add_contents: impl FnOnce(&mut Ui) -> R,
1751    ) -> InnerResponse<R> {
1752        let mut ui_builder = UiBuilder::new();
1753        if !visible {
1754            ui_builder = ui_builder.invisible();
1755        }
1756        self.scope_builder(ui_builder, add_contents)
1757    }
1758
1759    /// Add extra space before the next widget.
1760    ///
1761    /// The direction is dependent on the layout.
1762    /// This will be in addition to the [`crate::style::Spacing::item_spacing`].
1763    ///
1764    /// [`Self::min_rect`] will expand to contain the space.
1765    #[inline]
1766    pub fn add_space(&mut self, amount: f32) {
1767        self.placer.advance_cursor(amount);
1768    }
1769
1770    /// Show some text.
1771    ///
1772    /// Shortcut for `add(Label::new(text))`
1773    ///
1774    /// See also [`Label`].
1775    ///
1776    /// ### Example
1777    /// ```
1778    /// # egui::__run_test_ui(|ui| {
1779    /// use egui::{RichText, FontId, Color32};
1780    /// ui.label("Normal text");
1781    /// ui.label(RichText::new("Large text").font(FontId::proportional(40.0)));
1782    /// ui.label(RichText::new("Red text").color(Color32::RED));
1783    /// # });
1784    /// ```
1785    #[inline]
1786    pub fn label(&mut self, text: impl Into<WidgetText>) -> Response {
1787        Label::new(text).ui(self)
1788    }
1789
1790    /// Show colored text.
1791    ///
1792    /// Shortcut for `ui.label(RichText::new(text).color(color))`
1793    pub fn colored_label(
1794        &mut self,
1795        color: impl Into<Color32>,
1796        text: impl Into<RichText>,
1797    ) -> Response {
1798        Label::new(text.into().color(color)).ui(self)
1799    }
1800
1801    /// Show large text.
1802    ///
1803    /// Shortcut for `ui.label(RichText::new(text).heading())`
1804    pub fn heading(&mut self, text: impl Into<RichText>) -> Response {
1805        Label::new(text.into().heading()).ui(self)
1806    }
1807
1808    /// Show monospace (fixed width) text.
1809    ///
1810    /// Shortcut for `ui.label(RichText::new(text).monospace())`
1811    pub fn monospace(&mut self, text: impl Into<RichText>) -> Response {
1812        Label::new(text.into().monospace()).ui(self)
1813    }
1814
1815    /// Show text as monospace with a gray background.
1816    ///
1817    /// Shortcut for `ui.label(RichText::new(text).code())`
1818    pub fn code(&mut self, text: impl Into<RichText>) -> Response {
1819        Label::new(text.into().code()).ui(self)
1820    }
1821
1822    /// Show small text.
1823    ///
1824    /// Shortcut for `ui.label(RichText::new(text).small())`
1825    pub fn small(&mut self, text: impl Into<RichText>) -> Response {
1826        Label::new(text.into().small()).ui(self)
1827    }
1828
1829    /// Show text that stand out a bit (e.g. slightly brighter).
1830    ///
1831    /// Shortcut for `ui.label(RichText::new(text).strong())`
1832    pub fn strong(&mut self, text: impl Into<RichText>) -> Response {
1833        Label::new(text.into().strong()).ui(self)
1834    }
1835
1836    /// Show text that is weaker (fainter color).
1837    ///
1838    /// Shortcut for `ui.label(RichText::new(text).weak())`
1839    pub fn weak(&mut self, text: impl Into<RichText>) -> Response {
1840        Label::new(text.into().weak()).ui(self)
1841    }
1842
1843    /// Looks like a hyperlink.
1844    ///
1845    /// Shortcut for `add(Link::new(text))`.
1846    ///
1847    /// ```
1848    /// # egui::__run_test_ui(|ui| {
1849    /// if ui.link("Documentation").clicked() {
1850    ///     // …
1851    /// }
1852    /// # });
1853    /// ```
1854    ///
1855    /// See also [`Link`].
1856    #[must_use = "You should check if the user clicked this with `if ui.link(…).clicked() { … } "]
1857    pub fn link(&mut self, text: impl Into<WidgetText>) -> Response {
1858        Link::new(text).ui(self)
1859    }
1860
1861    /// Link to a web page.
1862    ///
1863    /// Shortcut for `add(Hyperlink::new(url))`.
1864    ///
1865    /// ```
1866    /// # egui::__run_test_ui(|ui| {
1867    /// ui.hyperlink("https://www.egui.rs/");
1868    /// # });
1869    /// ```
1870    ///
1871    /// See also [`Hyperlink`].
1872    pub fn hyperlink(&mut self, url: impl ToString) -> Response {
1873        Hyperlink::new(url).ui(self)
1874    }
1875
1876    /// Shortcut for `add(Hyperlink::from_label_and_url(label, url))`.
1877    ///
1878    /// ```
1879    /// # egui::__run_test_ui(|ui| {
1880    /// ui.hyperlink_to("egui on GitHub", "https://www.github.com/emilk/egui/");
1881    /// # });
1882    /// ```
1883    ///
1884    /// See also [`Hyperlink`].
1885    pub fn hyperlink_to(&mut self, label: impl Into<WidgetText>, url: impl ToString) -> Response {
1886        Hyperlink::from_label_and_url(label, url).ui(self)
1887    }
1888
1889    /// No newlines (`\n`) allowed. Pressing enter key will result in the [`TextEdit`] losing focus (`response.lost_focus`).
1890    ///
1891    /// See also [`TextEdit`].
1892    pub fn text_edit_singleline<S: widgets::text_edit::TextBuffer>(
1893        &mut self,
1894        text: &mut S,
1895    ) -> Response {
1896        TextEdit::singleline(text).ui(self)
1897    }
1898
1899    /// A [`TextEdit`] for multiple lines. Pressing enter key will create a new line.
1900    ///
1901    /// See also [`TextEdit`].
1902    pub fn text_edit_multiline<S: widgets::text_edit::TextBuffer>(
1903        &mut self,
1904        text: &mut S,
1905    ) -> Response {
1906        TextEdit::multiline(text).ui(self)
1907    }
1908
1909    /// A [`TextEdit`] for code editing.
1910    ///
1911    /// This will be multiline, monospace, and will insert tabs instead of moving focus.
1912    ///
1913    /// See also [`TextEdit::code_editor`].
1914    pub fn code_editor<S: widgets::text_edit::TextBuffer>(&mut self, text: &mut S) -> Response {
1915        self.add(TextEdit::multiline(text).code_editor())
1916    }
1917
1918    /// Usage: `if ui.button("Click me").clicked() { … }`
1919    ///
1920    /// Shortcut for `add(Button::new(text))`
1921    ///
1922    /// See also [`Button`].
1923    ///
1924    /// ```
1925    /// # egui::__run_test_ui(|ui| {
1926    /// if ui.button("Click me!").clicked() {
1927    ///     // …
1928    /// }
1929    ///
1930    /// # use egui::{RichText, Color32};
1931    /// if ui.button(RichText::new("delete").color(Color32::RED)).clicked() {
1932    ///     // …
1933    /// }
1934    /// # });
1935    /// ```
1936    #[must_use = "You should check if the user clicked this with `if ui.button(…).clicked() { … } "]
1937    #[inline]
1938    pub fn button(&mut self, text: impl Into<WidgetText>) -> Response {
1939        Button::new(text).ui(self)
1940    }
1941
1942    /// A button as small as normal body text.
1943    ///
1944    /// Usage: `if ui.small_button("Click me").clicked() { … }`
1945    ///
1946    /// Shortcut for `add(Button::new(text).small())`
1947    #[must_use = "You should check if the user clicked this with `if ui.small_button(…).clicked() { … } "]
1948    pub fn small_button(&mut self, text: impl Into<WidgetText>) -> Response {
1949        Button::new(text).small().ui(self)
1950    }
1951
1952    /// Show a checkbox.
1953    ///
1954    /// See also [`Self::toggle_value`].
1955    #[inline]
1956    pub fn checkbox(&mut self, checked: &mut bool, text: impl Into<WidgetText>) -> Response {
1957        Checkbox::new(checked, text).ui(self)
1958    }
1959
1960    /// Acts like a checkbox, but looks like a [`SelectableLabel`].
1961    ///
1962    /// Click to toggle to bool.
1963    ///
1964    /// See also [`Self::checkbox`].
1965    pub fn toggle_value(&mut self, selected: &mut bool, text: impl Into<WidgetText>) -> Response {
1966        let mut response = self.selectable_label(*selected, text);
1967        if response.clicked() {
1968            *selected = !*selected;
1969            response.mark_changed();
1970        }
1971        response
1972    }
1973
1974    /// Show a [`RadioButton`].
1975    /// Often you want to use [`Self::radio_value`] instead.
1976    #[must_use = "You should check if the user clicked this with `if ui.radio(…).clicked() { … } "]
1977    #[inline]
1978    pub fn radio(&mut self, selected: bool, text: impl Into<WidgetText>) -> Response {
1979        RadioButton::new(selected, text).ui(self)
1980    }
1981
1982    /// Show a [`RadioButton`]. It is selected if `*current_value == selected_value`.
1983    /// If clicked, `selected_value` is assigned to `*current_value`.
1984    ///
1985    /// ```
1986    /// # egui::__run_test_ui(|ui| {
1987    ///
1988    /// #[derive(PartialEq)]
1989    /// enum Enum { First, Second, Third }
1990    /// let mut my_enum = Enum::First;
1991    ///
1992    /// ui.radio_value(&mut my_enum, Enum::First, "First");
1993    ///
1994    /// // is equivalent to:
1995    ///
1996    /// if ui.add(egui::RadioButton::new(my_enum == Enum::First, "First")).clicked() {
1997    ///     my_enum = Enum::First
1998    /// }
1999    /// # });
2000    /// ```
2001    pub fn radio_value<Value: PartialEq>(
2002        &mut self,
2003        current_value: &mut Value,
2004        alternative: Value,
2005        text: impl Into<WidgetText>,
2006    ) -> Response {
2007        let mut response = self.radio(*current_value == alternative, text);
2008        if response.clicked() && *current_value != alternative {
2009            *current_value = alternative;
2010            response.mark_changed();
2011        }
2012        response
2013    }
2014
2015    /// Show a label which can be selected or not.
2016    ///
2017    /// See also [`SelectableLabel`] and [`Self::toggle_value`].
2018    #[must_use = "You should check if the user clicked this with `if ui.selectable_label(…).clicked() { … } "]
2019    pub fn selectable_label(&mut self, checked: bool, text: impl Into<WidgetText>) -> Response {
2020        SelectableLabel::new(checked, text).ui(self)
2021    }
2022
2023    /// Show selectable text. It is selected if `*current_value == selected_value`.
2024    /// If clicked, `selected_value` is assigned to `*current_value`.
2025    ///
2026    /// Example: `ui.selectable_value(&mut my_enum, Enum::Alternative, "Alternative")`.
2027    ///
2028    /// See also [`SelectableLabel`] and [`Self::toggle_value`].
2029    pub fn selectable_value<Value: PartialEq>(
2030        &mut self,
2031        current_value: &mut Value,
2032        selected_value: Value,
2033        text: impl Into<WidgetText>,
2034    ) -> Response {
2035        let mut response = self.selectable_label(*current_value == selected_value, text);
2036        if response.clicked() && *current_value != selected_value {
2037            *current_value = selected_value;
2038            response.mark_changed();
2039        }
2040        response
2041    }
2042
2043    /// Shortcut for `add(Separator::default())`
2044    ///
2045    /// See also [`Separator`].
2046    #[inline]
2047    pub fn separator(&mut self) -> Response {
2048        Separator::default().ui(self)
2049    }
2050
2051    /// Shortcut for `add(Spinner::new())`
2052    ///
2053    /// See also [`Spinner`].
2054    #[inline]
2055    pub fn spinner(&mut self) -> Response {
2056        Spinner::new().ui(self)
2057    }
2058
2059    /// Modify an angle. The given angle should be in radians, but is shown to the user in degrees.
2060    /// The angle is NOT wrapped, so the user may select, for instance 720° = 2𝞃 = 4π
2061    pub fn drag_angle(&mut self, radians: &mut f32) -> Response {
2062        let mut degrees = radians.to_degrees();
2063        let mut response = self.add(DragValue::new(&mut degrees).speed(1.0).suffix("°"));
2064
2065        // only touch `*radians` if we actually changed the degree value
2066        if degrees != radians.to_degrees() {
2067            *radians = degrees.to_radians();
2068            response.changed = true;
2069        }
2070
2071        response
2072    }
2073
2074    /// Modify an angle. The given angle should be in radians,
2075    /// but is shown to the user in fractions of one Tau (i.e. fractions of one turn).
2076    /// The angle is NOT wrapped, so the user may select, for instance 2𝞃 (720°)
2077    pub fn drag_angle_tau(&mut self, radians: &mut f32) -> Response {
2078        use std::f32::consts::TAU;
2079
2080        let mut taus = *radians / TAU;
2081        let mut response = self.add(DragValue::new(&mut taus).speed(0.01).suffix("τ"));
2082
2083        if self.style().explanation_tooltips {
2084            response =
2085                response.on_hover_text("1τ = one turn, 0.5τ = half a turn, etc. 0.25τ = 90°");
2086        }
2087
2088        // only touch `*radians` if we actually changed the value
2089        if taus != *radians / TAU {
2090            *radians = taus * TAU;
2091            response.changed = true;
2092        }
2093
2094        response
2095    }
2096
2097    /// Show an image available at the given `uri`.
2098    ///
2099    /// ⚠ This will do nothing unless you install some image loaders first!
2100    /// The easiest way to do this is via [`egui_extras::install_image_loaders`](https://docs.rs/egui_extras/latest/egui_extras/fn.install_image_loaders.html).
2101    ///
2102    /// The loaders handle caching image data, sampled textures, etc. across frames, so calling this is immediate-mode safe.
2103    ///
2104    /// ```
2105    /// # egui::__run_test_ui(|ui| {
2106    /// ui.image("https://picsum.photos/480");
2107    /// ui.image("file://assets/ferris.png");
2108    /// ui.image(egui::include_image!("../assets/ferris.png"));
2109    /// ui.add(
2110    ///     egui::Image::new(egui::include_image!("../assets/ferris.png"))
2111    ///         .max_width(200.0)
2112    ///         .rounding(10.0),
2113    /// );
2114    /// # });
2115    /// ```
2116    ///
2117    /// Using [`crate::include_image`] is often the most ergonomic, and the path
2118    /// will be resolved at compile-time and embedded in the binary.
2119    /// When using a "file://" url on the other hand, you need to make sure
2120    /// the files can be found in the right spot at runtime!
2121    ///
2122    /// See also [`crate::Image`], [`crate::ImageSource`].
2123    #[inline]
2124    pub fn image<'a>(&mut self, source: impl Into<ImageSource<'a>>) -> Response {
2125        Image::new(source).ui(self)
2126    }
2127}
2128
2129/// # Colors
2130impl Ui {
2131    /// Shows a button with the given color.
2132    /// If the user clicks the button, a full color picker is shown.
2133    pub fn color_edit_button_srgba(&mut self, srgba: &mut Color32) -> Response {
2134        color_picker::color_edit_button_srgba(self, srgba, color_picker::Alpha::BlendOrAdditive)
2135    }
2136
2137    /// Shows a button with the given color.
2138    /// If the user clicks the button, a full color picker is shown.
2139    pub fn color_edit_button_hsva(&mut self, hsva: &mut Hsva) -> Response {
2140        color_picker::color_edit_button_hsva(self, hsva, color_picker::Alpha::BlendOrAdditive)
2141    }
2142
2143    /// Shows a button with the given color.
2144    /// If the user clicks the button, a full color picker is shown.
2145    /// The given color is in `sRGB` space.
2146    pub fn color_edit_button_srgb(&mut self, srgb: &mut [u8; 3]) -> Response {
2147        color_picker::color_edit_button_srgb(self, srgb)
2148    }
2149
2150    /// Shows a button with the given color.
2151    /// If the user clicks the button, a full color picker is shown.
2152    /// The given color is in linear RGB space.
2153    pub fn color_edit_button_rgb(&mut self, rgb: &mut [f32; 3]) -> Response {
2154        color_picker::color_edit_button_rgb(self, rgb)
2155    }
2156
2157    /// Shows a button with the given color.
2158    /// If the user clicks the button, a full color picker is shown.
2159    /// The given color is in `sRGBA` space with premultiplied alpha
2160    pub fn color_edit_button_srgba_premultiplied(&mut self, srgba: &mut [u8; 4]) -> Response {
2161        let mut color = Color32::from_rgba_premultiplied(srgba[0], srgba[1], srgba[2], srgba[3]);
2162        let response = self.color_edit_button_srgba(&mut color);
2163        *srgba = color.to_array();
2164        response
2165    }
2166
2167    /// Shows a button with the given color.
2168    /// If the user clicks the button, a full color picker is shown.
2169    /// The given color is in `sRGBA` space without premultiplied alpha.
2170    /// If unsure, what "premultiplied alpha" is, then this is probably the function you want to use.
2171    pub fn color_edit_button_srgba_unmultiplied(&mut self, srgba: &mut [u8; 4]) -> Response {
2172        let mut rgba = Rgba::from_srgba_unmultiplied(srgba[0], srgba[1], srgba[2], srgba[3]);
2173        let response =
2174            color_picker::color_edit_button_rgba(self, &mut rgba, color_picker::Alpha::OnlyBlend);
2175        *srgba = rgba.to_srgba_unmultiplied();
2176        response
2177    }
2178
2179    /// Shows a button with the given color.
2180    /// If the user clicks the button, a full color picker is shown.
2181    /// The given color is in linear RGBA space with premultiplied alpha
2182    pub fn color_edit_button_rgba_premultiplied(&mut self, rgba_premul: &mut [f32; 4]) -> Response {
2183        let mut rgba = Rgba::from_rgba_premultiplied(
2184            rgba_premul[0],
2185            rgba_premul[1],
2186            rgba_premul[2],
2187            rgba_premul[3],
2188        );
2189        let response = color_picker::color_edit_button_rgba(
2190            self,
2191            &mut rgba,
2192            color_picker::Alpha::BlendOrAdditive,
2193        );
2194        *rgba_premul = rgba.to_array();
2195        response
2196    }
2197
2198    /// Shows a button with the given color.
2199    /// If the user clicks the button, a full color picker is shown.
2200    /// The given color is in linear RGBA space without premultiplied alpha.
2201    /// If unsure, what "premultiplied alpha" is, then this is probably the function you want to use.
2202    pub fn color_edit_button_rgba_unmultiplied(&mut self, rgba_unmul: &mut [f32; 4]) -> Response {
2203        let mut rgba = Rgba::from_rgba_unmultiplied(
2204            rgba_unmul[0],
2205            rgba_unmul[1],
2206            rgba_unmul[2],
2207            rgba_unmul[3],
2208        );
2209        let response =
2210            color_picker::color_edit_button_rgba(self, &mut rgba, color_picker::Alpha::OnlyBlend);
2211        *rgba_unmul = rgba.to_rgba_unmultiplied();
2212        response
2213    }
2214}
2215
2216/// # Adding Containers / Sub-uis:
2217impl Ui {
2218    /// Put into a [`Frame::group`], visually grouping the contents together
2219    ///
2220    /// ```
2221    /// # egui::__run_test_ui(|ui| {
2222    /// ui.group(|ui| {
2223    ///     ui.label("Within a frame");
2224    /// });
2225    /// # });
2226    /// ```
2227    ///
2228    /// See also [`Self::scope`].
2229    pub fn group<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse<R> {
2230        crate::Frame::group(self.style()).show(self, add_contents)
2231    }
2232
2233    /// Create a child Ui with an explicit [`Id`].
2234    ///
2235    /// ```
2236    /// # egui::__run_test_ui(|ui| {
2237    /// for i in 0..10 {
2238    ///     // ui.collapsing("Same header", |ui| { }); // this will cause an ID clash because of the same title!
2239    ///
2240    ///     ui.push_id(i, |ui| {
2241    ///         ui.collapsing("Same header", |ui| { }); // this is fine!
2242    ///     });
2243    /// }
2244    /// # });
2245    /// ```
2246    pub fn push_id<R>(
2247        &mut self,
2248        id_salt: impl Hash,
2249        add_contents: impl FnOnce(&mut Ui) -> R,
2250    ) -> InnerResponse<R> {
2251        self.scope_dyn(UiBuilder::new().id_salt(id_salt), Box::new(add_contents))
2252    }
2253
2254    /// Push another level onto the [`UiStack`].
2255    ///
2256    /// You can use this, for instance, to tag a group of widgets.
2257    #[deprecated = "Use 'ui.scope_builder' instead"]
2258    pub fn push_stack_info<R>(
2259        &mut self,
2260        ui_stack_info: UiStackInfo,
2261        add_contents: impl FnOnce(&mut Ui) -> R,
2262    ) -> InnerResponse<R> {
2263        self.scope_dyn(
2264            UiBuilder::new().ui_stack_info(ui_stack_info),
2265            Box::new(add_contents),
2266        )
2267    }
2268
2269    /// Create a scoped child ui.
2270    ///
2271    /// You can use this to temporarily change the [`Style`] of a sub-region, for instance:
2272    ///
2273    /// ```
2274    /// # egui::__run_test_ui(|ui| {
2275    /// ui.scope(|ui| {
2276    ///     ui.spacing_mut().slider_width = 200.0; // Temporary change
2277    ///     // …
2278    /// });
2279    /// # });
2280    /// ```
2281    pub fn scope<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse<R> {
2282        self.scope_dyn(UiBuilder::new(), Box::new(add_contents))
2283    }
2284
2285    /// Create a child, add content to it, and then allocate only what was used in the parent `Ui`.
2286    pub fn scope_builder<R>(
2287        &mut self,
2288        ui_builder: UiBuilder,
2289        add_contents: impl FnOnce(&mut Ui) -> R,
2290    ) -> InnerResponse<R> {
2291        self.scope_dyn(ui_builder, Box::new(add_contents))
2292    }
2293
2294    /// Create a child, add content to it, and then allocate only what was used in the parent `Ui`.
2295    pub fn scope_dyn<'c, R>(
2296        &mut self,
2297        ui_builder: UiBuilder,
2298        add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
2299    ) -> InnerResponse<R> {
2300        let next_auto_id_salt = self.next_auto_id_salt;
2301        let mut child_ui = self.new_child(ui_builder);
2302        self.next_auto_id_salt = next_auto_id_salt; // HACK: we want `scope` to only increment this once, so that `ui.scope` is equivalent to `ui.allocate_space`.
2303        let ret = add_contents(&mut child_ui);
2304        let response = child_ui.remember_min_rect();
2305        self.advance_cursor_after_rect(child_ui.min_rect());
2306        InnerResponse::new(ret, response)
2307    }
2308
2309    /// Redirect shapes to another paint layer.
2310    ///
2311    /// ```
2312    /// # use egui::{LayerId, Order, Id};
2313    /// # egui::__run_test_ui(|ui| {
2314    /// let layer_id = LayerId::new(Order::Tooltip, Id::new("my_floating_ui"));
2315    /// ui.with_layer_id(layer_id, |ui| {
2316    ///     ui.label("This is now in a different layer");
2317    /// });
2318    /// # });
2319    /// ```
2320    #[deprecated = "Use ui.scope_builder(UiBuilder::new().layer_id(…), …) instead"]
2321    pub fn with_layer_id<R>(
2322        &mut self,
2323        layer_id: LayerId,
2324        add_contents: impl FnOnce(&mut Self) -> R,
2325    ) -> InnerResponse<R> {
2326        self.scope_builder(UiBuilder::new().layer_id(layer_id), add_contents)
2327    }
2328
2329    /// A [`CollapsingHeader`] that starts out collapsed.
2330    ///
2331    /// The name must be unique within the current parent,
2332    /// or you need to use [`CollapsingHeader::id_salt`].
2333    pub fn collapsing<R>(
2334        &mut self,
2335        heading: impl Into<WidgetText>,
2336        add_contents: impl FnOnce(&mut Ui) -> R,
2337    ) -> CollapsingResponse<R> {
2338        CollapsingHeader::new(heading).show(self, add_contents)
2339    }
2340
2341    /// Create a child ui which is indented to the right.
2342    ///
2343    /// The `id_salt` here be anything at all.
2344    // TODO(emilk): remove `id_salt` argument?
2345    #[inline]
2346    pub fn indent<R>(
2347        &mut self,
2348        id_salt: impl Hash,
2349        add_contents: impl FnOnce(&mut Ui) -> R,
2350    ) -> InnerResponse<R> {
2351        self.indent_dyn(id_salt, Box::new(add_contents))
2352    }
2353
2354    fn indent_dyn<'c, R>(
2355        &mut self,
2356        id_salt: impl Hash,
2357        add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
2358    ) -> InnerResponse<R> {
2359        assert!(
2360            self.layout().is_vertical(),
2361            "You can only indent vertical layouts, found {:?}",
2362            self.layout()
2363        );
2364
2365        let indent = self.spacing().indent;
2366        let mut child_rect = self.placer.available_rect_before_wrap();
2367        child_rect.min.x += indent;
2368
2369        let mut child_ui = self.new_child(UiBuilder::new().id_salt(id_salt).max_rect(child_rect));
2370        let ret = add_contents(&mut child_ui);
2371
2372        let left_vline = self.visuals().indent_has_left_vline;
2373        let end_with_horizontal_line = self.spacing().indent_ends_with_horizontal_line;
2374
2375        if left_vline || end_with_horizontal_line {
2376            if end_with_horizontal_line {
2377                child_ui.add_space(4.0);
2378            }
2379
2380            let stroke = self.visuals().widgets.noninteractive.bg_stroke;
2381            let left_top = child_rect.min - 0.5 * indent * Vec2::X;
2382            let left_top = self.painter().round_pos_to_pixel_center(left_top);
2383            let left_bottom = pos2(left_top.x, child_ui.min_rect().bottom() - 2.0);
2384            let left_bottom = self.painter().round_pos_to_pixel_center(left_bottom);
2385
2386            if left_vline {
2387                // draw a faint line on the left to mark the indented section
2388                self.painter.line_segment([left_top, left_bottom], stroke);
2389            }
2390
2391            if end_with_horizontal_line {
2392                let fudge = 2.0; // looks nicer with button rounding in collapsing headers
2393                let right_bottom = pos2(child_ui.min_rect().right() - fudge, left_bottom.y);
2394                self.painter
2395                    .line_segment([left_bottom, right_bottom], stroke);
2396            }
2397        }
2398
2399        let response = self.allocate_rect(child_ui.min_rect(), Sense::hover());
2400        InnerResponse::new(ret, response)
2401    }
2402
2403    /// Start a ui with horizontal layout.
2404    /// After you have called this, the function registers the contents as any other widget.
2405    ///
2406    /// Elements will be centered on the Y axis, i.e.
2407    /// adjusted up and down to lie in the center of the horizontal layout.
2408    /// The initial height is `style.spacing.interact_size.y`.
2409    /// Centering is almost always what you want if you are
2410    /// planning to mix widgets or use different types of text.
2411    ///
2412    /// If you don't want the contents to be centered, use [`Self::horizontal_top`] instead.
2413    ///
2414    /// The returned [`Response`] will only have checked for mouse hover
2415    /// but can be used for tooltips (`on_hover_text`).
2416    /// It also contains the [`Rect`] used by the horizontal layout.
2417    ///
2418    /// ```
2419    /// # egui::__run_test_ui(|ui| {
2420    /// ui.horizontal(|ui| {
2421    ///     ui.label("Same");
2422    ///     ui.label("row");
2423    /// });
2424    /// # });
2425    /// ```
2426    ///
2427    /// See also [`Self::with_layout`] for more options.
2428    #[inline]
2429    pub fn horizontal<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse<R> {
2430        self.horizontal_with_main_wrap_dyn(false, Box::new(add_contents))
2431    }
2432
2433    /// Like [`Self::horizontal`], but allocates the full vertical height and then centers elements vertically.
2434    pub fn horizontal_centered<R>(
2435        &mut self,
2436        add_contents: impl FnOnce(&mut Ui) -> R,
2437    ) -> InnerResponse<R> {
2438        let initial_size = self.available_size_before_wrap();
2439        let layout = if self.placer.prefer_right_to_left() {
2440            Layout::right_to_left(Align::Center)
2441        } else {
2442            Layout::left_to_right(Align::Center)
2443        }
2444        .with_cross_align(Align::Center);
2445        self.allocate_ui_with_layout_dyn(initial_size, layout, Box::new(add_contents))
2446    }
2447
2448    /// Like [`Self::horizontal`], but aligns content with top.
2449    pub fn horizontal_top<R>(
2450        &mut self,
2451        add_contents: impl FnOnce(&mut Ui) -> R,
2452    ) -> InnerResponse<R> {
2453        let initial_size = self.available_size_before_wrap();
2454        let layout = if self.placer.prefer_right_to_left() {
2455            Layout::right_to_left(Align::Center)
2456        } else {
2457            Layout::left_to_right(Align::Center)
2458        }
2459        .with_cross_align(Align::Min);
2460        self.allocate_ui_with_layout_dyn(initial_size, layout, Box::new(add_contents))
2461    }
2462
2463    /// Start a ui with horizontal layout that wraps to a new row
2464    /// when it reaches the right edge of the `max_size`.
2465    /// After you have called this, the function registers the contents as any other widget.
2466    ///
2467    /// Elements will be centered on the Y axis, i.e.
2468    /// adjusted up and down to lie in the center of the horizontal layout.
2469    /// The initial height is `style.spacing.interact_size.y`.
2470    /// Centering is almost always what you want if you are
2471    /// planning to mix widgets or use different types of text.
2472    ///
2473    /// The returned [`Response`] will only have checked for mouse hover
2474    /// but can be used for tooltips (`on_hover_text`).
2475    /// It also contains the [`Rect`] used by the horizontal layout.
2476    ///
2477    /// See also [`Self::with_layout`] for more options.
2478    pub fn horizontal_wrapped<R>(
2479        &mut self,
2480        add_contents: impl FnOnce(&mut Ui) -> R,
2481    ) -> InnerResponse<R> {
2482        self.horizontal_with_main_wrap_dyn(true, Box::new(add_contents))
2483    }
2484
2485    fn horizontal_with_main_wrap_dyn<'c, R>(
2486        &mut self,
2487        main_wrap: bool,
2488        add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
2489    ) -> InnerResponse<R> {
2490        let initial_size = vec2(
2491            self.available_size_before_wrap().x,
2492            self.spacing().interact_size.y, // Assume there will be something interactive on the horizontal layout
2493        );
2494
2495        let layout = if self.placer.prefer_right_to_left() {
2496            Layout::right_to_left(Align::Center)
2497        } else {
2498            Layout::left_to_right(Align::Center)
2499        }
2500        .with_main_wrap(main_wrap);
2501
2502        self.allocate_ui_with_layout_dyn(initial_size, layout, add_contents)
2503    }
2504
2505    /// Start a ui with vertical layout.
2506    /// Widgets will be left-justified.
2507    ///
2508    /// ```
2509    /// # egui::__run_test_ui(|ui| {
2510    /// ui.vertical(|ui| {
2511    ///     ui.label("over");
2512    ///     ui.label("under");
2513    /// });
2514    /// # });
2515    /// ```
2516    ///
2517    /// See also [`Self::with_layout`] for more options.
2518    #[inline]
2519    pub fn vertical<R>(&mut self, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResponse<R> {
2520        self.allocate_new_ui(
2521            UiBuilder::new().layout(Layout::top_down(Align::Min)),
2522            add_contents,
2523        )
2524    }
2525
2526    /// Start a ui with vertical layout.
2527    /// Widgets will be horizontally centered.
2528    ///
2529    /// ```
2530    /// # egui::__run_test_ui(|ui| {
2531    /// ui.vertical_centered(|ui| {
2532    ///     ui.label("over");
2533    ///     ui.label("under");
2534    /// });
2535    /// # });
2536    /// ```
2537    #[inline]
2538    pub fn vertical_centered<R>(
2539        &mut self,
2540        add_contents: impl FnOnce(&mut Ui) -> R,
2541    ) -> InnerResponse<R> {
2542        self.allocate_new_ui(
2543            UiBuilder::new().layout(Layout::top_down(Align::Center)),
2544            add_contents,
2545        )
2546    }
2547
2548    /// Start a ui with vertical layout.
2549    /// Widgets will be horizontally centered and justified (fill full width).
2550    ///
2551    /// ```
2552    /// # egui::__run_test_ui(|ui| {
2553    /// ui.vertical_centered_justified(|ui| {
2554    ///     ui.label("over");
2555    ///     ui.label("under");
2556    /// });
2557    /// # });
2558    /// ```
2559    pub fn vertical_centered_justified<R>(
2560        &mut self,
2561        add_contents: impl FnOnce(&mut Ui) -> R,
2562    ) -> InnerResponse<R> {
2563        self.allocate_new_ui(
2564            UiBuilder::new().layout(Layout::top_down(Align::Center).with_cross_justify(true)),
2565            add_contents,
2566        )
2567    }
2568
2569    /// The new layout will take up all available space.
2570    ///
2571    /// ```
2572    /// # egui::__run_test_ui(|ui| {
2573    /// ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
2574    ///     ui.label("world!");
2575    ///     ui.label("Hello");
2576    /// });
2577    /// # });
2578    /// ```
2579    ///
2580    /// If you don't want to use up all available space, use [`Self::allocate_ui_with_layout`].
2581    ///
2582    /// See also the helpers [`Self::horizontal`], [`Self::vertical`], etc.
2583    #[inline]
2584    pub fn with_layout<R>(
2585        &mut self,
2586        layout: Layout,
2587        add_contents: impl FnOnce(&mut Self) -> R,
2588    ) -> InnerResponse<R> {
2589        self.allocate_new_ui(UiBuilder::new().layout(layout), add_contents)
2590    }
2591
2592    /// This will make the next added widget centered and justified in the available space.
2593    ///
2594    /// Only one widget may be added to the inner `Ui`!
2595    pub fn centered_and_justified<R>(
2596        &mut self,
2597        add_contents: impl FnOnce(&mut Self) -> R,
2598    ) -> InnerResponse<R> {
2599        self.allocate_new_ui(
2600            UiBuilder::new().layout(Layout::centered_and_justified(Direction::TopDown)),
2601            add_contents,
2602        )
2603    }
2604
2605    pub(crate) fn set_grid(&mut self, grid: grid::GridLayout) {
2606        self.placer.set_grid(grid);
2607    }
2608
2609    pub(crate) fn save_grid(&mut self) {
2610        self.placer.save_grid();
2611    }
2612
2613    pub(crate) fn is_grid(&self) -> bool {
2614        self.placer.is_grid()
2615    }
2616
2617    /// Move to the next row in a grid layout or wrapping layout.
2618    /// Otherwise does nothing.
2619    pub fn end_row(&mut self) {
2620        self.placer
2621            .end_row(self.spacing().item_spacing, &self.painter().clone());
2622    }
2623
2624    /// Set row height in horizontal wrapping layout.
2625    pub fn set_row_height(&mut self, height: f32) {
2626        self.placer.set_row_height(height);
2627    }
2628
2629    /// Temporarily split a [`Ui`] into several columns.
2630    ///
2631    /// ```
2632    /// # egui::__run_test_ui(|ui| {
2633    /// ui.columns(2, |columns| {
2634    ///     columns[0].label("First column");
2635    ///     columns[1].label("Second column");
2636    /// });
2637    /// # });
2638    /// ```
2639    #[inline]
2640    pub fn columns<R>(
2641        &mut self,
2642        num_columns: usize,
2643        add_contents: impl FnOnce(&mut [Self]) -> R,
2644    ) -> R {
2645        self.columns_dyn(num_columns, Box::new(add_contents))
2646    }
2647
2648    fn columns_dyn<'c, R>(
2649        &mut self,
2650        num_columns: usize,
2651        add_contents: Box<dyn FnOnce(&mut [Self]) -> R + 'c>,
2652    ) -> R {
2653        // TODO(emilk): ensure there is space
2654        let spacing = self.spacing().item_spacing.x;
2655        let total_spacing = spacing * (num_columns as f32 - 1.0);
2656        let column_width = (self.available_width() - total_spacing) / (num_columns as f32);
2657        let top_left = self.cursor().min;
2658
2659        let mut columns: Vec<Self> = (0..num_columns)
2660            .map(|col_idx| {
2661                let pos = top_left + vec2((col_idx as f32) * (column_width + spacing), 0.0);
2662                let child_rect = Rect::from_min_max(
2663                    pos,
2664                    pos2(pos.x + column_width, self.max_rect().right_bottom().y),
2665                );
2666                let mut column_ui = self.new_child(
2667                    UiBuilder::new()
2668                        .max_rect(child_rect)
2669                        .layout(Layout::top_down_justified(Align::LEFT)),
2670                );
2671                column_ui.set_width(column_width);
2672                column_ui
2673            })
2674            .collect();
2675
2676        let result = add_contents(&mut columns[..]);
2677
2678        let mut max_column_width = column_width;
2679        let mut max_height = 0.0;
2680        for column in &columns {
2681            max_column_width = max_column_width.max(column.min_rect().width());
2682            max_height = column.min_size().y.max(max_height);
2683        }
2684
2685        // Make sure we fit everything next frame:
2686        let total_required_width = total_spacing + max_column_width * (num_columns as f32);
2687
2688        let size = vec2(self.available_width().max(total_required_width), max_height);
2689        self.advance_cursor_after_rect(Rect::from_min_size(top_left, size));
2690        result
2691    }
2692
2693    /// Temporarily split a [`Ui`] into several columns.
2694    ///
2695    /// The same as [`Self::columns()`], but uses a constant for the column count.
2696    /// This allows for compile-time bounds checking, and makes the compiler happy.
2697    ///
2698    /// ```
2699    /// # egui::__run_test_ui(|ui| {
2700    /// ui.columns_const(|[col_1, col_2]| {
2701    ///     col_1.label("First column");
2702    ///     col_2.label("Second column");
2703    /// });
2704    /// # });
2705    /// ```
2706    #[inline]
2707    pub fn columns_const<const NUM_COL: usize, R>(
2708        &mut self,
2709        add_contents: impl FnOnce(&mut [Self; NUM_COL]) -> R,
2710    ) -> R {
2711        // TODO(emilk): ensure there is space
2712        let spacing = self.spacing().item_spacing.x;
2713        let total_spacing = spacing * (NUM_COL as f32 - 1.0);
2714        let column_width = (self.available_width() - total_spacing) / (NUM_COL as f32);
2715        let top_left = self.cursor().min;
2716
2717        let mut columns = std::array::from_fn(|col_idx| {
2718            let pos = top_left + vec2((col_idx as f32) * (column_width + spacing), 0.0);
2719            let child_rect = Rect::from_min_max(
2720                pos,
2721                pos2(pos.x + column_width, self.max_rect().right_bottom().y),
2722            );
2723            let mut column_ui = self.new_child(
2724                UiBuilder::new()
2725                    .max_rect(child_rect)
2726                    .layout(Layout::top_down_justified(Align::LEFT)),
2727            );
2728            column_ui.set_width(column_width);
2729            column_ui
2730        });
2731        let result = add_contents(&mut columns);
2732
2733        let mut max_column_width = column_width;
2734        let mut max_height = 0.0;
2735        for column in &columns {
2736            max_column_width = max_column_width.max(column.min_rect().width());
2737            max_height = column.min_size().y.max(max_height);
2738        }
2739
2740        // Make sure we fit everything next frame:
2741        let total_required_width = total_spacing + max_column_width * (NUM_COL as f32);
2742
2743        let size = vec2(self.available_width().max(total_required_width), max_height);
2744        self.advance_cursor_after_rect(Rect::from_min_size(top_left, size));
2745        result
2746    }
2747
2748    /// Create something that can be drag-and-dropped.
2749    ///
2750    /// The `id` needs to be globally unique.
2751    /// The payload is what will be dropped if the user starts dragging.
2752    ///
2753    /// In contrast to [`Response::dnd_set_drag_payload`],
2754    /// this function will paint the widget at the mouse cursor while the user is dragging.
2755    #[doc(alias = "drag and drop")]
2756    pub fn dnd_drag_source<Payload, R>(
2757        &mut self,
2758        id: Id,
2759        payload: Payload,
2760        add_contents: impl FnOnce(&mut Self) -> R,
2761    ) -> InnerResponse<R>
2762    where
2763        Payload: Any + Send + Sync,
2764    {
2765        let is_being_dragged = self.ctx().is_being_dragged(id);
2766
2767        if is_being_dragged {
2768            crate::DragAndDrop::set_payload(self.ctx(), payload);
2769
2770            // Paint the body to a new layer:
2771            let layer_id = LayerId::new(Order::Tooltip, id);
2772            let InnerResponse { inner, response } =
2773                self.scope_builder(UiBuilder::new().layer_id(layer_id), add_contents);
2774
2775            // Now we move the visuals of the body to where the mouse is.
2776            // Normally you need to decide a location for a widget first,
2777            // because otherwise that widget cannot interact with the mouse.
2778            // However, a dragged component cannot be interacted with anyway
2779            // (anything with `Order::Tooltip` always gets an empty [`Response`])
2780            // So this is fine!
2781
2782            if let Some(pointer_pos) = self.ctx().pointer_interact_pos() {
2783                let delta = pointer_pos - response.rect.center();
2784                self.ctx()
2785                    .transform_layer_shapes(layer_id, emath::TSTransform::from_translation(delta));
2786            }
2787
2788            InnerResponse::new(inner, response)
2789        } else {
2790            let InnerResponse { inner, response } = self.scope(add_contents);
2791
2792            // Check for drags:
2793            let dnd_response = self
2794                .interact(response.rect, id, Sense::drag())
2795                .on_hover_cursor(CursorIcon::Grab);
2796
2797            InnerResponse::new(inner, dnd_response | response)
2798        }
2799    }
2800
2801    /// Surround the given ui with a frame which
2802    /// changes colors when you can drop something onto it.
2803    ///
2804    /// Returns the dropped item, if it was released this frame.
2805    ///
2806    /// The given frame is used for its margins, but it color is ignored.
2807    #[doc(alias = "drag and drop")]
2808    pub fn dnd_drop_zone<Payload, R>(
2809        &mut self,
2810        frame: Frame,
2811        add_contents: impl FnOnce(&mut Ui) -> R,
2812    ) -> (InnerResponse<R>, Option<Arc<Payload>>)
2813    where
2814        Payload: Any + Send + Sync,
2815    {
2816        let is_anything_being_dragged = DragAndDrop::has_any_payload(self.ctx());
2817        let can_accept_what_is_being_dragged =
2818            DragAndDrop::has_payload_of_type::<Payload>(self.ctx());
2819
2820        let mut frame = frame.begin(self);
2821        let inner = add_contents(&mut frame.content_ui);
2822        let response = frame.allocate_space(self);
2823
2824        // NOTE: we use `response.contains_pointer` here instead of `hovered`, because
2825        // `hovered` is always false when another widget is being dragged.
2826        let style = if is_anything_being_dragged
2827            && can_accept_what_is_being_dragged
2828            && response.contains_pointer()
2829        {
2830            self.visuals().widgets.active
2831        } else {
2832            self.visuals().widgets.inactive
2833        };
2834
2835        let mut fill = style.bg_fill;
2836        let mut stroke = style.bg_stroke;
2837
2838        if is_anything_being_dragged && !can_accept_what_is_being_dragged {
2839            // When dragging something else, show that it can't be dropped here:
2840            fill = self.visuals().gray_out(fill);
2841            stroke.color = self.visuals().gray_out(stroke.color);
2842        }
2843
2844        frame.frame.fill = fill;
2845        frame.frame.stroke = stroke;
2846
2847        frame.paint(self);
2848
2849        let payload = response.dnd_release_payload::<Payload>();
2850
2851        (InnerResponse { inner, response }, payload)
2852    }
2853
2854    /// Create a new Scope and transform its contents via a [`emath::TSTransform`].
2855    /// This only affects visuals, inputs will not be transformed. So this is mostly useful
2856    /// to create visual effects on interactions, e.g. scaling a button on hover / click.
2857    ///
2858    /// Check out [`Context::set_transform_layer`] for a persistent transform that also affects
2859    /// inputs.
2860    pub fn with_visual_transform<R>(
2861        &mut self,
2862        transform: emath::TSTransform,
2863        add_contents: impl FnOnce(&mut Self) -> R,
2864    ) -> InnerResponse<R> {
2865        let start_idx = self.ctx().graphics(|gx| {
2866            gx.get(self.layer_id())
2867                .map_or(crate::layers::ShapeIdx(0), |l| l.next_idx())
2868        });
2869
2870        let r = self.scope_dyn(UiBuilder::new(), Box::new(add_contents));
2871
2872        self.ctx().graphics_mut(|g| {
2873            let list = g.entry(self.layer_id());
2874            let end_idx = list.next_idx();
2875            list.transform_range(start_idx, end_idx, transform);
2876        });
2877
2878        r
2879    }
2880}
2881
2882/// # Menus
2883impl Ui {
2884    /// Close the menu we are in (including submenus), if any.
2885    ///
2886    /// See also: [`Self::menu_button`] and [`Response::context_menu`].
2887    pub fn close_menu(&mut self) {
2888        if let Some(menu_state) = &mut self.menu_state {
2889            menu_state.write().close();
2890        }
2891        self.menu_state = None;
2892    }
2893
2894    pub(crate) fn set_menu_state(&mut self, menu_state: Option<Arc<RwLock<MenuState>>>) {
2895        self.menu_state = menu_state;
2896    }
2897
2898    #[inline]
2899    /// Create a menu button that when clicked will show the given menu.
2900    ///
2901    /// If called from within a menu this will instead create a button for a sub-menu.
2902    ///
2903    /// ```
2904    /// # egui::__run_test_ui(|ui| {
2905    /// ui.menu_button("My menu", |ui| {
2906    ///     ui.menu_button("My sub-menu", |ui| {
2907    ///         if ui.button("Close the menu").clicked() {
2908    ///             ui.close_menu();
2909    ///         }
2910    ///     });
2911    /// });
2912    /// # });
2913    /// ```
2914    ///
2915    /// See also: [`Self::close_menu`] and [`Response::context_menu`].
2916    pub fn menu_button<R>(
2917        &mut self,
2918        title: impl Into<WidgetText>,
2919        add_contents: impl FnOnce(&mut Ui) -> R,
2920    ) -> InnerResponse<Option<R>> {
2921        if let Some(menu_state) = self.menu_state.clone() {
2922            menu::submenu_button(self, menu_state, title, add_contents)
2923        } else {
2924            menu::menu_button(self, title, add_contents)
2925        }
2926    }
2927
2928    /// Create a menu button with an image that when clicked will show the given menu.
2929    ///
2930    /// If called from within a menu this will instead create a button for a sub-menu.
2931    ///
2932    /// ```ignore
2933    /// # egui::__run_test_ui(|ui| {
2934    /// let img = egui::include_image!("../assets/ferris.png");
2935    ///
2936    /// ui.menu_image_button(title, img, |ui| {
2937    ///     ui.menu_button("My sub-menu", |ui| {
2938    ///         if ui.button("Close the menu").clicked() {
2939    ///             ui.close_menu();
2940    ///         }
2941    ///     });
2942    /// });
2943    /// # });
2944    /// ```
2945    ///
2946    ///
2947    /// See also: [`Self::close_menu`] and [`Response::context_menu`].
2948    #[inline]
2949    pub fn menu_image_button<'a, R>(
2950        &mut self,
2951        image: impl Into<Image<'a>>,
2952        add_contents: impl FnOnce(&mut Ui) -> R,
2953    ) -> InnerResponse<Option<R>> {
2954        if let Some(menu_state) = self.menu_state.clone() {
2955            menu::submenu_button(self, menu_state, String::new(), add_contents)
2956        } else {
2957            menu::menu_custom_button(self, Button::image(image), add_contents)
2958        }
2959    }
2960
2961    /// Create a menu button with an image and a text that when clicked will show the given menu.
2962    ///
2963    /// If called from within a menu this will instead create a button for a sub-menu.
2964    ///
2965    /// ```
2966    /// # egui::__run_test_ui(|ui| {
2967    /// let img = egui::include_image!("../assets/ferris.png");
2968    /// let title = "My Menu";
2969    ///
2970    /// ui.menu_image_text_button(img, title, |ui| {
2971    ///     ui.menu_button("My sub-menu", |ui| {
2972    ///         if ui.button("Close the menu").clicked() {
2973    ///             ui.close_menu();
2974    ///         }
2975    ///     });
2976    /// });
2977    /// # });
2978    /// ```
2979    ///
2980    /// See also: [`Self::close_menu`] and [`Response::context_menu`].
2981    #[inline]
2982    pub fn menu_image_text_button<'a, R>(
2983        &mut self,
2984        image: impl Into<Image<'a>>,
2985        title: impl Into<WidgetText>,
2986        add_contents: impl FnOnce(&mut Ui) -> R,
2987    ) -> InnerResponse<Option<R>> {
2988        if let Some(menu_state) = self.menu_state.clone() {
2989            menu::submenu_button(self, menu_state, title, add_contents)
2990        } else {
2991            menu::menu_custom_button(self, Button::image_and_text(image, title), add_contents)
2992        }
2993    }
2994}
2995
2996// ----------------------------------------------------------------------------
2997
2998/// # Debug stuff
2999impl Ui {
3000    /// Shows where the next widget is going to be placed
3001    #[cfg(debug_assertions)]
3002    pub fn debug_paint_cursor(&self) {
3003        self.placer.debug_paint_cursor(&self.painter, "next");
3004    }
3005}
3006
3007impl Drop for Ui {
3008    fn drop(&mut self) {
3009        if !self.min_rect_already_remembered {
3010            // Register our final `min_rect`
3011            self.remember_min_rect();
3012        }
3013        #[cfg(debug_assertions)]
3014        register_rect(self, self.min_rect());
3015    }
3016}
3017
3018/// Show this rectangle to the user if certain debug options are set.
3019#[cfg(debug_assertions)]
3020fn register_rect(ui: &Ui, rect: Rect) {
3021    use emath::Align2;
3022
3023    let debug = ui.style().debug;
3024
3025    if debug.show_unaligned {
3026        let unaligned_line = |p0: Pos2, p1: Pos2| {
3027            let color = Color32::ORANGE;
3028            let font_id = TextStyle::Monospace.resolve(ui.style());
3029            ui.painter().line_segment([p0, p1], (1.0, color));
3030            ui.painter()
3031                .text(p0, Align2::LEFT_TOP, "Unaligned", font_id, color);
3032        };
3033
3034        if rect.left().fract() != 0.0 {
3035            unaligned_line(rect.left_top(), rect.left_bottom());
3036        }
3037        if rect.right().fract() != 0.0 {
3038            unaligned_line(rect.right_top(), rect.right_bottom());
3039        }
3040        if rect.top().fract() != 0.0 {
3041            unaligned_line(rect.left_top(), rect.right_top());
3042        }
3043        if rect.bottom().fract() != 0.0 {
3044            unaligned_line(rect.left_bottom(), rect.right_bottom());
3045        }
3046    }
3047
3048    let show_callstacks = debug.debug_on_hover
3049        || debug.debug_on_hover_with_all_modifiers && ui.input(|i| i.modifiers.all());
3050
3051    if !show_callstacks {
3052        return;
3053    }
3054
3055    if !ui.rect_contains_pointer(rect) {
3056        return;
3057    }
3058
3059    let is_clicking = ui.input(|i| i.pointer.could_any_button_be_click());
3060
3061    #[cfg(feature = "callstack")]
3062    let callstack = crate::callstack::capture();
3063
3064    #[cfg(not(feature = "callstack"))]
3065    let callstack = String::default();
3066
3067    // We only show one debug rectangle, or things get confusing:
3068    let debug_rect = pass_state::DebugRect {
3069        rect,
3070        callstack,
3071        is_clicking,
3072    };
3073
3074    let mut kept = false;
3075    ui.ctx().pass_state_mut(|fs| {
3076        if let Some(final_debug_rect) = &mut fs.debug_rect {
3077            // or maybe pick the one with deepest callstack?
3078            if final_debug_rect.rect.contains_rect(rect) {
3079                *final_debug_rect = debug_rect;
3080                kept = true;
3081            }
3082        } else {
3083            fs.debug_rect = Some(debug_rect);
3084            kept = true;
3085        }
3086    });
3087    if !kept {
3088        return;
3089    }
3090
3091    // ----------------------------------------------
3092
3093    // Use the debug-painter to avoid clip rect,
3094    // otherwise the content of the widget may cover what we paint here!
3095    let painter = ui.ctx().debug_painter();
3096
3097    if debug.hover_shows_next {
3098        ui.placer.debug_paint_cursor(&painter, "next");
3099    }
3100}
3101
3102#[cfg(not(debug_assertions))]
3103fn register_rect(_ui: &Ui, _rect: Rect) {}
3104
3105#[test]
3106fn ui_impl_send_sync() {
3107    fn assert_send_sync<T: Send + Sync>() {}
3108    assert_send_sync::<Ui>();
3109}