egui/ui_builder.rs
1use std::{hash::Hash, sync::Arc};
2
3use crate::{Id, LayerId, Layout, Rect, Sense, Style, UiStackInfo};
4
5#[allow(unused_imports)] // Used for doclinks
6use crate::Ui;
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 /// The sense will be registered below the Senses of any widgets contained in this [`Ui`], so
129 /// if the user clicks a button contained within this [`Ui`], that button will receive the click
130 /// instead.
131 ///
132 /// The response can be read early with [`Ui::response`].
133 #[inline]
134 pub fn sense(mut self, sense: Sense) -> Self {
135 self.sense = Some(sense);
136 self
137 }
138}