diff options
Diffstat (limited to 'style/src/theme.rs')
-rw-r--r-- | style/src/theme.rs | 146 |
1 files changed, 138 insertions, 8 deletions
diff --git a/style/src/theme.rs b/style/src/theme.rs index 64497181..47010728 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -1,8 +1,7 @@ //! Use the built-in theme and styles. pub mod palette; -use self::palette::Extended; -pub use self::palette::Palette; +pub use palette::Palette; use crate::application; use crate::button; @@ -18,6 +17,7 @@ use crate::rule; use crate::scrollable; use crate::slider; use crate::svg; +use crate::text_editor; use crate::text_input; use crate::toggler; @@ -40,7 +40,16 @@ pub enum Theme { impl Theme { /// Creates a new custom [`Theme`] from the given [`Palette`]. pub fn custom(palette: Palette) -> Self { - Self::Custom(Box::new(Custom::new(palette))) + Self::custom_with_fn(palette, palette::Extended::generate) + } + + /// Creates a new custom [`Theme`] from the given [`Palette`], with + /// a custom generator of a [`palette::Extended`]. + pub fn custom_with_fn( + palette: Palette, + generate: impl FnOnce(Palette) -> palette::Extended, + ) -> Self { + Self::Custom(Box::new(Custom::with_fn(palette, generate))) } /// Returns the [`Palette`] of the [`Theme`]. @@ -66,15 +75,24 @@ impl Theme { #[derive(Debug, Clone, Copy, PartialEq)] pub struct Custom { palette: Palette, - extended: Extended, + extended: palette::Extended, } impl Custom { /// Creates a [`Custom`] theme from the given [`Palette`]. pub fn new(palette: Palette) -> Self { + Self::with_fn(palette, palette::Extended::generate) + } + + /// Creates a [`Custom`] theme from the given [`Palette`] with + /// a custom generator of a [`palette::Extended`]. + pub fn with_fn( + palette: Palette, + generate: impl FnOnce(Palette) -> palette::Extended, + ) -> Self { Self { palette, - extended: Extended::generate(palette), + extended: generate(palette), } } } @@ -376,7 +394,7 @@ impl container::StyleSheet for Theme { fn appearance(&self, style: &Self::Style) -> container::Appearance { match style { - Container::Transparent => Default::default(), + Container::Transparent => container::Appearance::default(), Container::Box => { let palette = self.extended_palette(); @@ -887,7 +905,7 @@ impl svg::StyleSheet for Theme { fn appearance(&self, style: &Self::Style) -> svg::Appearance { match style { - Svg::Default => Default::default(), + Svg::Default => svg::Appearance::default(), Svg::Custom(custom) => custom.appearance(self), } } @@ -1036,7 +1054,7 @@ impl text::StyleSheet for Theme { fn appearance(&self, style: Self::Style) -> text::Appearance { match style { - Text::Default => Default::default(), + Text::Default => text::Appearance::default(), Text::Color(c) => text::Appearance { color: Some(c) }, } } @@ -1157,3 +1175,115 @@ impl text_input::StyleSheet for Theme { self.placeholder_color(style) } } + +/// The style of a text input. +#[derive(Default)] +pub enum TextEditor { + /// The default style. + #[default] + Default, + /// A custom style. + Custom(Box<dyn text_editor::StyleSheet<Style = Theme>>), +} + +impl text_editor::StyleSheet for Theme { + type Style = TextEditor; + + fn active(&self, style: &Self::Style) -> text_editor::Appearance { + if let TextEditor::Custom(custom) = style { + return custom.active(self); + } + + let palette = self.extended_palette(); + + text_editor::Appearance { + background: palette.background.base.color.into(), + border_radius: 2.0.into(), + border_width: 1.0, + border_color: palette.background.strong.color, + } + } + + fn hovered(&self, style: &Self::Style) -> text_editor::Appearance { + if let TextEditor::Custom(custom) = style { + return custom.hovered(self); + } + + let palette = self.extended_palette(); + + text_editor::Appearance { + background: palette.background.base.color.into(), + border_radius: 2.0.into(), + border_width: 1.0, + border_color: palette.background.base.text, + } + } + + fn focused(&self, style: &Self::Style) -> text_editor::Appearance { + if let TextEditor::Custom(custom) = style { + return custom.focused(self); + } + + let palette = self.extended_palette(); + + text_editor::Appearance { + background: palette.background.base.color.into(), + border_radius: 2.0.into(), + border_width: 1.0, + border_color: palette.primary.strong.color, + } + } + + fn placeholder_color(&self, style: &Self::Style) -> Color { + if let TextEditor::Custom(custom) = style { + return custom.placeholder_color(self); + } + + let palette = self.extended_palette(); + + palette.background.strong.color + } + + fn value_color(&self, style: &Self::Style) -> Color { + if let TextEditor::Custom(custom) = style { + return custom.value_color(self); + } + + let palette = self.extended_palette(); + + palette.background.base.text + } + + fn selection_color(&self, style: &Self::Style) -> Color { + if let TextEditor::Custom(custom) = style { + return custom.selection_color(self); + } + + let palette = self.extended_palette(); + + palette.primary.weak.color + } + + fn disabled(&self, style: &Self::Style) -> text_editor::Appearance { + if let TextEditor::Custom(custom) = style { + return custom.disabled(self); + } + + let palette = self.extended_palette(); + + text_editor::Appearance { + background: palette.background.weak.color.into(), + border_radius: 2.0.into(), + border_width: 1.0, + border_color: palette.background.strong.color, + } + } + + fn disabled_color(&self, style: &Self::Style) -> Color { + if let TextEditor::Custom(custom) = style { + return custom.disabled_color(self); + } + + self.placeholder_color(style) + } +} |