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}