diff options
| author | 2024-03-05 21:55:24 +0100 | |
|---|---|---|
| committer | 2024-03-05 21:55:24 +0100 | |
| commit | 7d84c9c9c3619513519ac1ef7ea1c5f6e4e2cf5d (patch) | |
| tree | 84247474621cb2d1615322e29eb9249752c780cd /widget/src | |
| parent | d735209fc32238185ea0f27f1f4d1d0044b90e06 (diff) | |
| download | iced-7d84c9c9c3619513519ac1ef7ea1c5f6e4e2cf5d.tar.gz iced-7d84c9c9c3619513519ac1ef7ea1c5f6e4e2cf5d.tar.bz2 iced-7d84c9c9c3619513519ac1ef7ea1c5f6e4e2cf5d.zip | |
Simplify theming for `Radio` widget
Diffstat (limited to '')
| -rw-r--r-- | widget/src/helpers.rs | 2 | ||||
| -rw-r--r-- | widget/src/radio.rs | 106 | 
2 files changed, 86 insertions, 22 deletions
| diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index c63a9706..355f7814 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -179,7 +179,7 @@ pub fn radio<Message, Theme, Renderer, V>(  ) -> Radio<Message, Theme, Renderer>  where      Message: Clone, -    Theme: radio::StyleSheet, +    Theme: radio::Style,      Renderer: core::text::Renderer,      V: Copy + Eq,  { diff --git a/widget/src/radio.rs b/widget/src/radio.rs index 68e9bc7e..c4283af8 100644 --- a/widget/src/radio.rs +++ b/widget/src/radio.rs @@ -9,11 +9,10 @@ use crate::core::touch;  use crate::core::widget;  use crate::core::widget::tree::{self, Tree};  use crate::core::{ -    Border, Clipboard, Element, Layout, Length, Pixels, Rectangle, Shell, Size, -    Widget, +    Background, Border, Clipboard, Color, Element, Layout, Length, Pixels, +    Rectangle, Shell, Size, Widget,  }; - -pub use iced_style::radio::{Appearance, StyleSheet}; +use crate::style::Theme;  /// A circular button representing a choice.  /// @@ -71,7 +70,6 @@ pub use iced_style::radio::{Appearance, StyleSheet};  #[allow(missing_debug_implementations)]  pub struct Radio<Message, Theme = crate::Theme, Renderer = crate::Renderer>  where -    Theme: StyleSheet,      Renderer: text::Renderer,  {      is_selected: bool, @@ -84,20 +82,19 @@ where      text_line_height: text::LineHeight,      text_shaping: text::Shaping,      font: Option<Renderer::Font>, -    style: Theme::Style, +    style: fn(&Theme, Status) -> Appearance,  }  impl<Message, Theme, Renderer> Radio<Message, Theme, Renderer>  where      Message: Clone, -    Theme: StyleSheet,      Renderer: text::Renderer,  {      /// The default size of a [`Radio`] button. -    pub const DEFAULT_SIZE: f32 = 28.0; +    pub const DEFAULT_SIZE: f32 = 14.0;      /// The default spacing of a [`Radio`] button. -    pub const DEFAULT_SPACING: f32 = 15.0; +    pub const DEFAULT_SPACING: f32 = 10.0;      /// Creates a new [`Radio`] button.      /// @@ -114,6 +111,7 @@ where          f: F,      ) -> Self      where +        Theme: Style,          V: Eq + Copy,          F: FnOnce(V) -> Message,      { @@ -128,7 +126,7 @@ where              text_line_height: text::LineHeight::default(),              text_shaping: text::Shaping::Basic,              font: None, -            style: Default::default(), +            style: Theme::style(),          }      } @@ -178,7 +176,7 @@ where      }      /// Sets the style of the [`Radio`] button. -    pub fn style(mut self, style: impl Into<Theme::Style>) -> Self { +    pub fn style(mut self, style: fn(&Theme, Status) -> Appearance) -> Self {          self.style = style.into();          self      } @@ -188,7 +186,6 @@ impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer>      for Radio<Message, Theme, Renderer>  where      Message: Clone, -    Theme: StyleSheet + crate::text::StyleSheet,      Renderer: text::Renderer,  {      fn tag(&self) -> tree::Tag { @@ -291,15 +288,18 @@ where          viewport: &Rectangle,      ) {          let is_mouse_over = cursor.is_over(layout.bounds()); +        let is_selected = self.is_selected;          let mut children = layout.children(); -        let custom_style = if is_mouse_over { -            theme.hovered(&self.style, self.is_selected) +        let status = if is_mouse_over { +            Status::Hovered { is_selected }          } else { -            theme.active(&self.style, self.is_selected) +            Status::Active { is_selected }          }; +        let appearance = (self.style)(theme, status); +          {              let layout = children.next().unwrap();              let bounds = layout.bounds(); @@ -312,12 +312,12 @@ where                      bounds,                      border: Border {                          radius: (size / 2.0).into(), -                        width: custom_style.border_width, -                        color: custom_style.border_color, +                        width: appearance.border_width, +                        color: appearance.border_color,                      },                      ..renderer::Quad::default()                  }, -                custom_style.background, +                appearance.background,              );              if self.is_selected { @@ -332,7 +332,7 @@ where                          border: Border::with_radius(dot_size / 2.0),                          ..renderer::Quad::default()                      }, -                    custom_style.dot_color, +                    appearance.dot_color,                  );              }          } @@ -346,7 +346,7 @@ where                  label_layout,                  tree.state.downcast_ref(),                  crate::text::Appearance { -                    color: custom_style.text_color, +                    color: appearance.text_color,                  },                  viewport,              ); @@ -358,7 +358,7 @@ impl<'a, Message, Theme, Renderer> From<Radio<Message, Theme, Renderer>>      for Element<'a, Message, Theme, Renderer>  where      Message: 'a + Clone, -    Theme: StyleSheet + crate::text::StyleSheet + 'a, +    Theme: 'a,      Renderer: 'a + text::Renderer,  {      fn from( @@ -367,3 +367,67 @@ where          Element::new(radio)      }  } + +/// The possible status of a [`TextInput`]. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Status { +    /// The [`Radio`] button can be interacted with. +    Active { +        /// Indicates whether the [`Radio`] button is currently selected. +        is_selected: bool, +    }, +    /// The [`Radio`] button is being hovered. +    Hovered { +        /// Indicates whether the [`Radio`] button is currently selected. +        is_selected: bool, +    }, +} + +/// The appearance of a radio button. +#[derive(Debug, Clone, Copy)] +pub struct Appearance { +    /// The [`Background`] of the radio button. +    pub background: Background, +    /// The [`Color`] of the dot of the radio button. +    pub dot_color: Color, +    /// The border width of the radio button. +    pub border_width: f32, +    /// The border [`Color`] of the radio button. +    pub border_color: Color, +    /// The text [`Color`] of the radio button. +    pub text_color: Option<Color>, +} + +/// The definiton of the default style of a [`Radio`] button. +pub trait Style { +    /// Returns the default style of a [`Radio`] button. +    fn style() -> fn(&Self, Status) -> Appearance; +} + +impl Style for Theme { +    fn style() -> fn(&Self, Status) -> Appearance { +        default +    } +} + +/// The default style of a [`Radio`] button. +pub fn default(theme: &Theme, status: Status) -> Appearance { +    let palette = theme.extended_palette(); + +    let active = Appearance { +        background: Color::TRANSPARENT.into(), +        dot_color: palette.primary.strong.color, +        border_width: 1.0, +        border_color: palette.primary.strong.color, +        text_color: None, +    }; + +    match status { +        Status::Active { .. } => active, +        Status::Hovered { .. } => Appearance { +            dot_color: palette.primary.strong.color, +            background: palette.primary.weak.color.into(), +            ..active +        }, +    } +} | 
