summaryrefslogtreecommitdiff
path: root/crates/material_theme/src
diff options
context:
space:
mode:
authorpml68 <contact@pml68.dev>2025-04-28 10:56:49 +0200
committerpml68 <contact@pml68.dev>2025-04-28 10:56:49 +0200
commitdac7e82e0bff128097653fe05829b2d576fcdb2f (patch)
tree6f36736e79eecd6904933c6876af1df58e6b605b /crates/material_theme/src
parentfeat(material_theme): implement `image::Catalog` (under feature flag) (diff)
downloadiced-builder-dac7e82e0bff128097653fe05829b2d576fcdb2f.tar.gz
refactor(material_theme)!: make `Theme` an enum with `Custom` variant
Diffstat (limited to 'crates/material_theme/src')
-rw-r--r--crates/material_theme/src/button.rs103
-rw-r--r--crates/material_theme/src/checkbox.rs30
-rw-r--r--crates/material_theme/src/container.rs119
-rw-r--r--crates/material_theme/src/dialog.rs4
-rw-r--r--crates/material_theme/src/image.rs8
-rw-r--r--crates/material_theme/src/lib.rs111
-rw-r--r--crates/material_theme/src/menu.rs2
-rw-r--r--crates/material_theme/src/pane_grid.rs8
-rw-r--r--crates/material_theme/src/pick_list.rs2
-rw-r--r--crates/material_theme/src/progress_bar.rs4
-rw-r--r--crates/material_theme/src/qr_code.rs2
-rw-r--r--crates/material_theme/src/radio.rs11
-rw-r--r--crates/material_theme/src/rule.rs4
-rw-r--r--crates/material_theme/src/scrollable.rs33
-rw-r--r--crates/material_theme/src/slider.rs6
-rw-r--r--crates/material_theme/src/text.rs22
-rw-r--r--crates/material_theme/src/text_editor.rs38
-rw-r--r--crates/material_theme/src/text_input.rs38
-rw-r--r--crates/material_theme/src/toggler.rs28
-rw-r--r--crates/material_theme/src/utils.rs18
20 files changed, 282 insertions, 309 deletions
diff --git a/crates/material_theme/src/button.rs b/crates/material_theme/src/button.rs
index e1369eb..3f16bc7 100644
--- a/crates/material_theme/src/button.rs
+++ b/crates/material_theme/src/button.rs
@@ -3,8 +3,8 @@ use iced_widget::core::{Background, Border, Color, border};
use crate::Theme;
use crate::utils::{
- DISABLED_CONTAINER_OPACITY, DISABLED_TEXT_OPACITY, HOVERED_LAYER_OPACITY,
- PRESSED_LAYER_OPACITY, elevation, mix, shadow_from_elevation,
+ HOVERED_LAYER_OPACITY, PRESSED_LAYER_OPACITY, disabled_container,
+ disabled_text, elevation, mix, shadow_from_elevation,
};
impl Catalog for Theme {
@@ -20,9 +20,8 @@ impl Catalog for Theme {
}
fn button(
- foreground: Color,
background: Color,
- tone_overlay: Color,
+ foreground: Color,
disabled: Color,
shadow_color: Color,
elevation_level: u8,
@@ -40,7 +39,7 @@ fn button(
Status::Pressed => Style {
background: Some(Background::Color(mix(
background,
- tone_overlay,
+ foreground,
HOVERED_LAYER_OPACITY,
))),
..active
@@ -48,25 +47,18 @@ fn button(
Status::Hovered => Style {
background: Some(Background::Color(mix(
background,
- tone_overlay,
+ foreground,
PRESSED_LAYER_OPACITY,
))),
- text_color: foreground,
- border: border::rounded(400),
shadow: shadow_from_elevation(
elevation(elevation_level + 1),
shadow_color,
),
+ ..active
},
Status::Disabled => Style {
- background: Some(Background::Color(Color {
- a: DISABLED_CONTAINER_OPACITY,
- ..disabled
- })),
- text_color: Color {
- a: DISABLED_TEXT_OPACITY,
- ..disabled
- },
+ background: Some(Background::Color(disabled_container(disabled))),
+ text_color: disabled_text(disabled),
border: border::rounded(400),
..Default::default()
},
@@ -74,70 +66,46 @@ fn button(
}
pub fn elevated(theme: &Theme, status: Status) -> Style {
- let surface_colors = theme.colorscheme.surface;
+ let surface = theme.colors().surface;
- let foreground = theme.colorscheme.primary.color;
- let background = surface_colors.surface_container.low;
- let disabled = surface_colors.on_surface;
+ let foreground = theme.colors().primary.color;
+ let background = surface.surface_container.low;
+ let disabled = surface.on_surface;
- let shadow_color = theme.colorscheme.shadow;
+ let shadow_color = theme.colors().shadow;
- button(
- foreground,
- background,
- foreground,
- disabled,
- shadow_color,
- 1,
- status,
- )
+ button(background, foreground, disabled, shadow_color, 1, status)
}
pub fn filled(theme: &Theme, status: Status) -> Style {
- let primary_colors = theme.colorscheme.primary;
+ let primary = theme.colors().primary;
- let foreground = primary_colors.on_primary;
- let background = primary_colors.color;
- let disabled = theme.colorscheme.surface.on_surface;
+ let foreground = primary.on_primary;
+ let background = primary.color;
+ let disabled = theme.colors().surface.on_surface;
- let shadow_color = theme.colorscheme.shadow;
+ let shadow_color = theme.colors().shadow;
- button(
- foreground,
- background,
- foreground,
- disabled,
- shadow_color,
- 0,
- status,
- )
+ button(background, foreground, disabled, shadow_color, 0, status)
}
pub fn filled_tonal(theme: &Theme, status: Status) -> Style {
- let secondary_colors = theme.colorscheme.secondary;
+ let secondary = theme.colors().secondary;
- let foreground = secondary_colors.on_secondary_container;
- let background = secondary_colors.secondary_container;
- let disabled = theme.colorscheme.surface.on_surface;
- let shadow_color = theme.colorscheme.shadow;
+ let foreground = secondary.on_secondary_container;
+ let background = secondary.secondary_container;
+ let disabled = theme.colors().surface.on_surface;
+ let shadow_color = theme.colors().shadow;
- button(
- foreground,
- background,
- foreground,
- disabled,
- shadow_color,
- 0,
- status,
- )
+ button(background, foreground, disabled, shadow_color, 0, status)
}
pub fn outlined(theme: &Theme, status: Status) -> Style {
- let foreground = theme.colorscheme.primary.color;
+ let foreground = theme.colors().primary.color;
let background = Color::TRANSPARENT;
- let disabled = theme.colorscheme.surface.on_surface;
+ let disabled = theme.colors().surface.on_surface;
- let outline = theme.colorscheme.outline.color;
+ let outline = theme.colors().outline.color;
let border = match status {
Status::Active | Status::Pressed | Status::Hovered => Border {
@@ -146,17 +114,13 @@ pub fn outlined(theme: &Theme, status: Status) -> Style {
radius: 400.into(),
},
Status::Disabled => Border {
- color: Color {
- a: DISABLED_CONTAINER_OPACITY,
- ..disabled
- },
+ color: disabled_container(disabled),
width: 1.0,
radius: 400.into(),
},
};
let style = button(
- foreground,
background,
foreground,
disabled,
@@ -169,12 +133,11 @@ pub fn outlined(theme: &Theme, status: Status) -> Style {
}
pub fn text(theme: &Theme, status: Status) -> Style {
- let foreground = theme.colorscheme.primary.color;
+ let foreground = theme.colors().primary.color;
let background = Color::TRANSPARENT;
- let disabled = theme.colorscheme.surface.on_surface;
+ let disabled = theme.colors().surface.on_surface;
let style = button(
- foreground,
background,
foreground,
disabled,
@@ -185,7 +148,7 @@ pub fn text(theme: &Theme, status: Status) -> Style {
match status {
Status::Hovered | Status::Pressed => style,
- _ => Style {
+ Status::Active | Status::Disabled => Style {
background: None,
..style
},
diff --git a/crates/material_theme/src/checkbox.rs b/crates/material_theme/src/checkbox.rs
index ff038b0..7a3729c 100644
--- a/crates/material_theme/src/checkbox.rs
+++ b/crates/material_theme/src/checkbox.rs
@@ -2,7 +2,7 @@ use iced_widget::checkbox::{Catalog, Status, Style, StyleFn};
use iced_widget::core::{Background, Border, Color, border};
use super::Theme;
-use crate::utils::{DISABLED_CONTAINER_OPACITY, HOVERED_LAYER_OPACITY, mix};
+use crate::utils::{HOVERED_LAYER_OPACITY, disabled_text, mix};
impl Catalog for Theme {
type Class<'a> = StyleFn<'a, Self>;
@@ -45,8 +45,8 @@ pub fn styled(
}
pub fn default(theme: &Theme, status: Status) -> Style {
- let surface = theme.colorscheme.surface;
- let primary = theme.colorscheme.primary;
+ let surface = theme.colors().surface;
+ let primary = theme.colors().primary;
match status {
Status::Active { is_checked } => styled(
@@ -69,16 +69,10 @@ pub fn default(theme: &Theme, status: Status) -> Style {
is_checked,
),
Status::Disabled { is_checked } => styled(
- Color {
- a: DISABLED_CONTAINER_OPACITY,
- ..surface.on_surface
- },
+ disabled_text(surface.on_surface),
None,
surface.color,
- Color {
- a: DISABLED_CONTAINER_OPACITY,
- ..surface.on_surface
- },
+ disabled_text(surface.on_surface),
Some(surface.on_surface),
is_checked,
),
@@ -86,8 +80,8 @@ pub fn default(theme: &Theme, status: Status) -> Style {
}
pub fn error(theme: &Theme, status: Status) -> Style {
- let surface = theme.colorscheme.surface;
- let error = theme.colorscheme.error;
+ let surface = theme.colors().surface;
+ let error = theme.colors().error;
match status {
Status::Active { is_checked } => styled(
@@ -110,16 +104,10 @@ pub fn error(theme: &Theme, status: Status) -> Style {
is_checked,
),
Status::Disabled { is_checked } => styled(
- Color {
- a: DISABLED_CONTAINER_OPACITY,
- ..surface.on_surface
- },
+ disabled_text(surface.on_surface),
None,
surface.color,
- Color {
- a: DISABLED_CONTAINER_OPACITY,
- ..surface.on_surface
- },
+ disabled_text(surface.on_surface),
Some(surface.on_surface),
is_checked,
),
diff --git a/crates/material_theme/src/container.rs b/crates/material_theme/src/container.rs
index a14cfd5..5c253ad 100644
--- a/crates/material_theme/src/container.rs
+++ b/crates/material_theme/src/container.rs
@@ -1,5 +1,5 @@
use iced_widget::container::{Catalog, Style, StyleFn};
-use iced_widget::core::{Background, border};
+use iced_widget::core::{Background, Border, border};
use super::Theme;
@@ -23,151 +23,178 @@ pub fn transparent(_theme: &Theme) -> Style {
}
pub fn primary(theme: &Theme) -> Style {
- let colors = theme.colorscheme.primary;
+ let primary = theme.colors().primary;
+
Style {
- background: Some(Background::Color(colors.color)),
- text_color: Some(colors.on_primary),
+ background: Some(Background::Color(primary.color)),
+ text_color: Some(primary.on_primary),
border: border::rounded(4),
..Style::default()
}
}
pub fn primary_container(theme: &Theme) -> Style {
- let colors = theme.colorscheme.primary;
+ let primary = theme.colors().primary;
+
Style {
- background: Some(Background::Color(colors.primary_container)),
- text_color: Some(colors.on_primary_container),
+ background: Some(Background::Color(primary.primary_container)),
+ text_color: Some(primary.on_primary_container),
border: border::rounded(8),
..Style::default()
}
}
pub fn secondary(theme: &Theme) -> Style {
- let colors = theme.colorscheme.secondary;
+ let secondary = theme.colors().secondary;
+
Style {
- background: Some(Background::Color(colors.color)),
- text_color: Some(colors.on_secondary),
+ background: Some(Background::Color(secondary.color)),
+ text_color: Some(secondary.on_secondary),
border: border::rounded(4),
..Style::default()
}
}
pub fn secondary_container(theme: &Theme) -> Style {
- let colors = theme.colorscheme.secondary;
+ let secondary = theme.colors().secondary;
+
Style {
- background: Some(Background::Color(colors.secondary_container)),
- text_color: Some(colors.on_secondary_container),
+ background: Some(Background::Color(secondary.secondary_container)),
+ text_color: Some(secondary.on_secondary_container),
border: border::rounded(8),
..Style::default()
}
}
pub fn tertiary(theme: &Theme) -> Style {
- let colors = theme.colorscheme.tertiary;
+ let tertiary = theme.colors().tertiary;
+
Style {
- background: Some(Background::Color(colors.color)),
- text_color: Some(colors.on_tertiary),
+ background: Some(Background::Color(tertiary.color)),
+ text_color: Some(tertiary.on_tertiary),
border: border::rounded(4),
..Style::default()
}
}
pub fn tertiary_container(theme: &Theme) -> Style {
- let colors = theme.colorscheme.tertiary;
+ let tertiary = theme.colors().tertiary;
+
Style {
- background: Some(Background::Color(colors.tertiary_container)),
- text_color: Some(colors.on_tertiary_container),
+ background: Some(Background::Color(tertiary.tertiary_container)),
+ text_color: Some(tertiary.on_tertiary_container),
border: border::rounded(8),
..Style::default()
}
}
pub fn error(theme: &Theme) -> Style {
- let colors = theme.colorscheme.error;
+ let error = theme.colors().error;
+
Style {
- background: Some(Background::Color(colors.color)),
- text_color: Some(colors.on_error),
+ background: Some(Background::Color(error.color)),
+ text_color: Some(error.on_error),
border: border::rounded(4),
..Style::default()
}
}
pub fn error_container(theme: &Theme) -> Style {
- let colors = theme.colorscheme.error;
+ let error = theme.colors().error;
+
Style {
- background: Some(Background::Color(colors.error_container)),
- text_color: Some(colors.on_error_container),
+ background: Some(Background::Color(error.error_container)),
+ text_color: Some(error.on_error_container),
border: border::rounded(8),
..Style::default()
}
}
pub fn surface(theme: &Theme) -> Style {
- let colors = theme.colorscheme.surface;
+ let surface = theme.colors().surface;
+
Style {
- background: Some(Background::Color(colors.color)),
- text_color: Some(colors.on_surface),
+ background: Some(Background::Color(surface.color)),
+ text_color: Some(surface.on_surface),
border: border::rounded(4),
..Style::default()
}
}
pub fn surface_container_lowest(theme: &Theme) -> Style {
- let colors = theme.colorscheme.surface;
+ let surface = theme.colors().surface;
+
Style {
- background: Some(Background::Color(colors.surface_container.lowest)),
- text_color: Some(colors.on_surface),
+ background: Some(Background::Color(surface.surface_container.lowest)),
+ text_color: Some(surface.on_surface),
border: border::rounded(8),
..Style::default()
}
}
pub fn surface_container_low(theme: &Theme) -> Style {
- let colors = theme.colorscheme.surface;
+ let surface = theme.colors().surface;
+
Style {
- background: Some(Background::Color(colors.surface_container.low)),
- text_color: Some(colors.on_surface),
+ background: Some(Background::Color(surface.surface_container.low)),
+ text_color: Some(surface.on_surface),
border: border::rounded(8),
..Style::default()
}
}
pub fn surface_container(theme: &Theme) -> Style {
- let colors = theme.colorscheme.surface;
+ let surface = theme.colors().surface;
+
Style {
- background: Some(Background::Color(colors.surface_container.base)),
- text_color: Some(colors.on_surface),
+ background: Some(Background::Color(surface.surface_container.base)),
+ text_color: Some(surface.on_surface),
border: border::rounded(8),
..Style::default()
}
}
pub fn surface_container_high(theme: &Theme) -> Style {
- let colors = theme.colorscheme.surface;
+ let surface = theme.colors().surface;
+
Style {
- background: Some(Background::Color(colors.surface_container.high)),
- text_color: Some(colors.on_surface),
+ background: Some(Background::Color(surface.surface_container.high)),
+ text_color: Some(surface.on_surface),
border: border::rounded(8),
..Style::default()
}
}
pub fn surface_container_highest(theme: &Theme) -> Style {
- let colors = theme.colorscheme.surface;
+ let surface = theme.colors().surface;
+
Style {
- background: Some(Background::Color(colors.surface_container.highest)),
- text_color: Some(colors.on_surface),
+ background: Some(Background::Color(surface.surface_container.highest)),
+ text_color: Some(surface.on_surface),
border: border::rounded(8),
..Style::default()
}
}
pub fn inverse_surface(theme: &Theme) -> Style {
- let colors = theme.colorscheme.inverse;
+ let inverse = theme.colors().inverse;
+
Style {
- background: Some(Background::Color(colors.inverse_surface)),
- text_color: Some(colors.inverse_on_surface),
+ background: Some(Background::Color(inverse.inverse_surface)),
+ text_color: Some(inverse.inverse_on_surface),
border: border::rounded(4),
..Style::default()
}
}
+
+pub fn outlined(theme: &Theme) -> Style {
+ let base = transparent(theme);
+
+ Style {
+ border: Border {
+ color: theme.colors().outline.color,
+ ..base.border
+ },
+ ..base
+ }
+}
diff --git a/crates/material_theme/src/dialog.rs b/crates/material_theme/src/dialog.rs
index a022548..c839948 100644
--- a/crates/material_theme/src/dialog.rs
+++ b/crates/material_theme/src/dialog.rs
@@ -25,7 +25,7 @@ impl Catalog for Theme {
}
pub fn default_container(theme: &Theme) -> container::Style {
- let colors = theme.colorscheme.surface;
+ let colors = theme.colors().surface;
container::Style {
background: Some(Background::Color(colors.surface_container.high)),
text_color: Some(colors.on_surface_variant),
@@ -36,6 +36,6 @@ pub fn default_container(theme: &Theme) -> container::Style {
pub fn default(theme: &Theme) -> Style {
Style {
- backdrop_color: theme.colorscheme.scrim,
+ backdrop_color: theme.colors().scrim,
}
}
diff --git a/crates/material_theme/src/image.rs b/crates/material_theme/src/image.rs
index de5942a..4251b39 100644
--- a/crates/material_theme/src/image.rs
+++ b/crates/material_theme/src/image.rs
@@ -1,21 +1,15 @@
-use iced_widget::core::{Background, Border, Color, border};
use iced_widget::image::{Catalog, Style, StyleFn};
use super::Theme;
-use crate::utils::{elevation, shadow_from_elevation};
impl Catalog for Theme {
type Class<'a> = StyleFn<'a, Self>;
fn default<'a>() -> Self::Class<'a> {
- Box::new(default)
+ Box::new(|_theme| Style::default())
}
fn style(&self, class: &Self::Class<'_>) -> Style {
class(self)
}
}
-
-pub fn default(_theme: &Theme) -> Style {
- Style::default()
-}
diff --git a/crates/material_theme/src/lib.rs b/crates/material_theme/src/lib.rs
index 1b4f90e..7b6ac58 100644
--- a/crates/material_theme/src/lib.rs
+++ b/crates/material_theme/src/lib.rs
@@ -2,6 +2,7 @@ use std::sync::LazyLock;
use iced_widget::core::Color;
use iced_widget::core::theme::{Base, Style};
+use utils::{lightness, mix};
pub mod button;
pub mod checkbox;
@@ -45,31 +46,47 @@ macro_rules! from_argb {
}};
}
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[allow(clippy::large_enum_variant)]
+#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
-pub struct Theme {
- pub name: &'static str,
- #[cfg_attr(feature = "serde", serde(flatten))]
- pub colorscheme: ColorScheme,
+pub enum Theme {
+ Dark,
+ Light,
+ Custom(Custom),
}
impl Theme {
- pub const ALL: &'static [Self] = &[Self::DARK, Self::LIGHT];
-
- pub const DARK: Self = Self {
- name: "Dark",
- colorscheme: ColorScheme::DARK,
- };
-
- pub const LIGHT: Self = Self {
- name: "Light",
- colorscheme: ColorScheme::LIGHT,
- };
+ pub const ALL: &'static [Self] = &[Self::Dark, Self::Light];
pub fn new(name: impl Into<String>, colorscheme: ColorScheme) -> Self {
- Self {
- name: Box::leak(name.into().into_boxed_str()),
+ Self::Custom(Custom {
+ name: name.into(),
colorscheme,
+ is_dark: lightness(colorscheme.surface.color) <= 0.5,
+ })
+ }
+
+ pub fn name(&self) -> &str {
+ match self {
+ Self::Dark => "Dark",
+ Self::Light => "Light",
+ Self::Custom(custom) => &custom.name,
+ }
+ }
+
+ pub fn colors(&self) -> ColorScheme {
+ match self {
+ Self::Dark => ColorScheme::DARK,
+ Self::Light => ColorScheme::LIGHT,
+ Self::Custom(custom) => custom.colorscheme,
+ }
+ }
+
+ pub fn is_dark(&self) -> bool {
+ match self {
+ Self::Dark => true,
+ Self::Light => false,
+ Self::Custom(custom) => custom.is_dark,
}
}
}
@@ -80,43 +97,39 @@ impl Default for Theme {
match dark_light::detect().unwrap_or(dark_light::Mode::Unspecified)
{
dark_light::Mode::Dark | dark_light::Mode::Unspecified => {
- Theme::DARK
+ Theme::Dark
}
- dark_light::Mode::Light => Theme::LIGHT,
+ dark_light::Mode::Light => Theme::Light,
}
});
- *DEFAULT
+ DEFAULT.clone()
}
}
impl std::fmt::Display for Theme {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- write!(f, "{}", self.name)
+ write!(f, "{}", self.name())
}
}
impl Base for Theme {
fn base(&self) -> Style {
Style {
- background_color: self.colorscheme.surface.color,
- text_color: self.colorscheme.surface.on_surface,
+ background_color: self.colors().surface.color,
+ text_color: self.colors().surface.on_surface,
}
}
fn palette(&self) -> Option<iced_widget::theme::Palette> {
- let colors = self.colorscheme;
+ let colors = self.colors();
Some(iced_widget::theme::Palette {
background: colors.surface.color,
text: colors.surface.on_surface,
primary: colors.primary.color,
success: colors.primary.primary_container,
- warning: utils::mix(
- from_argb!(0xffffff00),
- colors.primary.color,
- 0.25,
- ),
+ warning: mix(from_argb!(0xffffff00), colors.primary.color, 0.25),
danger: colors.error.color,
})
}
@@ -129,18 +142,44 @@ impl iced_anim::Animate for Theme {
}
fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
- self.colorscheme.update(components);
- self.name = "Animating Theme";
+ let mut colorscheme = self.colors();
+ colorscheme.update(components);
+ *self = Self::new("Animating Theme", colorscheme);
}
fn distance_to(&self, end: &Self) -> Vec<f32> {
- self.colorscheme.distance_to(&end.colorscheme)
+ self.colors().distance_to(&end.colors())
}
fn lerp(&mut self, start: &Self, end: &Self, progress: f32) {
- self.colorscheme
- .lerp(&start.colorscheme, &end.colorscheme, progress);
- self.name = "Animating Theme";
+ let mut colorscheme = self.colors();
+ colorscheme.lerp(&start.colors(), &end.colors(), progress);
+ *self = Self::new("Animating Theme", colorscheme);
+ }
+}
+
+#[derive(Debug, PartialEq)]
+#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+pub struct Custom {
+ pub name: String,
+ #[cfg_attr(feature = "serde", serde(flatten))]
+ pub colorscheme: ColorScheme,
+ pub is_dark: bool,
+}
+
+impl Clone for Custom {
+ fn clone(&self) -> Self {
+ Self {
+ name: self.name.clone(),
+ colorscheme: self.colorscheme,
+ is_dark: self.is_dark,
+ }
+ }
+
+ fn clone_from(&mut self, source: &Self) {
+ self.name.clone_from(&source.name);
+ self.colorscheme = source.colorscheme;
+ self.is_dark = source.is_dark;
}
}
diff --git a/crates/material_theme/src/menu.rs b/crates/material_theme/src/menu.rs
index 9f43c72..d595c2f 100644
--- a/crates/material_theme/src/menu.rs
+++ b/crates/material_theme/src/menu.rs
@@ -17,7 +17,7 @@ impl Catalog for Theme {
}
pub fn default(theme: &Theme) -> Style {
- let colors = theme.colorscheme.surface;
+ let colors = theme.colors().surface;
Style {
border: border::rounded(4),
diff --git a/crates/material_theme/src/pane_grid.rs b/crates/material_theme/src/pane_grid.rs
index d66e475..fb69a32 100644
--- a/crates/material_theme/src/pane_grid.rs
+++ b/crates/material_theme/src/pane_grid.rs
@@ -20,18 +20,18 @@ pub fn default(theme: &Theme) -> Style {
Style {
hovered_region: Highlight {
background: Background::Color(mix(
- theme.colorscheme.tertiary.tertiary_container,
- theme.colorscheme.surface.on_surface,
+ theme.colors().tertiary.tertiary_container,
+ theme.colors().surface.on_surface,
HOVERED_LAYER_OPACITY,
)),
border: border::rounded(12),
},
picked_split: Line {
- color: theme.colorscheme.outline.variant,
+ color: theme.colors().outline.variant,
width: 2.0,
},
hovered_split: Line {
- color: theme.colorscheme.surface.on_surface,
+ color: theme.colors().surface.on_surface,
width: 6.0,
},
}
diff --git a/crates/material_theme/src/pick_list.rs b/crates/material_theme/src/pick_list.rs
index 4b34871..1fe015e 100644
--- a/crates/material_theme/src/pick_list.rs
+++ b/crates/material_theme/src/pick_list.rs
@@ -20,7 +20,7 @@ impl Catalog for Theme {
}
pub fn default(theme: &Theme, status: Status) -> Style {
- let surface = theme.colorscheme.surface;
+ let surface = theme.colors().surface;
let active = Style {
text_color: surface.on_surface,
diff --git a/crates/material_theme/src/progress_bar.rs b/crates/material_theme/src/progress_bar.rs
index f686fff..9b4e844 100644
--- a/crates/material_theme/src/progress_bar.rs
+++ b/crates/material_theme/src/progress_bar.rs
@@ -18,9 +18,9 @@ impl Catalog for Theme {
pub fn default(theme: &Theme) -> Style {
Style {
background: Background::Color(
- theme.colorscheme.secondary.secondary_container,
+ theme.colors().secondary.secondary_container,
),
- bar: Background::Color(theme.colorscheme.primary.color),
+ bar: Background::Color(theme.colors().primary.color),
border: border::rounded(400),
}
}
diff --git a/crates/material_theme/src/qr_code.rs b/crates/material_theme/src/qr_code.rs
index f93fb77..f603440 100644
--- a/crates/material_theme/src/qr_code.rs
+++ b/crates/material_theme/src/qr_code.rs
@@ -15,7 +15,7 @@ impl Catalog for Theme {
}
pub fn default(theme: &Theme) -> Style {
- let surface = theme.colorscheme.surface;
+ let surface = theme.colors().surface;
Style {
cell: surface.on_surface,
diff --git a/crates/material_theme/src/radio.rs b/crates/material_theme/src/radio.rs
index d249413..7fb7a3f 100644
--- a/crates/material_theme/src/radio.rs
+++ b/crates/material_theme/src/radio.rs
@@ -2,7 +2,7 @@ use iced_widget::core::{Background, Color};
use iced_widget::radio::{Catalog, Status, Style, StyleFn};
use super::Theme;
-use crate::utils::{DISABLED_TEXT_OPACITY, HOVERED_LAYER_OPACITY, mix};
+use crate::utils::{HOVERED_LAYER_OPACITY, disabled_text, mix};
impl Catalog for Theme {
type Class<'a> = StyleFn<'a, Self>;
@@ -17,8 +17,8 @@ impl Catalog for Theme {
}
pub fn default(theme: &Theme, status: Status) -> Style {
- let surface = theme.colorscheme.surface;
- let primary = theme.colorscheme.primary;
+ let surface = theme.colors().surface;
+ let primary = theme.colors().primary;
let active = Style {
background: Color::TRANSPARENT.into(),
@@ -46,10 +46,7 @@ pub fn default(theme: &Theme, status: Status) -> Style {
border_color: if is_selected {
mix(primary.color, surface.on_surface, HOVERED_LAYER_OPACITY)
} else {
- Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- }
+ disabled_text(surface.on_surface)
},
background: Background::Color(if is_selected {
Color {
diff --git a/crates/material_theme/src/rule.rs b/crates/material_theme/src/rule.rs
index e433005..36e4dd4 100644
--- a/crates/material_theme/src/rule.rs
+++ b/crates/material_theme/src/rule.rs
@@ -17,7 +17,7 @@ impl Catalog for Theme {
pub fn inset(theme: &Theme) -> Style {
Style {
- color: theme.colorscheme.outline.variant,
+ color: theme.colors().outline.variant,
fill_mode: FillMode::Padded(8),
width: 1,
radius: Radius::default(),
@@ -25,7 +25,7 @@ pub fn inset(theme: &Theme) -> Style {
}
pub fn full_width(theme: &Theme) -> Style {
Style {
- color: theme.colorscheme.outline.variant,
+ color: theme.colors().outline.variant,
fill_mode: FillMode::Full,
width: 1,
radius: Radius::default(),
diff --git a/crates/material_theme/src/scrollable.rs b/crates/material_theme/src/scrollable.rs
index ee739ba..341f047 100644
--- a/crates/material_theme/src/scrollable.rs
+++ b/crates/material_theme/src/scrollable.rs
@@ -1,4 +1,4 @@
-use iced_widget::core::{Border, Color, border};
+use iced_widget::core::{Background, Border, border};
use iced_widget::scrollable::{
Catalog, Rail, Scroller, Status, Style, StyleFn,
};
@@ -7,8 +7,8 @@ use super::Theme;
use super::container::surface_container;
use super::utils::mix;
use crate::utils::{
- DISABLED_CONTAINER_OPACITY, DISABLED_TEXT_OPACITY, HOVERED_LAYER_OPACITY,
- PRESSED_LAYER_OPACITY,
+ HOVERED_LAYER_OPACITY, PRESSED_LAYER_OPACITY, disabled_container,
+ disabled_text,
};
impl Catalog for Theme {
@@ -24,30 +24,23 @@ impl Catalog for Theme {
}
pub fn default(theme: &Theme, status: Status) -> Style {
- let colors = theme.colorscheme.surface;
+ let surface = theme.colors().surface;
let active = Rail {
background: None,
scroller: Scroller {
- color: colors.on_surface,
+ color: surface.on_surface,
border: border::rounded(400),
},
border: Border::default(),
};
let disabled = Rail {
- background: Some(
- Color {
- a: DISABLED_CONTAINER_OPACITY,
- ..colors.on_surface
- }
- .into(),
- ),
+ background: Some(Background::Color(disabled_container(
+ surface.on_surface,
+ ))),
scroller: Scroller {
- color: Color {
- a: DISABLED_TEXT_OPACITY,
- ..colors.on_surface
- },
+ color: disabled_text(surface.on_surface),
border: border::rounded(400),
},
..active
@@ -86,8 +79,8 @@ pub fn default(theme: &Theme, status: Status) -> Style {
let hovered_rail = Rail {
scroller: Scroller {
color: mix(
- colors.on_surface,
- colors.color,
+ surface.on_surface,
+ surface.color,
HOVERED_LAYER_OPACITY,
),
border: border::rounded(400),
@@ -122,8 +115,8 @@ pub fn default(theme: &Theme, status: Status) -> Style {
let dragged_rail = Rail {
scroller: Scroller {
color: mix(
- colors.on_surface,
- colors.color,
+ surface.on_surface,
+ surface.color,
PRESSED_LAYER_OPACITY,
),
border: border::rounded(400),
diff --git a/crates/material_theme/src/slider.rs b/crates/material_theme/src/slider.rs
index 8665459..ae9ee4b 100644
--- a/crates/material_theme/src/slider.rs
+++ b/crates/material_theme/src/slider.rs
@@ -41,9 +41,9 @@ pub fn styled(left: Color, right: Color, handle_radius: f32) -> Style {
}
pub fn default(theme: &Theme, status: Status) -> Style {
- let surface = theme.colorscheme.surface;
- let primary = theme.colorscheme.primary;
- let secondary = theme.colorscheme.secondary;
+ let surface = theme.colors().surface;
+ let primary = theme.colors().primary;
+ let secondary = theme.colors().secondary;
match status {
Status::Active => {
diff --git a/crates/material_theme/src/text.rs b/crates/material_theme/src/text.rs
index 10b2e65..8da3cdf 100644
--- a/crates/material_theme/src/text.rs
+++ b/crates/material_theme/src/text.rs
@@ -21,66 +21,66 @@ pub fn none(_: &Theme) -> Style {
pub fn primary(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.primary.on_primary),
+ color: Some(theme.colors().primary.on_primary),
}
}
pub fn primary_container(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.primary.on_primary_container),
+ color: Some(theme.colors().primary.on_primary_container),
}
}
pub fn secondary(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.secondary.on_secondary),
+ color: Some(theme.colors().secondary.on_secondary),
}
}
pub fn secondary_container(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.secondary.on_secondary_container),
+ color: Some(theme.colors().secondary.on_secondary_container),
}
}
pub fn tertiary(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.tertiary.on_tertiary),
+ color: Some(theme.colors().tertiary.on_tertiary),
}
}
pub fn tertiary_container(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.tertiary.on_tertiary_container),
+ color: Some(theme.colors().tertiary.on_tertiary_container),
}
}
pub fn error(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.error.on_error),
+ color: Some(theme.colors().error.on_error),
}
}
pub fn error_container(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.error.on_error_container),
+ color: Some(theme.colors().error.on_error_container),
}
}
pub fn surface(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.surface.on_surface),
+ color: Some(theme.colors().surface.on_surface),
}
}
pub fn surface_variant(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.surface.on_surface_variant),
+ color: Some(theme.colors().surface.on_surface_variant),
}
}
pub fn inverse_surface(theme: &Theme) -> Style {
Style {
- color: Some(theme.colorscheme.inverse.inverse_on_surface),
+ color: Some(theme.colors().inverse.inverse_on_surface),
}
}
diff --git a/crates/material_theme/src/text_editor.rs b/crates/material_theme/src/text_editor.rs
index daad7d2..14d7104 100644
--- a/crates/material_theme/src/text_editor.rs
+++ b/crates/material_theme/src/text_editor.rs
@@ -2,7 +2,7 @@ use iced_widget::core::{Background, Border, Color, border};
use iced_widget::text_editor::{Catalog, Status, Style, StyleFn};
use super::Theme;
-use crate::utils::DISABLED_TEXT_OPACITY;
+use crate::utils::{disabled_container, disabled_text};
impl Catalog for Theme {
type Class<'a> = StyleFn<'a, Self>;
@@ -17,23 +17,20 @@ impl Catalog for Theme {
}
pub fn default(theme: &Theme, status: Status) -> Style {
- let surface = theme.colorscheme.surface;
- let primary = theme.colorscheme.primary;
+ let surface = theme.colors().surface;
+ let primary = theme.colors().primary;
let active = Style {
background: Background::Color(surface.surface_container.highest),
border: Border {
- color: theme.colorscheme.outline.color,
+ color: theme.colors().outline.color,
width: 1.0,
radius: 4.into(),
},
icon: surface.on_surface_variant,
placeholder: surface.on_surface_variant,
value: surface.on_surface,
- selection: Color {
- a: DISABLED_TEXT_OPACITY,
- ..primary.color
- },
+ selection: disabled_text(primary.color),
};
match status {
@@ -57,29 +54,14 @@ pub fn default(theme: &Theme, status: Status) -> Style {
Status::Disabled => Style {
background: Color::TRANSPARENT.into(),
border: Border {
- color: Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- },
+ color: disabled_container(surface.on_surface),
width: 1.0,
radius: border::radius(4),
},
- icon: Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- },
- placeholder: Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- },
- selection: Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- },
- value: Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- },
+ icon: disabled_text(surface.on_surface),
+ placeholder: disabled_text(surface.on_surface),
+ value: disabled_text(surface.on_surface),
+ selection: disabled_text(surface.on_surface),
},
}
}
diff --git a/crates/material_theme/src/text_input.rs b/crates/material_theme/src/text_input.rs
index 5de5993..ed5e02a 100644
--- a/crates/material_theme/src/text_input.rs
+++ b/crates/material_theme/src/text_input.rs
@@ -2,7 +2,7 @@ use iced_widget::core::{Background, Border, Color};
use iced_widget::text_input::{Catalog, Status, Style, StyleFn};
use super::Theme;
-use crate::utils::{DISABLED_CONTAINER_OPACITY, DISABLED_TEXT_OPACITY};
+use crate::utils::{disabled_container, disabled_text};
impl Catalog for Theme {
type Class<'a> = StyleFn<'a, Self>;
@@ -17,23 +17,20 @@ impl Catalog for Theme {
}
pub fn default(theme: &Theme, status: Status) -> Style {
- let surface = theme.colorscheme.surface;
- let primary = theme.colorscheme.primary;
+ let surface = theme.colors().surface;
+ let primary = theme.colors().primary;
let active = Style {
background: Background::Color(surface.surface_container.highest),
border: Border {
- color: theme.colorscheme.outline.color,
+ color: theme.colors().outline.color,
width: 1.0,
radius: 4.into(),
},
icon: surface.on_surface_variant,
placeholder: surface.on_surface_variant,
value: surface.on_surface,
- selection: Color {
- a: DISABLED_TEXT_OPACITY,
- ..primary.color
- },
+ selection: disabled_text(primary.color),
};
match status {
@@ -48,28 +45,13 @@ pub fn default(theme: &Theme, status: Status) -> Style {
Status::Disabled => Style {
background: Color::TRANSPARENT.into(),
border: Border {
- color: Color {
- a: DISABLED_CONTAINER_OPACITY,
- ..surface.on_surface
- },
+ color: disabled_container(surface.on_surface),
..active.border
},
- icon: Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- },
- placeholder: Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- },
- value: Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- },
- selection: Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- },
+ icon: disabled_text(surface.on_surface),
+ placeholder: disabled_text(surface.on_surface),
+ value: disabled_text(surface.on_surface),
+ selection: disabled_text(surface.on_surface),
},
Status::Focused { .. } => Style {
border: Border {
diff --git a/crates/material_theme/src/toggler.rs b/crates/material_theme/src/toggler.rs
index 8949d07..5cebc88 100644
--- a/crates/material_theme/src/toggler.rs
+++ b/crates/material_theme/src/toggler.rs
@@ -3,8 +3,7 @@ use iced_widget::toggler::{Catalog, Status, Style, StyleFn};
use super::Theme;
use crate::utils::{
- DISABLED_CONTAINER_OPACITY, DISABLED_TEXT_OPACITY, HOVERED_LAYER_OPACITY,
- mix,
+ HOVERED_LAYER_OPACITY, disabled_container, disabled_text, mix,
};
impl Catalog for Theme {
@@ -35,8 +34,8 @@ pub fn styled(
}
pub fn default(theme: &Theme, status: Status) -> Style {
- let surface = theme.colorscheme.surface;
- let primary = theme.colorscheme.primary;
+ let surface = theme.colors().surface;
+ let primary = theme.colors().primary;
match status {
Status::Active { is_toggled } => {
@@ -45,8 +44,8 @@ pub fn default(theme: &Theme, status: Status) -> Style {
} else {
styled(
surface.surface_container.highest,
- theme.colorscheme.outline.color,
- Some(theme.colorscheme.outline.color),
+ theme.colors().outline.color,
+ Some(theme.colors().outline.color),
)
}
}
@@ -61,23 +60,14 @@ pub fn default(theme: &Theme, status: Status) -> Style {
HOVERED_LAYER_OPACITY,
),
surface.on_surface_variant,
- Some(theme.colorscheme.outline.color),
+ Some(theme.colors().outline.color),
)
}
}
Status::Disabled => styled(
- Color {
- a: DISABLED_CONTAINER_OPACITY,
- ..surface.surface_container.highest
- },
- Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- },
- Some(Color {
- a: DISABLED_TEXT_OPACITY,
- ..surface.on_surface
- }),
+ disabled_container(surface.surface_container.highest),
+ disabled_text(surface.on_surface),
+ Some(disabled_text(surface.on_surface)),
),
}
}
diff --git a/crates/material_theme/src/utils.rs b/crates/material_theme/src/utils.rs
index 5ad137e..963c9fc 100644
--- a/crates/material_theme/src/utils.rs
+++ b/crates/material_theme/src/utils.rs
@@ -30,6 +30,20 @@ pub fn shadow_from_elevation(elevation: f32, color: Color) -> Shadow {
}
}
+pub fn disabled_text(color: Color) -> Color {
+ Color {
+ a: DISABLED_TEXT_OPACITY,
+ ..color
+ }
+}
+
+pub fn disabled_container(color: Color) -> Color {
+ Color {
+ a: DISABLED_CONTAINER_OPACITY,
+ ..color
+ }
+}
+
pub fn parse_argb(s: &str) -> Option<Color> {
let hex = s.strip_prefix('#').unwrap_or(s);
@@ -88,6 +102,10 @@ pub fn color_to_argb(color: Color) -> String {
hex
}
+pub const fn lightness(color: Color) -> f32 {
+ color.r * 0.299 + color.g * 0.587 + color.b * 0.114
+}
+
pub fn mix(color1: Color, color2: Color, p2: f32) -> Color {
if p2 <= 0.0 {
return color1;