1use gpui::{Action, AnyView, DefiniteLength};
2
3use crate::prelude::*;
4use crate::{ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, Icon, IconSize};
5
6use super::button_icon::ButtonIcon;
7
8#[derive(IntoElement)]
9pub struct IconButton {
10 base: ButtonLike,
11 icon: Icon,
12 icon_size: IconSize,
13 icon_color: Color,
14 selected_icon: Option<Icon>,
15}
16
17impl IconButton {
18 pub fn new(id: impl Into<ElementId>, icon: Icon) -> 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<Icon>>) -> Self {
39 self.selected_icon = icon.into();
40 self
41 }
42
43 pub fn action(self, action: Box<dyn Action>) -> Self {
44 self.on_click(move |_event, cx| cx.dispatch_action(action.boxed_clone()))
45 }
46}
47
48impl Disableable for IconButton {
49 fn disabled(mut self, disabled: bool) -> Self {
50 self.base = self.base.disabled(disabled);
51 self
52 }
53}
54
55impl Selectable for IconButton {
56 fn selected(mut self, selected: bool) -> Self {
57 self.base = self.base.selected(selected);
58 self
59 }
60}
61
62impl Clickable for IconButton {
63 fn on_click(
64 mut self,
65 handler: impl Fn(&gpui::ClickEvent, &mut WindowContext) + 'static,
66 ) -> Self {
67 self.base = self.base.on_click(handler);
68 self
69 }
70}
71
72impl FixedWidth for IconButton {
73 fn width(mut self, width: DefiniteLength) -> Self {
74 self.base = self.base.width(width);
75 self
76 }
77
78 fn full_width(mut self) -> Self {
79 self.base = self.base.full_width();
80 self
81 }
82}
83
84impl ButtonCommon for IconButton {
85 fn id(&self) -> &ElementId {
86 self.base.id()
87 }
88
89 fn style(mut self, style: ButtonStyle) -> Self {
90 self.base = self.base.style(style);
91 self
92 }
93
94 fn size(mut self, size: ButtonSize) -> Self {
95 self.base = self.base.size(size);
96 self
97 }
98
99 fn tooltip(mut self, tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self {
100 self.base = self.base.tooltip(tooltip);
101 self
102 }
103}
104
105impl RenderOnce for IconButton {
106 type Rendered = ButtonLike;
107
108 fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
109 let is_disabled = self.base.disabled;
110 let is_selected = self.base.selected;
111
112 self.base.child(
113 ButtonIcon::new(self.icon)
114 .disabled(is_disabled)
115 .selected(is_selected)
116 .selected_icon(self.selected_icon)
117 .size(self.icon_size)
118 .color(self.icon_color),
119 )
120 }
121}