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