egui/atomics/atom_ext.rs
1use crate::{Atom, FontSelection, 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 atom to a fixed size.
9 ///
10 /// If [`Atom::grow`] is `true`, this will be the minimum width.
11 /// If [`Atom::shrink`] is `true`, this will be the maximum width.
12 /// If both are true, the width will have no effect.
13 ///
14 /// [`Self::atom_max_size`] will limit size.
15 ///
16 /// See [`crate::AtomKind`] docs to see how the size affects the different types.
17 fn atom_size(self, size: Vec2) -> Atom<'a>;
18
19 /// Grow this atom to the available space.
20 ///
21 /// This will affect the size of the [`Atom`] in the main direction. Since
22 /// [`crate::AtomLayout`] today only supports horizontal layout, it will affect the width.
23 ///
24 /// You can also combine this with [`Self::atom_shrink`] to make it always take exactly the
25 /// remaining space.
26 fn atom_grow(self, grow: bool) -> Atom<'a>;
27
28 /// Shrink this atom if there isn't enough space.
29 ///
30 /// This will affect the size of the [`Atom`] in the main direction. Since
31 /// [`crate::AtomLayout`] today only supports horizontal layout, it will affect the width.
32 ///
33 /// NOTE: Only a single [`Atom`] may shrink for each widget.
34 ///
35 /// If no atom was set to shrink and `wrap_mode != TextWrapMode::Extend`, the first
36 /// `AtomKind::Text` is set to shrink.
37 fn atom_shrink(self, shrink: bool) -> Atom<'a>;
38
39 /// Set the maximum size of this atom.
40 ///
41 /// Will not affect the space taken by `grow` (All atoms marked as grow will always grow
42 /// equally to fill the available space).
43 fn atom_max_size(self, max_size: Vec2) -> Atom<'a>;
44
45 /// Set the maximum width 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_width(self, max_width: f32) -> Atom<'a>;
50
51 /// Set the maximum height of this atom.
52 fn atom_max_height(self, max_height: f32) -> Atom<'a>;
53
54 /// Set the max height of this atom to match the font size.
55 ///
56 /// This is useful for e.g. limiting the height of icons in buttons.
57 fn atom_max_height_font_size(self, ui: &Ui) -> Atom<'a>
58 where
59 Self: Sized,
60 {
61 let font_selection = FontSelection::default();
62 let font_id = font_selection.resolve(ui.style());
63 let height = ui.fonts(|f| f.row_height(&font_id));
64 self.atom_max_height(height)
65 }
66}
67
68impl<'a, T> AtomExt<'a> for T
69where
70 T: Into<Atom<'a>> + Sized,
71{
72 fn atom_size(self, size: Vec2) -> Atom<'a> {
73 let mut atom = self.into();
74 atom.size = Some(size);
75 atom
76 }
77
78 fn atom_grow(self, grow: bool) -> Atom<'a> {
79 let mut atom = self.into();
80 atom.grow = grow;
81 atom
82 }
83
84 fn atom_shrink(self, shrink: bool) -> Atom<'a> {
85 let mut atom = self.into();
86 atom.shrink = shrink;
87 atom
88 }
89
90 fn atom_max_size(self, max_size: Vec2) -> Atom<'a> {
91 let mut atom = self.into();
92 atom.max_size = max_size;
93 atom
94 }
95
96 fn atom_max_width(self, max_width: f32) -> Atom<'a> {
97 let mut atom = self.into();
98 atom.max_size.x = max_width;
99 atom
100 }
101
102 fn atom_max_height(self, max_height: f32) -> Atom<'a> {
103 let mut atom = self.into();
104 atom.max_size.y = max_height;
105 atom
106 }
107}