egui/
ui.rs

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