1use gpui::{AnyView, DefiniteLength};
2
3use crate::{prelude::*, SelectableButton};
4use crate::{ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, IconName, IconSize};
5
6use super::button_icon::ButtonIcon;
7
8#[derive(IntoElement)]
9pub struct IconButton {
10 base: ButtonLike,
11 icon: IconName,
12 icon_size: IconSize,
13 icon_color: Color,
14 selected_icon: Option<IconName>,
15}
16
17impl IconButton {
18 pub fn new(id: impl Into<ElementId>, icon: IconName) -> Self {
19 Self {
20 base: ButtonLike::new(id),
21 icon,
22 icon_size: IconSize::default(),
23 icon_color: Color::Default,
24 selected_icon: None,
25 }
26 }
27
28 pub fn icon_size(mut self, icon_size: IconSize) -> Self {
29 self.icon_size = icon_size;
30 self
31 }
32
33 pub fn icon_color(mut self, icon_color: Color) -> Self {
34 self.icon_color = icon_color;
35 self
36 }
37
38 pub fn selected_icon(mut self, icon: impl Into<Option<IconName>>) -> Self {
39 self.selected_icon = icon.into();
40 self
41 }
42}
43
44impl Disableable for IconButton {
45 fn disabled(mut self, disabled: bool) -> Self {
46 self.base = self.base.disabled(disabled);
47 self
48 }
49}
50
51impl Selectable for IconButton {
52 fn selected(mut self, selected: bool) -> Self {
53 self.base = self.base.selected(selected);
54 self
55 }
56}
57
58impl SelectableButton for IconButton {
59 fn selected_style(mut self, style: ButtonStyle) -> Self {
60 self.base = self.base.selected_style(style);
61 self
62 }
63}
64
65impl Clickable for IconButton {
66 fn on_click(
67 mut self,
68 handler: impl Fn(&gpui::ClickEvent, &mut WindowContext) + 'static,
69 ) -> Self {
70 self.base = self.base.on_click(handler);
71 self
72 }
73}
74
75impl FixedWidth for IconButton {
76 fn width(mut self, width: DefiniteLength) -> Self {
77 self.base = self.base.width(width);
78 self
79 }
80
81 fn full_width(mut self) -> Self {
82 self.base = self.base.full_width();
83 self
84 }
85}
86
87impl ButtonCommon for IconButton {
88 fn id(&self) -> &ElementId {
89 self.base.id()
90 }
91
92 fn style(mut self, style: ButtonStyle) -> Self {
93 self.base = self.base.style(style);
94 self
95 }
96
97 fn size(mut self, size: ButtonSize) -> Self {
98 self.base = self.base.size(size);
99 self
100 }
101
102 fn tooltip(mut self, tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self {
103 self.base = self.base.tooltip(tooltip);
104 self
105 }
106}
107
108impl VisibleOnHover for IconButton {
109 fn visible_on_hover(mut self, group_name: impl Into<SharedString>) -> Self {
110 self.base = self.base.visible_on_hover(group_name);
111 self
112 }
113}
114
115impl RenderOnce for IconButton {
116 fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
117 let is_disabled = self.base.disabled;
118 let is_selected = self.base.selected;
119 let selected_style = self.base.selected_style;
120
121 self.base.child(
122 ButtonIcon::new(self.icon)
123 .disabled(is_disabled)
124 .selected(is_selected)
125 .selected_icon(self.selected_icon)
126 .when_some(selected_style, |this, style| this.selected_style(style))
127 .size(self.icon_size)
128 .color(self.icon_color),
129 )
130 }
131}