diff options
-rw-r--r-- | examples/styling/src/main.rs | 43 | ||||
-rw-r--r-- | native/src/widget/checkbox.rs | 30 | ||||
-rw-r--r-- | pure/src/helpers.rs | 1 | ||||
-rw-r--r-- | pure/src/widget/checkbox.rs | 4 | ||||
-rw-r--r-- | src/pure/widget.rs | 2 | ||||
-rw-r--r-- | src/widget.rs | 2 | ||||
-rw-r--r-- | style/src/checkbox.rs | 43 | ||||
-rw-r--r-- | style/src/theme.rs | 104 |
8 files changed, 137 insertions, 92 deletions
diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs index e19b4279..8cd17a6c 100644 --- a/examples/styling/src/main.rs +++ b/examples/styling/src/main.rs @@ -105,8 +105,7 @@ impl Sandbox for Styling { self.checkbox_value, "Check me!", Message::CheckboxToggled, - ) - .style(self.theme); + ); let toggler = Toggler::new( self.toggler_value, @@ -158,7 +157,7 @@ impl Sandbox for Styling { } mod style { - use iced::{checkbox, scrollable, text_input}; + use iced::{scrollable, text_input}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Theme { @@ -194,17 +193,8 @@ mod style { } } - impl<'a> From<Theme> for Box<dyn checkbox::StyleSheet + 'a> { - fn from(theme: Theme) -> Self { - match theme { - Theme::Light => Default::default(), - Theme::Dark => dark::Checkbox.into(), - } - } - } - mod dark { - use iced::{checkbox, scrollable, text_input, Color}; + use iced::{scrollable, text_input, Color}; const SURFACE: Color = Color::from_rgb( 0x40 as f32 / 255.0, @@ -314,32 +304,5 @@ mod style { } } } - - pub struct Checkbox; - - impl checkbox::StyleSheet for Checkbox { - fn active(&self, is_checked: bool) -> checkbox::Style { - checkbox::Style { - background: if is_checked { ACTIVE } else { SURFACE } - .into(), - checkmark_color: Color::WHITE, - border_radius: 2.0, - border_width: 1.0, - border_color: ACTIVE, - text_color: None, - } - } - - fn hovered(&self, is_checked: bool) -> checkbox::Style { - checkbox::Style { - background: Color { - a: 0.8, - ..if is_checked { ACTIVE } else { SURFACE } - } - .into(), - ..self.active(is_checked) - } - } - } } } diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs index 290cb114..cedbb7d8 100644 --- a/native/src/widget/checkbox.rs +++ b/native/src/widget/checkbox.rs @@ -12,7 +12,7 @@ use crate::{ Widget, }; -pub use iced_style::checkbox::{Style, StyleSheet}; +pub use iced_style::checkbox::{Appearance, StyleSheet}; /// A box that can be checked. /// @@ -32,7 +32,11 @@ pub use iced_style::checkbox::{Style, StyleSheet}; /// ///  #[allow(missing_debug_implementations)] -pub struct Checkbox<'a, Message, Renderer: text::Renderer> { +pub struct Checkbox<'a, Message, Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ is_checked: bool, on_toggle: Box<dyn Fn(bool) -> Message + 'a>, label: String, @@ -41,10 +45,14 @@ pub struct Checkbox<'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> Checkbox<'a, Message, Renderer> { +impl<'a, Message, Renderer> Checkbox<'a, Message, Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ /// The default size of a [`Checkbox`]. const DEFAULT_SIZE: u16 = 20; @@ -72,7 +80,7 @@ impl<'a, Message, Renderer: text::Renderer> Checkbox<'a, Message, Renderer> { spacing: Self::DEFAULT_SPACING, text_size: None, font: Renderer::Font::default(), - style_sheet: Default::default(), + style: Default::default(), } } @@ -111,9 +119,9 @@ impl<'a, Message, Renderer: text::Renderer> Checkbox<'a, Message, Renderer> { /// Sets the style of the [`Checkbox`]. 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 } } @@ -122,6 +130,7 @@ impl<'a, Message, Renderer> Widget<Message, Renderer> for Checkbox<'a, Message, Renderer> where Renderer: text::Renderer, + Renderer::Theme: StyleSheet, { fn width(&self) -> Length { self.width @@ -209,9 +218,9 @@ where let mut children = layout.children(); let custom_style = if is_mouse_over { - self.style_sheet.hovered(self.is_checked) + theme.hovered(self.style, self.is_checked) } else { - self.style_sheet.active(self.is_checked) + theme.active(self.style, self.is_checked) }; { @@ -266,8 +275,9 @@ where impl<'a, Message, Renderer> From<Checkbox<'a, Message, Renderer>> for Element<'a, Message, Renderer> where - Renderer: 'a + text::Renderer, Message: 'a, + Renderer: 'a + text::Renderer, + Renderer::Theme: StyleSheet, { fn from( checkbox: Checkbox<'a, Message, Renderer>, diff --git a/pure/src/helpers.rs b/pure/src/helpers.rs index b26e1c22..ebc8f14b 100644 --- a/pure/src/helpers.rs +++ b/pure/src/helpers.rs @@ -93,6 +93,7 @@ pub fn checkbox<'a, Message, Renderer>( ) -> widget::Checkbox<'a, Message, Renderer> where Renderer: iced_native::text::Renderer, + Renderer::Theme: widget::checkbox::StyleSheet, { widget::Checkbox::new(is_checked, label, f) } diff --git a/pure/src/widget/checkbox.rs b/pure/src/widget/checkbox.rs index a6a6f8de..4128876e 100644 --- a/pure/src/widget/checkbox.rs +++ b/pure/src/widget/checkbox.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::checkbox::{Checkbox, Style, StyleSheet}; +pub use iced_native::widget::checkbox::{Appearance, Checkbox, StyleSheet}; impl<'a, Message, Renderer> Widget<Message, Renderer> for Checkbox<'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 36226109..de460bec 100644 --- a/src/pure/widget.rs +++ b/src/pure/widget.rs @@ -23,7 +23,7 @@ pub mod button { pub mod checkbox { //! Show toggle controls using checkboxes. - pub use iced_pure::widget::checkbox::{Style, StyleSheet}; + pub use iced_pure::widget::checkbox::{Appearance, StyleSheet}; /// A box that can be checked. pub type Checkbox<'a, Message, Theme> = diff --git a/src/widget.rs b/src/widget.rs index 1634a1f2..4cbf02ef 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -39,7 +39,7 @@ pub mod button { pub mod checkbox { //! Show toggle controls using checkboxes. - pub use iced_native::widget::checkbox::{Style, StyleSheet}; + pub use iced_native::widget::checkbox::{Appearance, StyleSheet}; /// A box that can be checked. pub type Checkbox<'a, Message, Theme> = diff --git a/style/src/checkbox.rs b/style/src/checkbox.rs index de52e548..ba54b0a2 100644 --- a/style/src/checkbox.rs +++ b/style/src/checkbox.rs @@ -3,7 +3,7 @@ use iced_core::{Background, Color}; /// The appearance of a checkbox. #[derive(Debug, Clone, Copy)] -pub struct Style { +pub struct Appearance { pub background: Background, pub checkmark_color: Color, pub border_radius: f32, @@ -14,44 +14,9 @@ pub struct Style { /// A set of rules that dictate the style of a checkbox. pub trait StyleSheet { - fn active(&self, is_checked: bool) -> Style; + type Style: Default + Copy; - fn hovered(&self, is_checked: bool) -> Style; -} - -struct Default; - -impl StyleSheet for Default { - fn active(&self, _is_checked: bool) -> Style { - Style { - background: Background::Color(Color::from_rgb(0.95, 0.95, 0.95)), - checkmark_color: Color::from_rgb(0.3, 0.3, 0.3), - border_radius: 5.0, - border_width: 1.0, - border_color: Color::from_rgb(0.6, 0.6, 0.6), - text_color: None, - } - } - - fn hovered(&self, is_checked: bool) -> Style { - Style { - background: Background::Color(Color::from_rgb(0.90, 0.90, 0.90)), - ..self.active(is_checked) - } - } -} - -impl<'a> std::default::Default for Box<dyn StyleSheet + 'a> { - fn default() -> Self { - Box::new(Default) - } -} + fn active(&self, style: Self::Style, is_checked: bool) -> 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, is_checked: bool) -> Appearance; } diff --git a/style/src/theme.rs b/style/src/theme.rs index 305c5cc2..b0846c0e 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::checkbox; use crate::pane_grid; use crate::progress_bar; use crate::radio; @@ -122,6 +123,109 @@ impl button::StyleSheet for Theme { } /* + * Checkbox + */ + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Checkbox { + Primary, + Secondary, + Success, + Danger, +} + +impl Default for Checkbox { + fn default() -> Self { + Self::Primary + } +} + +impl checkbox::StyleSheet for Theme { + type Style = Checkbox; + + fn active( + &self, + style: Self::Style, + is_checked: bool, + ) -> checkbox::Appearance { + let palette = self.extended_palette(); + + match style { + Checkbox::Primary => checkbox_appearance( + palette.background.weak, + palette.primary.strong, + is_checked, + ), + Checkbox::Secondary => checkbox_appearance( + palette.background.weak, + palette.background.base, + is_checked, + ), + Checkbox::Success => checkbox_appearance( + palette.background.weak, + palette.success.base, + is_checked, + ), + Checkbox::Danger => checkbox_appearance( + palette.background.weak, + palette.danger.base, + is_checked, + ), + } + } + + fn hovered( + &self, + style: Self::Style, + is_checked: bool, + ) -> checkbox::Appearance { + let palette = self.extended_palette(); + + match style { + Checkbox::Primary => checkbox_appearance( + palette.background.strong, + palette.primary.strong, + is_checked, + ), + Checkbox::Secondary => checkbox_appearance( + palette.background.strong, + palette.background.strong, + is_checked, + ), + Checkbox::Success => checkbox_appearance( + palette.background.strong, + palette.success.strong, + is_checked, + ), + Checkbox::Danger => checkbox_appearance( + palette.background.strong, + palette.danger.strong, + is_checked, + ), + } + } +} + +fn checkbox_appearance( + base: palette::Pair, + accent: palette::Pair, + is_checked: bool, +) -> checkbox::Appearance { + checkbox::Appearance { + background: Background::Color(if is_checked { + accent.color + } else { + base.color + }), + checkmark_color: accent.text, + border_radius: 2.0, + border_width: 1.0, + border_color: accent.color, + text_color: None, + } +} + +/* * Slider */ impl slider::StyleSheet for Theme { |