button_icon.rs

 1use crate::{prelude::*, Icon, IconName, 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: IconName,
10    size: IconSize,
11    color: Color,
12    disabled: bool,
13    selected: bool,
14    selected_icon: Option<IconName>,
15    selected_style: Option<ButtonStyle>,
16}
17
18impl ButtonIcon {
19    pub fn new(icon: IconName) -> Self {
20        Self {
21            icon,
22            size: IconSize::default(),
23            color: Color::default(),
24            disabled: false,
25            selected: false,
26            selected_icon: None,
27            selected_style: None,
28        }
29    }
30
31    pub fn size(mut self, size: impl Into<Option<IconSize>>) -> Self {
32        if let Some(size) = size.into() {
33            self.size = size;
34        }
35
36        self
37    }
38
39    pub fn color(mut self, color: impl Into<Option<Color>>) -> Self {
40        if let Some(color) = color.into() {
41            self.color = color;
42        }
43
44        self
45    }
46
47    pub fn selected_icon(mut self, icon: impl Into<Option<IconName>>) -> Self {
48        self.selected_icon = icon.into();
49        self
50    }
51}
52
53impl Disableable for ButtonIcon {
54    fn disabled(mut self, disabled: bool) -> Self {
55        self.disabled = disabled;
56        self
57    }
58}
59
60impl Selectable for ButtonIcon {
61    fn selected(mut self, selected: bool) -> Self {
62        self.selected = selected;
63        self
64    }
65}
66
67impl SelectableButton for ButtonIcon {
68    fn selected_style(mut self, style: ButtonStyle) -> Self {
69        self.selected_style = Some(style);
70        self
71    }
72}
73
74impl RenderOnce for ButtonIcon {
75    fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
76        let icon = self
77            .selected_icon
78            .filter(|_| self.selected)
79            .unwrap_or(self.icon);
80
81        let icon_color = if self.disabled {
82            Color::Disabled
83        } else if self.selected_style.is_some() && self.selected {
84            self.selected_style.unwrap().into()
85        } else if self.selected {
86            Color::Selected
87        } else {
88            self.color
89        };
90
91        Icon::new(icon).size(self.size).color(icon_color)
92    }
93}