button_icon.rs

  1#![allow(missing_docs)]
  2use crate::{prelude::*, Icon, IconName, IconSize};
  3
  4/// An icon that appears within a button.
  5///
  6/// Can be used as either an icon alongside a label, like in [`Button`](crate::Button),
  7/// or as a standalone icon, like in [`IconButton`](crate::IconButton).
  8#[derive(IntoElement)]
  9pub(super) struct ButtonIcon {
 10    icon: IconName,
 11    size: IconSize,
 12    color: Color,
 13    disabled: bool,
 14    selected: bool,
 15    selected_icon: Option<IconName>,
 16    selected_icon_color: Option<Color>,
 17    selected_style: Option<ButtonStyle>,
 18}
 19
 20impl ButtonIcon {
 21    pub fn new(icon: IconName) -> Self {
 22        Self {
 23            icon,
 24            size: IconSize::default(),
 25            color: Color::default(),
 26            disabled: false,
 27            selected: false,
 28            selected_icon: None,
 29            selected_icon_color: None,
 30            selected_style: None,
 31        }
 32    }
 33
 34    pub fn size(mut self, size: impl Into<Option<IconSize>>) -> Self {
 35        if let Some(size) = size.into() {
 36            self.size = size;
 37        }
 38
 39        self
 40    }
 41
 42    pub fn color(mut self, color: impl Into<Option<Color>>) -> Self {
 43        if let Some(color) = color.into() {
 44            self.color = color;
 45        }
 46
 47        self
 48    }
 49
 50    pub fn selected_icon(mut self, icon: impl Into<Option<IconName>>) -> Self {
 51        self.selected_icon = icon.into();
 52        self
 53    }
 54
 55    pub fn selected_icon_color(mut self, color: impl Into<Option<Color>>) -> Self {
 56        self.selected_icon_color = color.into();
 57        self
 58    }
 59}
 60
 61impl Disableable for ButtonIcon {
 62    fn disabled(mut self, disabled: bool) -> Self {
 63        self.disabled = disabled;
 64        self
 65    }
 66}
 67
 68impl Toggleable for ButtonIcon {
 69    fn toggle_state(mut self, selected: bool) -> Self {
 70        self.selected = selected;
 71        self
 72    }
 73}
 74
 75impl SelectableButton for ButtonIcon {
 76    fn selected_style(mut self, style: ButtonStyle) -> Self {
 77        self.selected_style = Some(style);
 78        self
 79    }
 80}
 81
 82impl RenderOnce for ButtonIcon {
 83    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
 84        let icon = self
 85            .selected_icon
 86            .filter(|_| self.selected)
 87            .unwrap_or(self.icon);
 88
 89        let icon_color = if self.disabled {
 90            Color::Disabled
 91        } else if self.selected_style.is_some() && self.selected {
 92            self.selected_style.unwrap().into()
 93        } else if self.selected {
 94            self.selected_icon_color.unwrap_or(Color::Selected)
 95        } else {
 96            self.color
 97        };
 98
 99        Icon::new(icon).size(self.size).color(icon_color)
100    }
101}