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}