diff options
author | 2024-03-05 21:55:24 +0100 | |
---|---|---|
committer | 2024-03-05 21:55:24 +0100 | |
commit | 7d84c9c9c3619513519ac1ef7ea1c5f6e4e2cf5d (patch) | |
tree | 84247474621cb2d1615322e29eb9249752c780cd | |
parent | d735209fc32238185ea0f27f1f4d1d0044b90e06 (diff) | |
download | iced-7d84c9c9c3619513519ac1ef7ea1c5f6e4e2cf5d.tar.gz iced-7d84c9c9c3619513519ac1ef7ea1c5f6e4e2cf5d.tar.bz2 iced-7d84c9c9c3619513519ac1ef7ea1c5f6e4e2cf5d.zip |
Simplify theming for `Radio` widget
-rw-r--r-- | style/src/lib.rs | 1 | ||||
-rw-r--r-- | style/src/radio.rs | 29 | ||||
-rw-r--r-- | style/src/theme.rs | 56 | ||||
-rw-r--r-- | widget/src/helpers.rs | 2 | ||||
-rw-r--r-- | widget/src/radio.rs | 106 |
5 files changed, 86 insertions, 108 deletions
diff --git a/style/src/lib.rs b/style/src/lib.rs index 6da84b4d..45717d46 100644 --- a/style/src/lib.rs +++ b/style/src/lib.rs @@ -21,7 +21,6 @@ pub mod menu; pub mod pane_grid; pub mod pick_list; pub mod progress_bar; -pub mod radio; pub mod rule; pub mod svg; pub mod text_editor; diff --git a/style/src/radio.rs b/style/src/radio.rs deleted file mode 100644 index 06c49029..00000000 --- a/style/src/radio.rs +++ /dev/null @@ -1,29 +0,0 @@ -//! Change the appearance of radio buttons. -use iced_core::{Background, Color}; - -/// 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>, -} - -/// A set of rules that dictate the style of a radio button. -pub trait StyleSheet { - /// The supported style of the [`StyleSheet`]. - type Style: Default; - - /// Produces the active [`Appearance`] of a radio button. - fn active(&self, style: &Self::Style, is_selected: bool) -> Appearance; - - /// Produces the hovered [`Appearance`] of a radio button. - fn hovered(&self, style: &Self::Style, is_selected: bool) -> Appearance; -} diff --git a/style/src/theme.rs b/style/src/theme.rs index 2f8488c7..b188e561 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -9,7 +9,6 @@ use crate::menu; use crate::pane_grid; use crate::pick_list; use crate::progress_bar; -use crate::radio; use crate::rule; use crate::svg; use crate::text_editor; @@ -381,61 +380,6 @@ impl pick_list::StyleSheet for Theme { } } -/// The style of a radio button. -#[derive(Default)] -pub enum Radio { - /// The default style. - #[default] - Default, - /// A custom style. - Custom(Box<dyn radio::StyleSheet<Style = Theme>>), -} - -impl radio::StyleSheet for Theme { - type Style = Radio; - - fn active( - &self, - style: &Self::Style, - is_selected: bool, - ) -> radio::Appearance { - match style { - Radio::Default => { - let palette = self.extended_palette(); - - radio::Appearance { - background: Color::TRANSPARENT.into(), - dot_color: palette.primary.strong.color, - border_width: 1.0, - border_color: palette.primary.strong.color, - text_color: None, - } - } - Radio::Custom(custom) => custom.active(self, is_selected), - } - } - - fn hovered( - &self, - style: &Self::Style, - is_selected: bool, - ) -> radio::Appearance { - match style { - Radio::Default => { - let active = self.active(style, is_selected); - let palette = self.extended_palette(); - - radio::Appearance { - dot_color: palette.primary.strong.color, - background: palette.primary.weak.color.into(), - ..active - } - } - Radio::Custom(custom) => custom.hovered(self, is_selected), - } - } -} - /// The style of a toggler. #[derive(Default)] pub enum Toggler { 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 + }, + } +} |