egui/atomics/atom_ext.rs
1use crate::{Atom, FontSelection, Id, Ui};
2use emath::Vec2;
3
4/// A trait for conveniently building [`Atom`]s.
5///
6/// The functions are prefixed with `atom_` to avoid conflicts with e.g. [`crate::RichText::size`].
7pub trait AtomExt<'a> {
8 /// Set the [`Id`] for custom rendering.
9 ///
10 /// You can get the [`crate::Rect`] with the [`Id`] from [`crate::AtomLayoutResponse`] and use a
11 /// [`crate::Painter`] or [`Ui::place`] to add/draw some custom content.
12 fn atom_id(self, id: Id) -> Atom<'a>;
13
14 /// Set the atom to a fixed size.
15 ///
16 /// If [`Atom::grow`] is `true`, this will be the minimum width.
17 /// If [`Atom::shrink`] is `true`, this will be the maximum width.
18 /// If both are true, the width will have no effect.
19 ///
20 /// [`Self::atom_max_size`] will limit size.
21 ///
22 /// See [`crate::AtomKind`] docs to see how the size affects the different types.
23 fn atom_size(self, size: Vec2) -> Atom<'a>;
24
25 /// Grow this atom to the available space.
26 ///
27 /// This will affect the size of the [`Atom`] in the main direction. Since
28 /// [`crate::AtomLayout`] today only supports horizontal layout, it will affect the width.
29 ///
30 /// You can also combine this with [`Self::atom_shrink`] to make it always take exactly the
31 /// remaining space.
32 fn atom_grow(self, grow: bool) -> Atom<'a>;
33
34 /// Shrink this atom if there isn't enough space.
35 ///
36 /// This will affect the size of the [`Atom`] in the main direction. Since
37 /// [`crate::AtomLayout`] today only supports horizontal layout, it will affect the width.
38 ///
39 /// NOTE: Only a single [`Atom`] may shrink for each widget.
40 ///
41 /// If no atom was set to shrink and `wrap_mode != TextWrapMode::Extend`, the first
42 /// `AtomKind::Text` is set to shrink.
43 fn atom_shrink(self, shrink: bool) -> Atom<'a>;
44
45 /// Set the maximum size of this atom.
46 ///
47 /// Will not affect the space taken by `grow` (All atoms marked as grow will always grow
48 /// equally to fill the available space).
49 fn atom_max_size(self, max_size: Vec2) -> Atom<'a>;
50
51 /// Set the maximum width of this atom.
52 ///
53 /// Will not affect the space taken by `grow` (All atoms marked as grow will always grow
54 /// equally to fill the available space).
55 fn atom_max_width(self, max_width: f32) -> Atom<'a>;
56
57 /// Set the maximum height of this atom.
58 fn atom_max_height(self, max_height: f32) -> Atom<'a>;
59
60 /// Set the max height of this atom to match the font size.
61 ///
62 /// This is useful for e.g. limiting the height of icons in buttons.
63 fn atom_max_height_font_size(self, ui: &Ui) -> Atom<'a>
64 where
65 Self: Sized,
66 {
67 let font_selection = FontSelection::default();
68 let font_id = font_selection.resolve(ui.style());
69 let height = ui.fonts_mut(|f| f.row_height(&font_id));
70 self.atom_max_height(height)
71 }
72
73 /// Sets the [`emath::Align2`] of a single atom within its available space.
74 ///
75 /// Defaults to center-center.
76 fn atom_align(self, align: emath::Align2) -> Atom<'a>;
77}
78
79impl<'a, T> AtomExt<'a> for T
80where
81 T: Into<Atom<'a>> + Sized,
82{
83 fn atom_id(self, id: Id) -> Atom<'a> {
84 let mut atom = self.into();
85 atom.id = Some(id);
86 atom
87 }
88
89 fn atom_size(self, size: Vec2) -> Atom<'a> {
90 let mut atom = self.into();
91 atom.size = Some(size);
92 atom
93 }
94
95 fn atom_grow(self, grow: bool) -> Atom<'a> {
96 let mut atom = self.into();
97 atom.grow = grow;
98 atom
99 }
100
101 fn atom_shrink(self, shrink: bool) -> Atom<'a> {
102 let mut atom = self.into();
103 atom.shrink = shrink;
104 atom
105 }
106
107 fn atom_max_size(self, max_size: Vec2) -> Atom<'a> {
108 let mut atom = self.into();
109 atom.max_size = max_size;
110 atom
111 }
112
113 fn atom_max_width(self, max_width: f32) -> Atom<'a> {
114 let mut atom = self.into();
115 atom.max_size.x = max_width;
116 atom
117 }
118
119 fn atom_max_height(self, max_height: f32) -> Atom<'a> {
120 let mut atom = self.into();
121 atom.max_size.y = max_height;
122 atom
123 }
124
125 fn atom_align(self, align: emath::Align2) -> Atom<'a> {
126 let mut atom = self.into();
127 atom.align = align;
128 atom
129 }
130}