diff options
author | 2022-05-31 05:13:57 +0200 | |
---|---|---|
committer | 2022-06-01 01:46:04 +0200 | |
commit | 3e2b6247f72815b6e928237f242c2d66478cf15d (patch) | |
tree | 694eba8c2bbf28565d598e02627b0b8e026e1e78 | |
parent | 28d09bfff1dde55190986bab10d7aaeb0ceb49de (diff) | |
download | iced-3e2b6247f72815b6e928237f242c2d66478cf15d.tar.gz iced-3e2b6247f72815b6e928237f242c2d66478cf15d.tar.bz2 iced-3e2b6247f72815b6e928237f242c2d66478cf15d.zip |
Implement theme styling for `Toggler`
... and wire up theming to the `styling` example.
-rw-r--r-- | examples/styling/src/main.rs | 53 | ||||
-rw-r--r-- | native/src/widget/toggler.rs | 32 | ||||
-rw-r--r-- | pure/src/helpers.rs | 1 | ||||
-rw-r--r-- | pure/src/widget/toggler.rs | 4 | ||||
-rw-r--r-- | src/pure/widget.rs | 2 | ||||
-rw-r--r-- | src/widget.rs | 2 | ||||
-rw-r--r-- | style/src/theme.rs | 60 | ||||
-rw-r--r-- | style/src/toggler.rs | 45 |
8 files changed, 101 insertions, 98 deletions
diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index 27b3ead4..044f75a9 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -5,7 +5,7 @@ use iced::text_input; use iced::{ Alignment, Button, Checkbox, Column, Container, Element, Length, ProgressBar, Radio, Row, Rule, Sandbox, Scrollable, Settings, Slider, - Space, Text, TextInput, Toggler, + Space, Text, TextInput, Theme, Toggler, }; pub fn main() -> iced::Result { @@ -115,8 +115,7 @@ impl Sandbox for Styling { Message::TogglerToggled, ) .width(Length::Shrink) - .spacing(10) - .style(self.theme); + .spacing(10); let content = Column::new() .spacing(20) @@ -151,12 +150,18 @@ impl Sandbox for Styling { .style(self.theme) .into() } + + fn theme(&self) -> Theme { + match self.theme { + style::Theme::Light => Theme::Light, + style::Theme::Dark => Theme::Dark, + } + } } mod style { use iced::{ checkbox, container, progress_bar, rule, scrollable, text_input, - toggler, }; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -220,15 +225,6 @@ mod style { } } - impl From<Theme> for Box<dyn toggler::StyleSheet> { - fn from(theme: Theme) -> Self { - match theme { - Theme::Light => Default::default(), - Theme::Dark => dark::Toggler.into(), - } - } - } - impl From<Theme> for Box<dyn rule::StyleSheet> { fn from(theme: Theme) -> Self { match theme { @@ -241,7 +237,7 @@ mod style { mod dark { use iced::{ checkbox, container, progress_bar, rule, scrollable, text_input, - toggler, Color, + Color, }; const SURFACE: Color = Color::from_rgb( @@ -404,35 +400,6 @@ mod style { } } - pub struct Toggler; - - impl toggler::StyleSheet for Toggler { - fn active(&self, is_active: bool) -> toggler::Style { - toggler::Style { - background: if is_active { ACTIVE } else { SURFACE }, - background_border: None, - foreground: if is_active { Color::WHITE } else { ACTIVE }, - foreground_border: None, - } - } - - fn hovered(&self, is_active: bool) -> toggler::Style { - toggler::Style { - background: if is_active { ACTIVE } else { SURFACE }, - background_border: None, - foreground: if is_active { - Color { - a: 0.5, - ..Color::WHITE - } - } else { - Color { a: 0.5, ..ACTIVE } - }, - foreground_border: None, - } - } - } - pub struct Rule; impl rule::StyleSheet for Rule { diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index c19b9a32..25391404 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -11,7 +11,7 @@ use crate::{ Shell, Widget, }; -pub use iced_style::toggler::{Style, StyleSheet}; +pub use iced_style::toggler::{Appearance, StyleSheet}; /// A toggler widget. /// @@ -29,7 +29,11 @@ pub use iced_style::toggler::{Style, StyleSheet}; /// Toggler::new(is_active, String::from("Toggle me!"), |b| Message::TogglerToggled(b)); /// ``` #[allow(missing_debug_implementations)] -pub struct Toggler<'a, Message, Renderer: text::Renderer> { +pub struct Toggler<'a, Message, Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ is_active: bool, on_toggle: Box<dyn Fn(bool) -> Message + 'a>, label: Option<String>, @@ -39,10 +43,14 @@ pub struct Toggler<'a, Message, Renderer: text::Renderer> { text_alignment: alignment::Horizontal, spacing: u16, font: Renderer::Font, - style_sheet: Box<dyn StyleSheet + 'a>, + style: <Renderer::Theme as StyleSheet>::Style, } -impl<'a, Message, Renderer: text::Renderer> Toggler<'a, Message, Renderer> { +impl<'a, Message, Renderer> Toggler<'a, Message, Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ /// The default size of a [`Toggler`]. pub const DEFAULT_SIZE: u16 = 20; @@ -72,7 +80,7 @@ impl<'a, Message, Renderer: text::Renderer> Toggler<'a, Message, Renderer> { text_alignment: alignment::Horizontal::Left, spacing: 0, font: Renderer::Font::default(), - style_sheet: Default::default(), + style: Default::default(), } } @@ -117,9 +125,9 @@ impl<'a, Message, Renderer: text::Renderer> Toggler<'a, Message, Renderer> { /// Sets the style of the [`Toggler`]. 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 } } @@ -128,6 +136,7 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> for Toggler<'a, Message, Renderer> where Renderer: text::Renderer, + Renderer::Theme: StyleSheet, { fn width(&self) -> Length { self.width @@ -208,7 +217,7 @@ where fn draw( &self, renderer: &mut Renderer, - _theme: &Renderer::Theme, + theme: &Renderer::Theme, style: &renderer::Style, layout: Layout<'_>, cursor_position: Point, @@ -245,9 +254,9 @@ where let is_mouse_over = bounds.contains(cursor_position); let style = if is_mouse_over { - self.style_sheet.hovered(self.is_active) + theme.hovered(self.style, self.is_active) } else { - self.style_sheet.active(self.is_active) + theme.active(self.style, self.is_active) }; let border_radius = bounds.height as f32 / BORDER_RADIUS_RATIO; @@ -301,8 +310,9 @@ where impl<'a, Message, Renderer> From<Toggler<'a, Message, Renderer>> for Element<'a, Message, Renderer> where - Renderer: 'a + text::Renderer, Message: 'a, + Renderer: 'a + text::Renderer, + Renderer::Theme: StyleSheet, { fn from( toggler: Toggler<'a, Message, Renderer>, diff --git a/pure/src/helpers.rs b/pure/src/helpers.rs index 159256ed..9a8a29c1 100644 --- a/pure/src/helpers.rs +++ b/pure/src/helpers.rs @@ -125,6 +125,7 @@ pub fn toggler<'a, Message, Renderer>( ) -> widget::Toggler<'a, Message, Renderer> where Renderer: iced_native::text::Renderer, + Renderer::Theme: widget::toggler::StyleSheet, { widget::Toggler::new(is_checked, label, f) } diff --git a/pure/src/widget/toggler.rs b/pure/src/widget/toggler.rs index e08b5f47..fc01a2c9 100644 --- a/pure/src/widget/toggler.rs +++ b/pure/src/widget/toggler.rs @@ -9,12 +9,13 @@ use iced_native::renderer; use iced_native::text; use iced_native::{Clipboard, Length, Point, Rectangle, Shell}; -pub use iced_native::widget::toggler::{Style, StyleSheet, Toggler}; +pub use iced_native::widget::toggler::{Appearance, StyleSheet, Toggler}; impl<'a, Message, Renderer> Widget<Message, Renderer> for Toggler<'a, Message, Renderer> where Renderer: text::Renderer, + Renderer::Theme: StyleSheet, { fn width(&self) -> Length { <Self as iced_native::Widget<Message, Renderer>>::width(self) @@ -99,6 +100,7 @@ impl<'a, Message, Renderer> Into<Element<'a, Message, Renderer>> where Message: 'a, 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 04975c0d..36226109 100644 --- a/src/pure/widget.rs +++ b/src/pure/widget.rs @@ -109,7 +109,7 @@ pub mod scrollable { pub mod toggler { //! Show toggle controls using togglers. - pub use iced_pure::widget::toggler::{Style, StyleSheet}; + pub use iced_pure::widget::toggler::{Appearance, StyleSheet}; /// A toggler widget. pub type Toggler<'a, Message, Theme> = diff --git a/src/widget.rs b/src/widget.rs index 2f3600b6..1634a1f2 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -127,7 +127,7 @@ pub mod scrollable { pub mod toggler { //! Show toggle controls using togglers. - pub use iced_native::widget::toggler::{Style, StyleSheet}; + pub use iced_native::widget::toggler::{Appearance, StyleSheet}; /// A toggler widget. pub type Toggler<'a, Message, Theme> = diff --git a/style/src/theme.rs b/style/src/theme.rs index e3b151aa..2f9fd4fa 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -6,6 +6,7 @@ use crate::application; use crate::button; use crate::radio; use crate::slider; +use crate::toggler; use iced_core::{Background, Color}; @@ -51,6 +52,9 @@ impl application::StyleSheet for Theme { } } +/* + * Button + */ #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Button { Primary, @@ -114,6 +118,9 @@ impl button::StyleSheet for Theme { } } +/* + * Slider + */ impl slider::StyleSheet for Theme { type Style = (); @@ -167,6 +174,9 @@ impl slider::StyleSheet for Theme { } } +/* + * Radio + */ impl radio::StyleSheet for Theme { type Style = (); @@ -193,3 +203,53 @@ impl radio::StyleSheet for Theme { } } } + +/* + * Toggler + */ +impl toggler::StyleSheet for Theme { + type Style = (); + + fn active( + &self, + _style: Self::Style, + is_active: bool, + ) -> toggler::Appearance { + let palette = self.extended_palette(); + + toggler::Appearance { + background: if is_active { + palette.primary.strong.color + } else { + palette.background.strong.color + }, + background_border: None, + foreground: if is_active { + palette.primary.strong.text + } else { + palette.background.base.color + }, + foreground_border: None, + } + } + + fn hovered( + &self, + style: Self::Style, + is_active: bool, + ) -> toggler::Appearance { + let palette = self.extended_palette(); + + toggler::Appearance { + foreground: if is_active { + Color { + a: 0.5, + ..palette.primary.strong.text + } + } else { + palette.background.weak.color + }, + ..self.active(style, is_active) + } + } +} diff --git a/style/src/toggler.rs b/style/src/toggler.rs index c06a8cd1..4ee7db46 100644 --- a/style/src/toggler.rs +++ b/style/src/toggler.rs @@ -3,7 +3,7 @@ use iced_core::Color; /// The appearance of a toggler. #[derive(Debug)] -pub struct Style { +pub struct Appearance { pub background: Color, pub background_border: Option<Color>, pub foreground: Color, @@ -12,46 +12,9 @@ pub struct Style { /// A set of rules that dictate the style of a toggler. pub trait StyleSheet { - fn active(&self, is_active: bool) -> Style; + type Style: Default + Copy; - fn hovered(&self, is_active: bool) -> Style; -} - -struct Default; - -impl StyleSheet for Default { - fn active(&self, is_active: bool) -> Style { - Style { - background: if is_active { - Color::from_rgb(0.0, 1.0, 0.0) - } else { - Color::from_rgb(0.7, 0.7, 0.7) - }, - background_border: None, - foreground: Color::WHITE, - foreground_border: None, - } - } - - fn hovered(&self, is_active: bool) -> Style { - Style { - foreground: Color::from_rgb(0.95, 0.95, 0.95), - ..self.active(is_active) - } - } -} - -impl<'a> std::default::Default for Box<dyn StyleSheet + 'a> { - fn default() -> Self { - Box::new(Default) - } -} + fn active(&self, style: Self::Style, is_active: bool) -> Appearance; -impl<'a, T> From<T> for Box<dyn StyleSheet + 'a> -where - T: 'a + StyleSheet, -{ - fn from(style: T) -> Self { - Box::new(style) - } + fn hovered(&self, style: Self::Style, is_active: bool) -> Appearance; } |