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