1use gpui::{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
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 Clickable for IconButton {
59 fn on_click(
60 mut self,
61 handler: impl Fn(&gpui::ClickEvent, &mut WindowContext) + 'static,
62 ) -> Self {
63 self.base = self.base.on_click(handler);
64 self
65 }
66}
67
68impl FixedWidth for IconButton {
69 fn width(mut self, width: DefiniteLength) -> Self {
70 self.base = self.base.width(width);
71 self
72 }
73
74 fn full_width(mut self) -> Self {
75 self.base = self.base.full_width();
76 self
77 }
78}
79
80impl ButtonCommon for IconButton {
81 fn id(&self) -> &ElementId {
82 self.base.id()
83 }
84
85 fn style(mut self, style: ButtonStyle) -> Self {
86 self.base = self.base.style(style);
87 self
88 }
89
90 fn size(mut self, size: ButtonSize) -> Self {
91 self.base = self.base.size(size);
92 self
93 }
94
95 fn tooltip(mut self, tooltip: impl Fn(&mut WindowContext) -> AnyView + 'static) -> Self {
96 self.base = self.base.tooltip(tooltip);
97 self
98 }
99}
100
101impl VisibleOnHover for IconButton {
102 fn visible_on_hover(mut self, group_name: impl Into<SharedString>) -> Self {
103 self.base = self.base.visible_on_hover(group_name);
104 self
105 }
106}
107
108impl RenderOnce for IconButton {
109 type Rendered = ButtonLike;
110
111 fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
112 let is_disabled = self.base.disabled;
113 let is_selected = self.base.selected;
114
115 self.base.child(
116 ButtonIcon::new(self.icon)
117 .disabled(is_disabled)
118 .selected(is_selected)
119 .selected_icon(self.selected_icon)
120 .size(self.icon_size)
121 .color(self.icon_color),
122 )
123 }
124}