1use gpui::{Action, AnyView};
2
3use crate::prelude::*;
4use crate::{ButtonCommon, ButtonLike, ButtonSize2, ButtonStyle2, Icon, IconElement, IconSize};
5
6#[derive(IntoElement)]
7pub struct IconButton {
8 base: ButtonLike,
9 icon: Icon,
10 icon_size: IconSize,
11 icon_color: Color,
12 selected: bool,
13}
14
15impl IconButton {
16 pub fn new(id: impl Into<ElementId>, icon: Icon) -> Self {
17 Self {
18 base: ButtonLike::new(id),
19 icon,
20 icon_size: IconSize::default(),
21 icon_color: Color::Default,
22 selected: false,
23 }
24 }
25
26 pub fn selected(mut self, selected: bool) -> Self {
27 self.selected = selected;
28 self
29 }
30
31 pub fn icon_size(mut self, icon_size: IconSize) -> Self {
32 self.icon_size = icon_size;
33 self
34 }
35
36 pub fn icon_color(mut self, icon_color: Color) -> Self {
37 self.icon_color = icon_color;
38 self
39 }
40
41 pub fn action(self, action: Box<dyn Action>) -> Self {
42 self.on_click(move |_event, cx| cx.dispatch_action(action.boxed_clone()))
43 }
44}
45
46impl Clickable for IconButton {
47 fn on_click(
48 mut self,
49 handler: impl Fn(&gpui::ClickEvent, &mut WindowContext) + 'static,
50 ) -> Self {
51 self.base = self.base.on_click(handler);
52 self
53 }
54}
55
56impl Disableable for IconButton {
57 fn disabled(mut self, disabled: bool) -> Self {
58 self.base = self.base.disabled(disabled);
59 self
60 }
61}
62
63impl ButtonCommon for IconButton {
64 fn id(&self) -> &ElementId {
65 self.base.id()
66 }
67
68 fn style(mut self, style: ButtonStyle2) -> Self {
69 self.base = self.base.style(style);
70 self
71 }
72
73 fn size(mut self, size: ButtonSize2) -> Self {
74 self.base = self.base.size(size);
75 self
76 }
77
78 fn tooltip(mut self, tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self {
79 self.base = self.base.tooltip(tooltip);
80 self
81 }
82}
83
84impl RenderOnce for IconButton {
85 type Rendered = ButtonLike;
86
87 fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
88 let icon_color = if self.base.disabled {
89 Color::Disabled
90 } else if self.selected {
91 Color::Selected
92 } else {
93 self.icon_color
94 };
95
96 self.base.child(
97 IconElement::new(self.icon)
98 .size(self.icon_size)
99 .color(icon_color),
100 )
101 }
102}