Skip to main content

egui/
ui.rs

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