diff options
author | 2022-05-27 01:26:57 +0200 | |
---|---|---|
committer | 2022-05-27 01:29:36 +0200 | |
commit | 28d09bfff1dde55190986bab10d7aaeb0ceb49de (patch) | |
tree | df38cec7242de571d94378cd736a05bc82a622c2 | |
parent | d988d813d77bc23147a179586206048e6cc42157 (diff) | |
download | iced-28d09bfff1dde55190986bab10d7aaeb0ceb49de.tar.gz iced-28d09bfff1dde55190986bab10d7aaeb0ceb49de.tar.bz2 iced-28d09bfff1dde55190986bab10d7aaeb0ceb49de.zip |
Implement theme styling for `Radio`
-rw-r--r-- | examples/scrollable/src/main.rs | 15 | ||||
-rw-r--r-- | examples/scrollable/src/style.rs | 40 | ||||
-rw-r--r-- | examples/styling/src/main.rs | 51 | ||||
-rw-r--r-- | native/src/widget/radio.rs | 39 | ||||
-rw-r--r-- | pure/src/helpers.rs | 5 | ||||
-rw-r--r-- | pure/src/widget/radio.rs | 9 | ||||
-rw-r--r-- | src/pure/widget.rs | 6 | ||||
-rw-r--r-- | src/widget.rs | 6 | ||||
-rw-r--r-- | style/src/radio.rs | 42 | ||||
-rw-r--r-- | style/src/theme.rs | 28 |
10 files changed, 85 insertions, 156 deletions
diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs index 8e027504..e49aa63b 100644 --- a/examples/scrollable/src/main.rs +++ b/examples/scrollable/src/main.rs @@ -69,15 +69,12 @@ impl Sandbox for ScrollableDemo { let choose_theme = style::Theme::ALL.iter().fold( Column::new().spacing(10).push(Text::new("Choose a theme:")), |column, option| { - column.push( - Radio::new( - *option, - format!("{:?}", option), - Some(*theme), - Message::ThemeChanged, - ) - .style(*theme), - ) + column.push(Radio::new( + *option, + format!("{:?}", option), + Some(*theme), + Message::ThemeChanged, + )) }, ); diff --git a/examples/scrollable/src/style.rs b/examples/scrollable/src/style.rs index 0ed38b00..0581a8c8 100644 --- a/examples/scrollable/src/style.rs +++ b/examples/scrollable/src/style.rs @@ -1,4 +1,4 @@ -use iced::{container, radio, rule, scrollable}; +use iced::{container, rule, scrollable}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Theme { @@ -25,15 +25,6 @@ impl<'a> From<Theme> for Box<dyn container::StyleSheet + 'a> { } } -impl<'a> From<Theme> for Box<dyn radio::StyleSheet + 'a> { - fn from(theme: Theme) -> Self { - match theme { - Theme::Light => Default::default(), - Theme::Dark => dark::Radio.into(), - } - } -} - impl<'a> From<Theme> for Box<dyn scrollable::StyleSheet + 'a> { fn from(theme: Theme) -> Self { match theme { @@ -53,7 +44,7 @@ impl From<Theme> for Box<dyn rule::StyleSheet> { } mod dark { - use iced::{container, radio, rule, scrollable, Color}; + use iced::{container, rule, scrollable, Color}; const BACKGROUND: Color = Color::from_rgb( 0x36 as f32 / 255.0, @@ -73,12 +64,6 @@ mod dark { 0xE9 as f32 / 255.0, ); - const ACTIVE: Color = Color::from_rgb( - 0x72 as f32 / 255.0, - 0x89 as f32 / 255.0, - 0xDA as f32 / 255.0, - ); - const SCROLLBAR: Color = Color::from_rgb( 0x2E as f32 / 255.0, 0x33 as f32 / 255.0, @@ -107,27 +92,6 @@ mod dark { } } - pub struct Radio; - - impl radio::StyleSheet for Radio { - fn active(&self) -> radio::Style { - radio::Style { - background: SURFACE.into(), - dot_color: ACTIVE, - border_width: 1.0, - border_color: ACTIVE, - text_color: None, - } - } - - fn hovered(&self) -> radio::Style { - radio::Style { - background: Color { a: 0.5, ..SURFACE }.into(), - ..self.active() - } - } - } - pub struct Scrollable; impl scrollable::StyleSheet for Scrollable { diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index 82876cb4..27b3ead4 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -61,15 +61,12 @@ impl Sandbox for Styling { let choose_theme = style::Theme::ALL.iter().fold( Column::new().spacing(10).push(Text::new("Choose a theme:")), |column, theme| { - column.push( - Radio::new( - *theme, - format!("{:?}", theme), - Some(self.theme), - Message::ThemeChanged, - ) - .style(self.theme), - ) + column.push(Radio::new( + *theme, + format!("{:?}", theme), + Some(self.theme), + Message::ThemeChanged, + )) }, ); @@ -158,7 +155,7 @@ impl Sandbox for Styling { mod style { use iced::{ - checkbox, container, progress_bar, radio, rule, scrollable, text_input, + checkbox, container, progress_bar, rule, scrollable, text_input, toggler, }; @@ -187,15 +184,6 @@ mod style { } } - impl<'a> From<Theme> for Box<dyn radio::StyleSheet + 'a> { - fn from(theme: Theme) -> Self { - match theme { - Theme::Light => Default::default(), - Theme::Dark => dark::Radio.into(), - } - } - } - impl<'a> From<Theme> for Box<dyn text_input::StyleSheet + 'a> { fn from(theme: Theme) -> Self { match theme { @@ -252,8 +240,8 @@ mod style { mod dark { use iced::{ - checkbox, container, progress_bar, radio, rule, scrollable, - text_input, toggler, Color, + checkbox, container, progress_bar, rule, scrollable, text_input, + toggler, Color, }; const SURFACE: Color = Color::from_rgb( @@ -292,27 +280,6 @@ mod style { } } - pub struct Radio; - - impl radio::StyleSheet for Radio { - fn active(&self) -> radio::Style { - radio::Style { - background: SURFACE.into(), - dot_color: ACTIVE, - border_width: 1.0, - border_color: ACTIVE, - text_color: None, - } - } - - fn hovered(&self) -> radio::Style { - radio::Style { - background: Color { a: 0.5, ..SURFACE }.into(), - ..self.active() - } - } - } - pub struct TextInput; impl text_input::StyleSheet for TextInput { diff --git a/native/src/widget/radio.rs b/native/src/widget/radio.rs index 5d936eaf..de7e2735 100644 --- a/native/src/widget/radio.rs +++ b/native/src/widget/radio.rs @@ -12,14 +12,14 @@ use crate::{ Shell, Widget, }; -pub use iced_style::radio::{Style, StyleSheet}; +pub use iced_style::radio::{Appearance, StyleSheet}; /// A circular button representing a choice. /// /// # Example /// ``` -/// # type Radio<'a, Message> = -/// # iced_native::widget::Radio<'a, Message, iced_native::renderer::Null>; +/// # type Radio<Message> = +/// # iced_native::widget::Radio<Message, iced_native::renderer::Null>; /// # /// #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// pub enum Choice { @@ -41,7 +41,11 @@ pub use iced_style::radio::{Style, StyleSheet}; /// ///  #[allow(missing_debug_implementations)] -pub struct Radio<'a, Message, Renderer: text::Renderer> { +pub struct Radio<Message, Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ is_selected: bool, on_click: Message, label: String, @@ -50,12 +54,14 @@ pub struct Radio<'a, Message, Renderer: text::Renderer> { spacing: u16, text_size: Option<u16>, font: Renderer::Font, - style_sheet: Box<dyn StyleSheet + 'a>, + style: <Renderer::Theme as StyleSheet>::Style, } -impl<'a, Message, Renderer: text::Renderer> Radio<'a, Message, Renderer> +impl<Message, Renderer> Radio<Message, Renderer> where Message: Clone, + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, { /// The default size of a [`Radio`] button. pub const DEFAULT_SIZE: u16 = 28; @@ -90,7 +96,7 @@ where spacing: Self::DEFAULT_SPACING, //15 text_size: None, font: Default::default(), - style_sheet: Default::default(), + style: Default::default(), } } @@ -127,18 +133,18 @@ where /// Sets the style of the [`Radio`] button. pub fn style( mut self, - style_sheet: impl Into<Box<dyn StyleSheet + 'a>>, + style: impl Into<<Renderer::Theme as StyleSheet>::Style>, ) -> Self { - self.style_sheet = style_sheet.into(); + self.style = style.into(); self } } -impl<'a, Message, Renderer> Widget<Message, Renderer> - for Radio<'a, Message, Renderer> +impl<Message, Renderer> Widget<Message, Renderer> for Radio<Message, Renderer> where Message: Clone, Renderer: text::Renderer, + Renderer::Theme: StyleSheet, { fn width(&self) -> Length { self.width @@ -223,9 +229,9 @@ where let mut children = layout.children(); let custom_style = if is_mouse_over { - self.style_sheet.hovered() + theme.hovered(self.style) } else { - self.style_sheet.active() + theme.active(self.style) }; { @@ -281,15 +287,14 @@ where } } -impl<'a, Message, Renderer> From<Radio<'a, Message, Renderer>> +impl<'a, Message, Renderer> From<Radio<Message, Renderer>> for Element<'a, Message, Renderer> where Message: 'a + Clone, Renderer: 'a + text::Renderer, + Renderer::Theme: StyleSheet, { - fn from( - radio: Radio<'a, Message, Renderer>, - ) -> Element<'a, Message, Renderer> { + fn from(radio: Radio<Message, Renderer>) -> Element<'a, Message, Renderer> { Element::new(radio) } } diff --git a/pure/src/helpers.rs b/pure/src/helpers.rs index d8741b09..159256ed 100644 --- a/pure/src/helpers.rs +++ b/pure/src/helpers.rs @@ -100,15 +100,16 @@ where /// Creates a new [`Radio`]. /// /// [`Radio`]: widget::Radio -pub fn radio<'a, Message, Renderer, V>( +pub fn radio<Message, Renderer, V>( label: impl Into<String>, value: V, selected: Option<V>, on_click: impl FnOnce(V) -> Message, -) -> widget::Radio<'a, Message, Renderer> +) -> widget::Radio<Message, Renderer> where Message: Clone, Renderer: iced_native::text::Renderer, + Renderer::Theme: widget::radio::StyleSheet, V: Copy + Eq, { widget::Radio::new(value, label, selected, on_click) diff --git a/pure/src/widget/radio.rs b/pure/src/widget/radio.rs index c92c8dbc..9a8885e0 100644 --- a/pure/src/widget/radio.rs +++ b/pure/src/widget/radio.rs @@ -9,13 +9,13 @@ use iced_native::renderer; use iced_native::text; use iced_native::{Clipboard, Length, Point, Rectangle, Shell}; -pub use iced_native::widget::radio::{Radio, Style, StyleSheet}; +pub use iced_native::widget::radio::{Appearance, Radio, StyleSheet}; -impl<'a, Message, Renderer> Widget<Message, Renderer> - for Radio<'a, Message, Renderer> +impl<Message, Renderer> Widget<Message, Renderer> for Radio<Message, Renderer> where Message: Clone, Renderer: text::Renderer, + Renderer::Theme: StyleSheet, { fn width(&self) -> Length { <Self as iced_native::Widget<Message, Renderer>>::width(self) @@ -96,10 +96,11 @@ where } impl<'a, Message, Renderer> Into<Element<'a, Message, Renderer>> - for Radio<'a, Message, Renderer> + for Radio<Message, Renderer> where Message: 'a + Clone, Renderer: text::Renderer + 'a, + Renderer::Theme: StyleSheet, { fn into(self) -> Element<'a, Message, Renderer> { Element::new(self) diff --git a/src/pure/widget.rs b/src/pure/widget.rs index e91cf56a..04975c0d 100644 --- a/src/pure/widget.rs +++ b/src/pure/widget.rs @@ -90,11 +90,11 @@ pub mod pick_list { pub mod radio { //! Create choices using radio buttons. - pub use iced_pure::widget::radio::{Style, StyleSheet}; + pub use iced_pure::widget::radio::{Appearance, StyleSheet}; /// A circular button representing a choice. - pub type Radio<'a, Message, Theme> = - iced_pure::widget::Radio<'a, Message, crate::Renderer<Theme>>; + pub type Radio<Message, Theme> = + iced_pure::widget::Radio<Message, crate::Renderer<Theme>>; } pub mod scrollable { diff --git a/src/widget.rs b/src/widget.rs index 51a498b0..2f3600b6 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -106,11 +106,11 @@ pub mod pick_list { pub mod radio { //! Create choices using radio buttons. - pub use iced_native::widget::radio::{Style, StyleSheet}; + pub use iced_native::widget::radio::{Appearance, StyleSheet}; /// A circular button representing a choice. - pub type Radio<'a, Message, Theme> = - iced_native::widget::Radio<'a, Message, crate::Renderer<Theme>>; + pub type Radio<Message, Theme> = + iced_native::widget::Radio<Message, crate::Renderer<Theme>>; } pub mod scrollable { diff --git a/style/src/radio.rs b/style/src/radio.rs index dab76ad8..a4d4a83b 100644 --- a/style/src/radio.rs +++ b/style/src/radio.rs @@ -3,7 +3,7 @@ use iced_core::{Background, Color}; /// The appearance of a radio button. #[derive(Debug, Clone, Copy)] -pub struct Style { +pub struct Appearance { pub background: Background, pub dot_color: Color, pub border_width: f32, @@ -13,43 +13,9 @@ pub struct Style { /// A set of rules that dictate the style of a radio button. pub trait StyleSheet { - fn active(&self) -> Style; + type Style: Default + Copy; - fn hovered(&self) -> Style; -} - -struct Default; - -impl StyleSheet for Default { - fn active(&self) -> Style { - Style { - background: Background::Color(Color::from_rgb(0.95, 0.95, 0.95)), - dot_color: Color::from_rgb(0.3, 0.3, 0.3), - border_width: 1.0, - border_color: Color::from_rgb(0.6, 0.6, 0.6), - text_color: None, - } - } - - fn hovered(&self) -> Style { - Style { - background: Background::Color(Color::from_rgb(0.90, 0.90, 0.90)), - ..self.active() - } - } -} - -impl<'a> std::default::Default for Box<dyn StyleSheet + 'a> { - fn default() -> Self { - Box::new(Default) - } -} + fn active(&self, style: Self::Style) -> Appearance; -impl<'a, T> From<T> for Box<dyn StyleSheet + 'a> -where - T: StyleSheet + 'a, -{ - fn from(style_sheet: T) -> Self { - Box::new(style_sheet) - } + fn hovered(&self, style: Self::Style) -> Appearance; } diff --git a/style/src/theme.rs b/style/src/theme.rs index c9fae3c2..e3b151aa 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -4,6 +4,7 @@ pub use self::palette::Palette; use crate::application; use crate::button; +use crate::radio; use crate::slider; use iced_core::{Background, Color}; @@ -165,3 +166,30 @@ impl slider::StyleSheet for Theme { } } } + +impl radio::StyleSheet for Theme { + type Style = (); + + fn active(&self, _style: Self::Style) -> radio::Appearance { + let palette = self.extended_palette(); + + radio::Appearance { + background: Color::TRANSPARENT.into(), + dot_color: palette.primary.strong.color.into(), + border_width: 1.0, + border_color: palette.primary.strong.color, + text_color: None, + } + } + + fn hovered(&self, style: Self::Style) -> radio::Appearance { + let active = self.active(style); + let palette = self.extended_palette(); + + radio::Appearance { + dot_color: palette.primary.weak.text.into(), + background: palette.primary.weak.color.into(), + ..active + } + } +} |