icon_button.rs

  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}