button_icon.rs

 1use crate::{prelude::*, Icon, IconElement, IconSize};
 2
 3/// An icon that appears within a button.
 4///
 5/// Can be used as either an icon alongside a label, like in [`Button`](crate::Button),
 6/// or as a standalone icon, like in [`IconButton`](crate::IconButton).
 7#[derive(IntoElement)]
 8pub(super) struct ButtonIcon {
 9    icon: Icon,
10    size: IconSize,
11    color: Color,
12    disabled: bool,
13    selected: bool,
14    selected_icon: Option<Icon>,
15}
16
17impl ButtonIcon {
18    pub fn new(icon: Icon) -> Self {
19        Self {
20            icon,
21            size: IconSize::default(),
22            color: Color::default(),
23            disabled: false,
24            selected: false,
25            selected_icon: None,
26        }
27    }
28
29    pub fn size(mut self, size: impl Into<Option<IconSize>>) -> Self {
30        if let Some(size) = size.into() {
31            self.size = size;
32        }
33
34        self
35    }
36
37    pub fn color(mut self, color: impl Into<Option<Color>>) -> Self {
38        if let Some(color) = color.into() {
39            self.color = color;
40        }
41
42        self
43    }
44
45    pub fn selected_icon(mut self, icon: impl Into<Option<Icon>>) -> Self {
46        self.selected_icon = icon.into();
47        self
48    }
49}
50
51impl Disableable for ButtonIcon {
52    fn disabled(mut self, disabled: bool) -> Self {
53        self.disabled = disabled;
54        self
55    }
56}
57
58impl Selectable for ButtonIcon {
59    fn selected(mut self, selected: bool) -> Self {
60        self.selected = selected;
61        self
62    }
63}
64
65impl RenderOnce for ButtonIcon {
66    type Rendered = IconElement;
67
68    fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
69        let icon = self
70            .selected_icon
71            .filter(|_| self.selected)
72            .unwrap_or(self.icon);
73
74        let icon_color = if self.disabled {
75            Color::Disabled
76        } else if self.selected {
77            Color::Selected
78        } else {
79            self.color
80        };
81
82        IconElement::new(icon).size(self.size).color(icon_color)
83    }
84}