summaryrefslogtreecommitdiffstats
path: root/style/src/theme.rs
diff options
context:
space:
mode:
Diffstat (limited to 'style/src/theme.rs')
-rw-r--r--style/src/theme.rs163
1 files changed, 157 insertions, 6 deletions
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)
+ }
+}