egui/
ui.rs

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