egui/ui_builder.rs
1use std::{hash::Hash, sync::Arc};
2
3use crate::ClosableTag;
4#[expect(unused_imports)] // Used for doclinks
5use crate::Ui;
6use crate::{Id, LayerId, Layout, Rect, Sense, Style, UiStackInfo};
7
8/// Build a [`Ui`] as the child of another [`Ui`].
9///
10/// By default, everything is inherited from the parent,
11/// except for `max_rect` which by default is set to
12/// the parent [`Ui::available_rect_before_wrap`].
13#[must_use]
14#[derive(Clone, Default)]
15pub struct UiBuilder {
16 pub id_salt: Option<Id>,
17 pub ui_stack_info: UiStackInfo,
18 pub layer_id: Option<LayerId>,
19 pub max_rect: Option<Rect>,
20 pub layout: Option<Layout>,
21 pub disabled: bool,
22 pub invisible: bool,
23 pub sizing_pass: bool,
24 pub style: Option<Arc<Style>>,
25 pub sense: Option<Sense>,
26}
27
28impl UiBuilder {
29 #[inline]
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 /// Seed the child `Ui` with this `id_salt`, which will be mixed
35 /// with the [`Ui::id`] of the parent.
36 ///
37 /// You should give each [`Ui`] an `id_salt` that is unique
38 /// within the parent, or give it none at all.
39 #[inline]
40 pub fn id_salt(mut self, id_salt: impl Hash) -> Self {
41 self.id_salt = Some(Id::new(id_salt));
42 self
43 }
44
45 /// Provide some information about the new `Ui` being built.
46 #[inline]
47 pub fn ui_stack_info(mut self, ui_stack_info: UiStackInfo) -> Self {
48 self.ui_stack_info = ui_stack_info;
49 self
50 }
51
52 /// Show the [`Ui`] in a different [`LayerId`] from its parent.
53 #[inline]
54 pub fn layer_id(mut self, layer_id: LayerId) -> Self {
55 self.layer_id = Some(layer_id);
56 self
57 }
58
59 /// Set the max rectangle, within which widgets will go.
60 ///
61 /// New widgets will *try* to fit within this rectangle.
62 ///
63 /// Text labels will wrap to fit within `max_rect`.
64 /// Separator lines will span the `max_rect`.
65 ///
66 /// If a new widget doesn't fit within the `max_rect` then the
67 /// [`Ui`] will make room for it by expanding both `min_rect` and
68 ///
69 /// If not set, this will be set to the parent
70 /// [`Ui::available_rect_before_wrap`].
71 #[inline]
72 pub fn max_rect(mut self, max_rect: Rect) -> Self {
73 self.max_rect = Some(max_rect);
74 self
75 }
76
77 /// Override the layout.
78 ///
79 /// Will otherwise be inherited from the parent.
80 #[inline]
81 pub fn layout(mut self, layout: Layout) -> Self {
82 self.layout = Some(layout);
83 self
84 }
85
86 /// Make the new `Ui` disabled, i.e. grayed-out and non-interactive.
87 ///
88 /// Note that if the parent `Ui` is disabled, the child will always be disabled.
89 #[inline]
90 pub fn disabled(mut self) -> Self {
91 self.disabled = true;
92 self
93 }
94
95 /// Make the contents invisible.
96 ///
97 /// Will also disable the `Ui` (see [`Self::disabled`]).
98 ///
99 /// If the parent `Ui` is invisible, the child will always be invisible.
100 #[inline]
101 pub fn invisible(mut self) -> Self {
102 self.invisible = true;
103 self.disabled = true;
104 self
105 }
106
107 /// Set to true in special cases where we do one frame
108 /// where we size up the contents of the Ui, without actually showing it.
109 ///
110 /// If the `sizing_pass` flag is set on the parent,
111 /// the child will inherit it automatically.
112 #[inline]
113 pub fn sizing_pass(mut self) -> Self {
114 self.sizing_pass = true;
115 self
116 }
117
118 /// Override the style.
119 ///
120 /// Otherwise will inherit the style of the parent.
121 #[inline]
122 pub fn style(mut self, style: impl Into<Arc<Style>>) -> Self {
123 self.style = Some(style.into());
124 self
125 }
126
127 /// Set if you want sense clicks and/or drags. Default is [`Sense::hover`].
128 ///
129 /// The sense will be registered below the Senses of any widgets contained in this [`Ui`], so
130 /// if the user clicks a button contained within this [`Ui`], that button will receive the click
131 /// instead.
132 ///
133 /// The response can be read early with [`Ui::response`].
134 #[inline]
135 pub fn sense(mut self, sense: Sense) -> Self {
136 self.sense = Some(sense);
137 self
138 }
139
140 /// Make this [`Ui`] closable.
141 ///
142 /// Calling [`Ui::close`] in a child [`Ui`] will mark this [`Ui`] for closing.
143 /// After [`Ui::close`] was called, [`Ui::should_close`] and [`crate::Response::should_close`] will
144 /// return `true` (for this frame).
145 ///
146 /// This works by adding a [`ClosableTag`] to the [`UiStackInfo`].
147 #[inline]
148 pub fn closable(mut self) -> Self {
149 self.ui_stack_info
150 .tags
151 .insert(ClosableTag::NAME, Some(Arc::new(ClosableTag::default())));
152 self
153 }
154}