diff options
Diffstat (limited to 'style/src')
-rw-r--r-- | style/src/container.rs | 26 | ||||
-rw-r--r-- | style/src/lib.rs | 1 | ||||
-rw-r--r-- | style/src/svg.rs | 3 | ||||
-rw-r--r-- | style/src/text_editor.rs | 47 | ||||
-rw-r--r-- | style/src/theme.rs | 163 | ||||
-rw-r--r-- | style/src/theme/palette.rs | 3 |
6 files changed, 236 insertions, 7 deletions
diff --git a/style/src/container.rs b/style/src/container.rs index ec543ae4..490a9dab 100644 --- a/style/src/container.rs +++ b/style/src/container.rs @@ -1,5 +1,5 @@ //! Change the appearance of a container. -use iced_core::{Background, BorderRadius, Color}; +use crate::core::{Background, BorderRadius, Color, Pixels}; /// The appearance of a container. #[derive(Debug, Clone, Copy)] @@ -16,6 +16,30 @@ pub struct Appearance { pub border_color: Color, } +impl Appearance { + /// Derives a new [`Appearance`] with a border of the given [`Color`] and + /// `width`. + pub fn with_border( + self, + color: impl Into<Color>, + width: impl Into<Pixels>, + ) -> Self { + Self { + border_color: color.into(), + border_width: width.into().0, + ..self + } + } + + /// Derives a new [`Appearance`] with the given [`Background`]. + pub fn with_background(self, background: impl Into<Background>) -> Self { + Self { + background: Some(background.into()), + ..self + } + } +} + impl std::default::Default for Appearance { fn default() -> Self { Self { diff --git a/style/src/lib.rs b/style/src/lib.rs index 30f17a44..e4097434 100644 --- a/style/src/lib.rs +++ b/style/src/lib.rs @@ -29,6 +29,7 @@ pub mod rule; pub mod scrollable; pub mod slider; pub mod svg; +pub mod text_editor; pub mod text_input; pub mod theme; pub mod toggler; diff --git a/style/src/svg.rs b/style/src/svg.rs index 9378c1a7..5053f9f8 100644 --- a/style/src/svg.rs +++ b/style/src/svg.rs @@ -20,4 +20,7 @@ pub trait StyleSheet { /// Produces the [`Appearance`] of the svg. fn appearance(&self, style: &Self::Style) -> Appearance; + + /// Produces the hovered [`Appearance`] of a svg content. + fn hovered(&self, style: &Self::Style) -> Appearance; } diff --git a/style/src/text_editor.rs b/style/src/text_editor.rs new file mode 100644 index 00000000..f6bae7e6 --- /dev/null +++ b/style/src/text_editor.rs @@ -0,0 +1,47 @@ +//! Change the appearance of a text editor. +use crate::core::{Background, BorderRadius, Color}; + +/// The appearance of a text input. +#[derive(Debug, Clone, Copy)] +pub struct Appearance { + /// The [`Background`] of the text input. + pub background: Background, + /// The border radius of the text input. + pub border_radius: BorderRadius, + /// The border width of the text input. + pub border_width: f32, + /// The border [`Color`] of the text input. + pub border_color: Color, +} + +/// A set of rules that dictate the style of a text input. +pub trait StyleSheet { + /// The supported style of the [`StyleSheet`]. + type Style: Default; + + /// Produces the style of an active text input. + fn active(&self, style: &Self::Style) -> Appearance; + + /// Produces the style of a focused text input. + fn focused(&self, style: &Self::Style) -> Appearance; + + /// Produces the [`Color`] of the placeholder of a text input. + fn placeholder_color(&self, style: &Self::Style) -> Color; + + /// Produces the [`Color`] of the value of a text input. + fn value_color(&self, style: &Self::Style) -> Color; + + /// Produces the [`Color`] of the value of a disabled text input. + fn disabled_color(&self, style: &Self::Style) -> Color; + + /// Produces the [`Color`] of the selection of a text input. + fn selection_color(&self, style: &Self::Style) -> Color; + + /// Produces the style of an hovered text input. + fn hovered(&self, style: &Self::Style) -> Appearance { + self.focused(style) + } + + /// Produces the style of a disabled text input. + fn disabled(&self, style: &Self::Style) -> Appearance; +} diff --git a/style/src/theme.rs b/style/src/theme.rs index 3c1f2de6..f78587e5 100644 --- a/style/src/theme.rs +++ b/style/src/theme.rs @@ -17,11 +17,13 @@ use crate::rule; use crate::scrollable; use crate::slider; use crate::svg; +use crate::text_editor; use crate::text_input; use crate::toggler; use iced_core::{Background, Color, Vector}; +use std::fmt; use std::rc::Rc; /// A built-in theme. @@ -37,18 +39,22 @@ pub enum Theme { } impl Theme { + /// A list with all the defined themes. + pub const ALL: &'static [Self] = &[Self::Light, Self::Dark]; + /// Creates a new custom [`Theme`] from the given [`Palette`]. - pub fn custom(palette: Palette) -> Self { - Self::custom_with_fn(palette, palette::Extended::generate) + pub fn custom(name: String, palette: Palette) -> Self { + Self::custom_with_fn(name, 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( + name: String, palette: Palette, generate: impl FnOnce(Palette) -> palette::Extended, ) -> Self { - Self::Custom(Box::new(Custom::with_fn(palette, generate))) + Self::Custom(Box::new(Custom::with_fn(name, palette, generate))) } /// Returns the [`Palette`] of the [`Theme`]. @@ -70,32 +76,51 @@ impl Theme { } } +impl fmt::Display for Theme { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Light => write!(f, "Light"), + Self::Dark => write!(f, "Dark"), + Self::Custom(custom) => custom.fmt(f), + } + } +} + /// A [`Theme`] with a customized [`Palette`]. -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, PartialEq)] pub struct Custom { + name: String, palette: Palette, 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) + pub fn new(name: String, palette: Palette) -> Self { + Self::with_fn(name, palette, palette::Extended::generate) } /// Creates a [`Custom`] theme from the given [`Palette`] with /// a custom generator of a [`palette::Extended`]. pub fn with_fn( + name: String, palette: Palette, generate: impl FnOnce(Palette) -> palette::Extended, ) -> Self { Self { + name, palette, extended: generate(palette), } } } +impl fmt::Display for Custom { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.name) + } +} + /// The style of an application. #[derive(Default)] pub enum Application { @@ -382,6 +407,12 @@ pub enum Container { Custom(Box<dyn container::StyleSheet<Style = Theme>>), } +impl From<container::Appearance> for Container { + fn from(appearance: container::Appearance) -> Self { + Self::Custom(Box::new(move |_: &_| appearance)) + } +} + impl<T: Fn(&Theme) -> container::Appearance + 'static> From<T> for Container { fn from(f: T) -> Self { Self::Custom(Box::new(f)) @@ -908,6 +939,10 @@ impl svg::StyleSheet for Theme { Svg::Custom(custom) => custom.appearance(self), } } + + fn hovered(&self, style: &Self::Style) -> svg::Appearance { + self.appearance(style) + } } impl svg::StyleSheet for fn(&Theme) -> svg::Appearance { @@ -916,6 +951,10 @@ impl svg::StyleSheet for fn(&Theme) -> svg::Appearance { fn appearance(&self, style: &Self::Style) -> svg::Appearance { (self)(style) } + + fn hovered(&self, style: &Self::Style) -> svg::Appearance { + self.appearance(style) + } } /// The style of a scrollable. @@ -1174,3 +1213,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) + } +} diff --git a/style/src/theme/palette.rs b/style/src/theme/palette.rs index aaeb799d..76977a29 100644 --- a/style/src/theme/palette.rs +++ b/style/src/theme/palette.rs @@ -82,6 +82,8 @@ pub struct Extended { pub success: Success, /// The set of danger colors. pub danger: Danger, + /// Whether the palette is dark or not. + pub is_dark: bool, } /// The built-in light variant of an [`Extended`] palette. @@ -113,6 +115,7 @@ impl Extended { palette.background, palette.text, ), + is_dark: is_dark(palette.background), } } } |