From 495985f449e46b24e6b734d3aa9e135a779a8b77 Mon Sep 17 00:00:00 2001 From: pml68 Date: Sun, 13 Apr 2025 03:40:38 +0200 Subject: refactor: move `material_theme` and `iced_drop` into separate crates dir --- material_theme/Cargo.toml | 53 ------- material_theme/README.md | 3 - material_theme/assets/themes/dark.toml | 49 ------- material_theme/assets/themes/light.toml | 49 ------- material_theme/src/button.rs | 193 ------------------------- material_theme/src/container.rs | 173 ---------------------- material_theme/src/dialog.rs | 25 ---- material_theme/src/lib.rs | 248 -------------------------------- material_theme/src/menu.rs | 33 ----- material_theme/src/pick_list.rs | 40 ------ material_theme/src/scrollable.rs | 161 --------------------- material_theme/src/text.rs | 86 ----------- material_theme/src/utils.rs | 116 --------------- 13 files changed, 1229 deletions(-) delete mode 100644 material_theme/Cargo.toml delete mode 100644 material_theme/README.md delete mode 100644 material_theme/assets/themes/dark.toml delete mode 100644 material_theme/assets/themes/light.toml delete mode 100644 material_theme/src/button.rs delete mode 100644 material_theme/src/container.rs delete mode 100644 material_theme/src/dialog.rs delete mode 100644 material_theme/src/lib.rs delete mode 100644 material_theme/src/menu.rs delete mode 100644 material_theme/src/pick_list.rs delete mode 100644 material_theme/src/scrollable.rs delete mode 100644 material_theme/src/text.rs delete mode 100644 material_theme/src/utils.rs (limited to 'material_theme') diff --git a/material_theme/Cargo.toml b/material_theme/Cargo.toml deleted file mode 100644 index eef9605..0000000 --- a/material_theme/Cargo.toml +++ /dev/null @@ -1,53 +0,0 @@ -[package] -name = "material_theme" -description = "An M3 inspired theme for `iced`" -authors = ["pml68 "] -version = "0.14.0-dev" -edition = "2024" -license = "MIT" -# readme = "README.md" -repository = "https://github.com/pml68/iced_builder" -categories = ["gui"] -keywords = ["gui", "ui", "graphics", "interface", "widgets"] -rust-version = "1.85" - -[features] -default = [] -animate = ["dep:iced_anim"] -dialog = ["dep:iced_dialog"] - -[dependencies] -iced_widget = "0.14.0-dev" -serde.workspace = true -toml.workspace = true -dark-light = "2.0.0" -iced_dialog.workspace = true -iced_dialog.optional = true - -[dependencies.iced_anim] -workspace = true -features = ["derive"] -optional = true - -[lints.rust] -missing_debug_implementations = "deny" -unsafe_code = "deny" -unused_results = "deny" - -[lints.clippy] -type-complexity = "allow" -semicolon_if_nothing_returned = "deny" -trivially-copy-pass-by-ref = "deny" -default_trait_access = "deny" -match-wildcard-for-single-variants = "deny" -redundant-closure-for-method-calls = "deny" -filter_map_next = "deny" -manual_let_else = "deny" -unused_async = "deny" -from_over_into = "deny" -needless_borrow = "deny" -new_without_default = "deny" -useless_conversion = "deny" - -[lints.rustdoc] -broken_intra_doc_links = "forbid" diff --git a/material_theme/README.md b/material_theme/README.md deleted file mode 100644 index da5a1ec..0000000 --- a/material_theme/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# material_theme - -## A [Material3](https://m3.material.io) inspired custom theme for [`iced`](https://iced.rs) diff --git a/material_theme/assets/themes/dark.toml b/material_theme/assets/themes/dark.toml deleted file mode 100644 index 18a369f..0000000 --- a/material_theme/assets/themes/dark.toml +++ /dev/null @@ -1,49 +0,0 @@ -name = "Dark" - -shadow = "#000000" -scrim = "#4d000000" - -[primary] -color = "#9bd4a1" -on_primary = "#003916" -primary_container = "#1b5129" -on_primary_container = "#b6f1bb" - -[secondary] -color = "#b8ccb6" -on_secondary = "#233425" -secondary_container = "#394b3a" -on_secondary_container = "#d3e8d1" - -[tertiary] -color = "#a1ced7" -on_tertiary = "#00363e" -tertiary_container = "#1f4d55" -on_tertiary_container = "#bdeaf4" - -[error] -color = "#ffb4ab" -on_error = "#690005" -error_container = "#93000a" -on_error_container = "#ffdad6" - -[surface] -color = "#101510" -on_surface = "#e0e4dc" -on_surface_variant = "#c1c9be" - -[surface.surface_container] -lowest = "#0b0f0b" -low = "#181d18" -base = "#1c211c" -high = "#262b26" -highest = "#313631" - -[inverse] -inverse_surface = "#e0e4dc" -inverse_on_surface = "#2d322c" -inverse_primary = "#34693f" - -[outline] -color = "#8b9389" -variant = "#414941" diff --git a/material_theme/assets/themes/light.toml b/material_theme/assets/themes/light.toml deleted file mode 100644 index a7115c4..0000000 --- a/material_theme/assets/themes/light.toml +++ /dev/null @@ -1,49 +0,0 @@ -name = "Light" - -shadow = "#000000" -scrim = "#4d000000" - -[primary] -color = "#34693f" -on_primary = "#ffffff" -primary_container = "#b6f1bb" -on_primary_container = "#1b5129" - -[secondary] -color = "#516351" -on_secondary = "#ffffff" -secondary_container = "#d3e8d1" -on_secondary_container = "#394b3a" - -[tertiary] -color = "#39656d" -on_tertiary = "#ffffff" -tertiary_container = "#bdeaf4" -on_tertiary_container = "#1f4d55" - -[error] -color = "#ba1a1a" -on_error = "#ffffff" -error_container = "#ffdad6" -on_error_container = "#93000a" - -[surface] -color = "#f7fbf2" -on_surface = "#181d18" -on_surface_variant = "#414941" - -[surface.surface_container] -lowest = "#ffffff" -low = "#f1f5ed" -base = "#ebefe7" -high = "#e5e9e1" -highest = "#e0e4dc" - -[inverse] -inverse_surface = "#2d322c" -inverse_on_surface = "#eef2ea" -inverse_primary = "#9bd4a1" - -[outline] -color = "#727970" -variant = "#c1c9be" diff --git a/material_theme/src/button.rs b/material_theme/src/button.rs deleted file mode 100644 index 21d77b7..0000000 --- a/material_theme/src/button.rs +++ /dev/null @@ -1,193 +0,0 @@ -use iced_widget::button::{Catalog, Status, Style, StyleFn}; -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, -}; - -impl Catalog for Theme { - type Class<'a> = StyleFn<'a, Self>; - - fn default<'a>() -> Self::Class<'a> { - Box::new(filled) - } - - fn style(&self, class: &Self::Class<'_>, status: Status) -> Style { - class(self, status) - } -} - -fn button( - foreground: Color, - background: Color, - tone_overlay: Color, - disabled: Color, - shadow_color: Color, - elevation_level: u8, - status: Status, -) -> Style { - let active = Style { - background: Some(Background::Color(background)), - text_color: foreground, - border: border::rounded(400), - shadow: shadow_from_elevation(elevation(elevation_level), shadow_color), - }; - - match status { - Status::Active => active, - Status::Pressed => Style { - background: Some(Background::Color(mix( - background, - tone_overlay, - HOVERED_LAYER_OPACITY, - ))), - ..active - }, - Status::Hovered => Style { - background: Some(Background::Color(mix( - background, - tone_overlay, - PRESSED_LAYER_OPACITY, - ))), - text_color: foreground, - border: border::rounded(400), - shadow: shadow_from_elevation( - elevation(elevation_level + 1), - shadow_color, - ), - }, - Status::Disabled => Style { - background: Some(Background::Color(Color { - a: DISABLED_CONTAINER_OPACITY, - ..disabled - })), - text_color: Color { - a: DISABLED_TEXT_OPACITY, - ..disabled - }, - border: border::rounded(400), - ..Default::default() - }, - } -} - -pub fn elevated(theme: &Theme, status: Status) -> Style { - let surface_colors = theme.colorscheme.surface; - - let foreground = theme.colorscheme.primary.color; - let background = surface_colors.surface_container.low; - let disabled = surface_colors.on_surface; - - let shadow_color = theme.colorscheme.shadow; - - button( - foreground, - background, - foreground, - disabled, - shadow_color, - 1, - status, - ) -} - -pub fn filled(theme: &Theme, status: Status) -> Style { - let primary_colors = theme.colorscheme.primary; - - let foreground = primary_colors.on_primary; - let background = primary_colors.color; - let disabled = theme.colorscheme.surface.on_surface; - - let shadow_color = theme.colorscheme.shadow; - - button( - foreground, - background, - foreground, - disabled, - shadow_color, - 0, - status, - ) -} - -pub fn filled_tonal(theme: &Theme, status: Status) -> Style { - let secondary_colors = theme.colorscheme.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; - - button( - foreground, - background, - foreground, - disabled, - shadow_color, - 0, - status, - ) -} - -pub fn outlined(theme: &Theme, status: Status) -> Style { - let foreground = theme.colorscheme.primary.color; - let background = Color::TRANSPARENT; - let disabled = theme.colorscheme.surface.on_surface; - - let outline = theme.colorscheme.outline.color; - - let border = match status { - Status::Active | Status::Pressed | Status::Hovered => Border { - color: outline, - width: 1.0, - radius: 400.0.into(), - }, - Status::Disabled => Border { - color: Color { - a: DISABLED_CONTAINER_OPACITY, - ..disabled - }, - width: 1.0, - radius: 400.0.into(), - }, - }; - - let style = button( - foreground, - background, - foreground, - disabled, - Color::TRANSPARENT, - 0, - status, - ); - - Style { border, ..style } -} - -pub fn text(theme: &Theme, status: Status) -> Style { - let foreground = theme.colorscheme.primary.color; - let background = Color::TRANSPARENT; - let disabled = theme.colorscheme.surface.on_surface; - - let style = button( - foreground, - background, - foreground, - disabled, - Color::TRANSPARENT, - 0, - status, - ); - - match status { - Status::Hovered | Status::Pressed => style, - _ => Style { - background: None, - ..style - }, - } -} diff --git a/material_theme/src/container.rs b/material_theme/src/container.rs deleted file mode 100644 index a14cfd5..0000000 --- a/material_theme/src/container.rs +++ /dev/null @@ -1,173 +0,0 @@ -use iced_widget::container::{Catalog, Style, StyleFn}; -use iced_widget::core::{Background, border}; - -use super::Theme; - -impl Catalog for Theme { - type Class<'a> = StyleFn<'a, Self>; - - fn default<'a>() -> Self::Class<'a> { - Box::new(transparent) - } - - fn style(&self, class: &Self::Class<'_>) -> Style { - class(self) - } -} - -pub fn transparent(_theme: &Theme) -> Style { - Style { - border: border::rounded(4), - ..Style::default() - } -} - -pub fn primary(theme: &Theme) -> Style { - let colors = theme.colorscheme.primary; - Style { - background: Some(Background::Color(colors.color)), - text_color: Some(colors.on_primary), - border: border::rounded(4), - ..Style::default() - } -} - -pub fn primary_container(theme: &Theme) -> Style { - let colors = theme.colorscheme.primary; - Style { - background: Some(Background::Color(colors.primary_container)), - text_color: Some(colors.on_primary_container), - border: border::rounded(8), - ..Style::default() - } -} - -pub fn secondary(theme: &Theme) -> Style { - let colors = theme.colorscheme.secondary; - Style { - background: Some(Background::Color(colors.color)), - text_color: Some(colors.on_secondary), - border: border::rounded(4), - ..Style::default() - } -} - -pub fn secondary_container(theme: &Theme) -> Style { - let colors = theme.colorscheme.secondary; - Style { - background: Some(Background::Color(colors.secondary_container)), - text_color: Some(colors.on_secondary_container), - border: border::rounded(8), - ..Style::default() - } -} - -pub fn tertiary(theme: &Theme) -> Style { - let colors = theme.colorscheme.tertiary; - Style { - background: Some(Background::Color(colors.color)), - text_color: Some(colors.on_tertiary), - border: border::rounded(4), - ..Style::default() - } -} - -pub fn tertiary_container(theme: &Theme) -> Style { - let colors = theme.colorscheme.tertiary; - Style { - background: Some(Background::Color(colors.tertiary_container)), - text_color: Some(colors.on_tertiary_container), - border: border::rounded(8), - ..Style::default() - } -} - -pub fn error(theme: &Theme) -> Style { - let colors = theme.colorscheme.error; - Style { - background: Some(Background::Color(colors.color)), - text_color: Some(colors.on_error), - border: border::rounded(4), - ..Style::default() - } -} - -pub fn error_container(theme: &Theme) -> Style { - let colors = theme.colorscheme.error; - Style { - background: Some(Background::Color(colors.error_container)), - text_color: Some(colors.on_error_container), - border: border::rounded(8), - ..Style::default() - } -} - -pub fn surface(theme: &Theme) -> Style { - let colors = theme.colorscheme.surface; - Style { - background: Some(Background::Color(colors.color)), - text_color: Some(colors.on_surface), - border: border::rounded(4), - ..Style::default() - } -} - -pub fn surface_container_lowest(theme: &Theme) -> Style { - let colors = theme.colorscheme.surface; - Style { - background: Some(Background::Color(colors.surface_container.lowest)), - text_color: Some(colors.on_surface), - border: border::rounded(8), - ..Style::default() - } -} - -pub fn surface_container_low(theme: &Theme) -> Style { - let colors = theme.colorscheme.surface; - Style { - background: Some(Background::Color(colors.surface_container.low)), - text_color: Some(colors.on_surface), - border: border::rounded(8), - ..Style::default() - } -} - -pub fn surface_container(theme: &Theme) -> Style { - let colors = theme.colorscheme.surface; - Style { - background: Some(Background::Color(colors.surface_container.base)), - text_color: Some(colors.on_surface), - border: border::rounded(8), - ..Style::default() - } -} - -pub fn surface_container_high(theme: &Theme) -> Style { - let colors = theme.colorscheme.surface; - Style { - background: Some(Background::Color(colors.surface_container.high)), - text_color: Some(colors.on_surface), - border: border::rounded(8), - ..Style::default() - } -} - -pub fn surface_container_highest(theme: &Theme) -> Style { - let colors = theme.colorscheme.surface; - Style { - background: Some(Background::Color(colors.surface_container.highest)), - text_color: Some(colors.on_surface), - border: border::rounded(8), - ..Style::default() - } -} - -pub fn inverse_surface(theme: &Theme) -> Style { - let colors = theme.colorscheme.inverse; - Style { - background: Some(Background::Color(colors.inverse_surface)), - text_color: Some(colors.inverse_on_surface), - border: border::rounded(4), - ..Style::default() - } -} diff --git a/material_theme/src/dialog.rs b/material_theme/src/dialog.rs deleted file mode 100644 index 68c61b5..0000000 --- a/material_theme/src/dialog.rs +++ /dev/null @@ -1,25 +0,0 @@ -use iced_widget::container::Style; -use iced_widget::core::{Background, border}; - -use super::{Theme, text}; - -impl iced_dialog::dialog::Catalog for Theme { - fn default_container<'a>() - -> ::Class<'a> { - Box::new(default_container) - } - - fn default_title<'a>() -> ::Class<'a> { - Box::new(text::surface) - } -} - -pub fn default_container(theme: &Theme) -> Style { - let colors = theme.colorscheme.surface; - Style { - background: Some(Background::Color(colors.surface_container.high)), - text_color: Some(colors.on_surface_variant), - border: border::rounded(28), - ..Style::default() - } -} diff --git a/material_theme/src/lib.rs b/material_theme/src/lib.rs deleted file mode 100644 index 521af2c..0000000 --- a/material_theme/src/lib.rs +++ /dev/null @@ -1,248 +0,0 @@ -use std::sync::LazyLock; - -use iced_widget::core::Color; -use iced_widget::core::theme::{Base, Style}; -use serde::Deserialize; - -pub mod button; -pub mod container; -#[cfg(feature = "dialog")] -pub mod dialog; -pub mod menu; -pub mod pick_list; -pub mod scrollable; -pub mod text; -pub mod utils; - -const DARK_THEME_CONTENT: &str = include_str!("../assets/themes/dark.toml"); -const LIGHT_THEME_CONTENT: &str = include_str!("../assets/themes/light.toml"); - -#[derive(Debug, PartialEq, Deserialize)] -pub struct Theme { - pub name: String, - #[serde(flatten)] - pub colorscheme: ColorScheme, -} - -impl Theme { - pub fn new(name: impl Into, colorscheme: ColorScheme) -> Self { - Self { - name: name.into(), - colorscheme, - } - } -} - -impl Clone for Theme { - fn clone(&self) -> Self { - Self { - name: self.name.clone(), - colorscheme: self.colorscheme, - } - } - - fn clone_from(&mut self, source: &Self) { - self.name = source.name.clone(); - self.colorscheme = source.colorscheme; - } -} - -impl Default for Theme { - fn default() -> Self { - static DEFAULT: LazyLock = LazyLock::new(|| { - match dark_light::detect().unwrap_or(dark_light::Mode::Unspecified) - { - dark_light::Mode::Dark | dark_light::Mode::Unspecified => { - DARK.clone() - } - dark_light::Mode::Light => LIGHT.clone(), - } - }); - - DEFAULT.clone() - } -} - -impl std::fmt::Display for Theme { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - 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, - } - } - - fn palette(&self) -> Option { - // TODO: create a Palette - None - } -} - -#[cfg(feature = "animate")] -impl iced_anim::Animate for Theme { - fn components() -> usize { - ColorScheme::components() - } - - fn update(&mut self, components: &mut impl Iterator) { - let mut colors = self.colorscheme; - colors.update(components); - - *self = Theme::new("Animating Theme", colors); - } - - fn distance_to(&self, end: &Self) -> Vec { - self.colorscheme.distance_to(&end.colorscheme) - } - - fn lerp(&mut self, start: &Self, end: &Self, progress: f32) { - let mut colors = self.colorscheme; - colors.lerp(&start.colorscheme, &end.colorscheme, progress); - - *self = Theme::new("Animating Theme", colors); - } -} - -pub static DARK: LazyLock = LazyLock::new(|| { - toml::from_str(DARK_THEME_CONTENT).expect("parse dark theme") -}); - -pub static LIGHT: LazyLock = LazyLock::new(|| { - toml::from_str(LIGHT_THEME_CONTENT).expect("parse light theme") -}); - -#[derive(Debug, Clone, Copy, PartialEq, Deserialize)] -#[cfg_attr(feature = "animate", derive(iced_anim::Animate))] -pub struct ColorScheme { - pub primary: Primary, - pub secondary: Secondary, - pub tertiary: Tertiary, - pub error: Error, - pub surface: Surface, - pub inverse: Inverse, - pub outline: Outline, - #[serde(with = "color_serde")] - pub shadow: Color, - #[serde(with = "color_serde")] - pub scrim: Color, -} - -#[derive(Debug, Clone, Copy, PartialEq, Deserialize)] -#[cfg_attr(feature = "animate", derive(iced_anim::Animate))] -pub struct Primary { - #[serde(with = "color_serde")] - pub color: Color, - #[serde(with = "color_serde")] - pub on_primary: Color, - #[serde(with = "color_serde")] - pub primary_container: Color, - #[serde(with = "color_serde")] - pub on_primary_container: Color, -} - -#[derive(Debug, Clone, Copy, PartialEq, Deserialize)] -#[cfg_attr(feature = "animate", derive(iced_anim::Animate))] -pub struct Secondary { - #[serde(with = "color_serde")] - pub color: Color, - #[serde(with = "color_serde")] - pub on_secondary: Color, - #[serde(with = "color_serde")] - pub secondary_container: Color, - #[serde(with = "color_serde")] - pub on_secondary_container: Color, -} - -#[derive(Debug, Clone, Copy, PartialEq, Deserialize)] -#[cfg_attr(feature = "animate", derive(iced_anim::Animate))] -pub struct Tertiary { - #[serde(with = "color_serde")] - pub color: Color, - #[serde(with = "color_serde")] - pub on_tertiary: Color, - #[serde(with = "color_serde")] - pub tertiary_container: Color, - #[serde(with = "color_serde")] - pub on_tertiary_container: Color, -} - -#[derive(Debug, Clone, Copy, PartialEq, Deserialize)] -#[cfg_attr(feature = "animate", derive(iced_anim::Animate))] -pub struct Error { - #[serde(with = "color_serde")] - pub color: Color, - #[serde(with = "color_serde")] - pub on_error: Color, - #[serde(with = "color_serde")] - pub error_container: Color, - #[serde(with = "color_serde")] - pub on_error_container: Color, -} - -#[derive(Debug, Clone, Copy, PartialEq, Deserialize)] -#[cfg_attr(feature = "animate", derive(iced_anim::Animate))] -pub struct Surface { - #[serde(with = "color_serde")] - pub color: Color, - #[serde(with = "color_serde")] - pub on_surface: Color, - #[serde(with = "color_serde")] - pub on_surface_variant: Color, - pub surface_container: SurfaceContainer, -} - -#[derive(Debug, Clone, Copy, PartialEq, Deserialize)] -#[cfg_attr(feature = "animate", derive(iced_anim::Animate))] -pub struct SurfaceContainer { - #[serde(with = "color_serde")] - pub lowest: Color, - #[serde(with = "color_serde")] - pub low: Color, - #[serde(with = "color_serde")] - pub base: Color, - #[serde(with = "color_serde")] - pub high: Color, - #[serde(with = "color_serde")] - pub highest: Color, -} - -#[derive(Debug, Clone, Copy, PartialEq, Deserialize)] -#[cfg_attr(feature = "animate", derive(iced_anim::Animate))] -pub struct Inverse { - #[serde(with = "color_serde")] - pub inverse_surface: Color, - #[serde(with = "color_serde")] - pub inverse_on_surface: Color, - #[serde(with = "color_serde")] - pub inverse_primary: Color, -} - -#[derive(Debug, Clone, Copy, PartialEq, Deserialize)] -#[cfg_attr(feature = "animate", derive(iced_anim::Animate))] -pub struct Outline { - #[serde(with = "color_serde")] - pub color: Color, - #[serde(with = "color_serde")] - pub variant: Color, -} - -mod color_serde { - use iced_widget::core::Color; - use serde::{Deserialize, Deserializer}; - - use super::utils::parse_argb; - - pub fn deserialize<'de, D>(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - Ok(String::deserialize(deserializer) - .map(|hex| parse_argb(&hex))? - .unwrap_or(Color::TRANSPARENT)) - } -} diff --git a/material_theme/src/menu.rs b/material_theme/src/menu.rs deleted file mode 100644 index 9f43c72..0000000 --- a/material_theme/src/menu.rs +++ /dev/null @@ -1,33 +0,0 @@ -use iced_widget::core::{Background, border}; -use iced_widget::overlay::menu::{Catalog, Style, StyleFn}; - -use super::Theme; -use crate::utils::{HOVERED_LAYER_OPACITY, mix}; - -impl Catalog for Theme { - type Class<'a> = StyleFn<'a, Self>; - - fn default<'a>() -> ::Class<'a> { - Box::new(default) - } - - fn style(&self, class: &::Class<'_>) -> Style { - class(self) - } -} - -pub fn default(theme: &Theme) -> Style { - let colors = theme.colorscheme.surface; - - Style { - border: border::rounded(4), - background: Background::Color(colors.surface_container.base), - text_color: colors.on_surface, - selected_background: Background::Color(mix( - colors.surface_container.base, - colors.on_surface, - HOVERED_LAYER_OPACITY, - )), - selected_text_color: colors.on_surface, - } -} diff --git a/material_theme/src/pick_list.rs b/material_theme/src/pick_list.rs deleted file mode 100644 index c589100..0000000 --- a/material_theme/src/pick_list.rs +++ /dev/null @@ -1,40 +0,0 @@ -use iced_widget::core::{Background, border}; -use iced_widget::pick_list::{Catalog, Status, Style, StyleFn}; - -use super::Theme; - -impl Catalog for Theme { - type Class<'a> = StyleFn<'a, Self>; - - fn default<'a>() -> ::Class<'a> { - Box::new(default) - } - - fn style( - &self, - class: &::Class<'_>, - status: Status, - ) -> Style { - class(self, status) - } -} - -pub fn default(theme: &Theme, status: Status) -> Style { - let surface = theme.colorscheme.surface; - - let active = Style { - text_color: surface.on_surface, - placeholder_color: surface.on_surface_variant, - handle_color: surface.on_surface_variant, - background: Background::Color(surface.surface_container.highest), - border: border::rounded(4), - }; - - match status { - Status::Active => active, - Status::Hovered | Status::Opened { .. } => Style { - background: Background::Color(surface.surface_container.highest), - ..active - }, - } -} diff --git a/material_theme/src/scrollable.rs b/material_theme/src/scrollable.rs deleted file mode 100644 index 8a22e56..0000000 --- a/material_theme/src/scrollable.rs +++ /dev/null @@ -1,161 +0,0 @@ -use iced_widget::core::{Border, Color, border}; -use iced_widget::scrollable::{ - Catalog, Rail, Scroller, Status, Style, StyleFn, -}; - -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, -}; - -impl Catalog for Theme { - type Class<'a> = StyleFn<'a, Self>; - - fn default<'a>() -> Self::Class<'a> { - Box::new(default) - } - - fn style(&self, class: &Self::Class<'_>, status: Status) -> Style { - class(self, status) - } -} - -pub fn default(theme: &Theme, status: Status) -> Style { - let colors = theme.colorscheme.surface; - - let active = Rail { - background: None, - scroller: Scroller { - color: colors.on_surface, - border: border::rounded(400), - }, - border: Border::default(), - }; - - let disabled = Rail { - background: Some( - Color { - a: DISABLED_CONTAINER_OPACITY, - ..colors.on_surface - } - .into(), - ), - scroller: Scroller { - color: Color { - a: DISABLED_TEXT_OPACITY, - ..colors.on_surface - }, - border: border::rounded(400), - }, - ..active - }; - - let style = Style { - container: surface_container(theme), - vertical_rail: active, - horizontal_rail: active, - gap: None, - }; - - match status { - Status::Active { - is_horizontal_scrollbar_disabled, - is_vertical_scrollbar_disabled, - } => Style { - horizontal_rail: if is_horizontal_scrollbar_disabled { - disabled - } else { - active - }, - vertical_rail: if is_vertical_scrollbar_disabled { - disabled - } else { - active - }, - ..style - }, - Status::Hovered { - is_horizontal_scrollbar_hovered, - is_vertical_scrollbar_hovered, - is_horizontal_scrollbar_disabled, - is_vertical_scrollbar_disabled, - } => { - let hovered_rail = Rail { - scroller: Scroller { - color: mix( - colors.on_surface, - colors.color, - HOVERED_LAYER_OPACITY, - ), - border: border::rounded(400), - }, - ..active - }; - - Style { - horizontal_rail: if is_horizontal_scrollbar_disabled { - disabled - } else { - if is_horizontal_scrollbar_hovered { - hovered_rail - } else { - active - } - }, - vertical_rail: if is_vertical_scrollbar_disabled { - disabled - } else { - if is_vertical_scrollbar_hovered { - hovered_rail - } else { - active - } - }, - ..style - } - } - Status::Dragged { - is_horizontal_scrollbar_dragged, - is_vertical_scrollbar_dragged, - is_horizontal_scrollbar_disabled, - is_vertical_scrollbar_disabled, - } => { - let dragged_rail = Rail { - scroller: Scroller { - color: mix( - colors.on_surface, - colors.color, - PRESSED_LAYER_OPACITY, - ), - border: border::rounded(400), - }, - ..active - }; - - Style { - horizontal_rail: if is_horizontal_scrollbar_disabled { - disabled - } else { - if is_horizontal_scrollbar_dragged { - dragged_rail - } else { - active - } - }, - vertical_rail: if is_vertical_scrollbar_disabled { - disabled - } else { - if is_vertical_scrollbar_dragged { - dragged_rail - } else { - active - } - }, - ..style - } - } - } -} diff --git a/material_theme/src/text.rs b/material_theme/src/text.rs deleted file mode 100644 index 10b2e65..0000000 --- a/material_theme/src/text.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![allow(dead_code)] -use iced_widget::text::{Catalog, Style, StyleFn}; - -use crate::Theme; - -impl Catalog for Theme { - type Class<'a> = StyleFn<'a, Self>; - - fn default<'a>() -> Self::Class<'a> { - Box::new(none) - } - - fn style(&self, class: &Self::Class<'_>) -> Style { - class(self) - } -} - -pub fn none(_: &Theme) -> Style { - Style { color: None } -} - -pub fn primary(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.primary.on_primary), - } -} - -pub fn primary_container(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.primary.on_primary_container), - } -} - -pub fn secondary(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.secondary.on_secondary), - } -} - -pub fn secondary_container(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.secondary.on_secondary_container), - } -} - -pub fn tertiary(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.tertiary.on_tertiary), - } -} - -pub fn tertiary_container(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.tertiary.on_tertiary_container), - } -} - -pub fn error(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.error.on_error), - } -} - -pub fn error_container(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.error.on_error_container), - } -} - -pub fn surface(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.surface.on_surface), - } -} - -pub fn surface_variant(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.surface.on_surface_variant), - } -} - -pub fn inverse_surface(theme: &Theme) -> Style { - Style { - color: Some(theme.colorscheme.inverse.inverse_on_surface), - } -} diff --git a/material_theme/src/utils.rs b/material_theme/src/utils.rs deleted file mode 100644 index a05bc62..0000000 --- a/material_theme/src/utils.rs +++ /dev/null @@ -1,116 +0,0 @@ -use iced_widget::core::{Color, Shadow, Vector}; - -pub const HOVERED_LAYER_OPACITY: f32 = 0.08; -pub const PRESSED_LAYER_OPACITY: f32 = 0.1; - -pub const DISABLED_TEXT_OPACITY: f32 = 0.38; -pub const DISABLED_CONTAINER_OPACITY: f32 = 0.12; - -pub fn elevation(elevation_level: u8) -> f32 { - (match elevation_level { - 0 => 0.0, - 1 => 1.0, - 2 => 3.0, - 3 => 6.0, - 4 => 8.0, - _ => 12.0, - } as f32) -} - -pub fn shadow_from_elevation(elevation: f32, color: Color) -> Shadow { - Shadow { - color, - offset: Vector { - x: 0.0, - y: elevation, - }, - blur_radius: (elevation) * (1.0 + 0.4_f32.powf(elevation)), - } -} - -pub fn parse_argb(s: &str) -> Option { - let hex = s.strip_prefix('#').unwrap_or(s); - - let parse_channel = |from: usize, to: usize| { - let num = - usize::from_str_radix(&hex[from..=to], 16).ok()? as f32 / 255.0; - - // If we only got half a byte (one letter), expand it into a full byte (two letters) - Some(if from == to { num + num * 16.0 } else { num }) - }; - - Some(match hex.len() { - 3 => Color::from_rgb( - parse_channel(0, 0)?, - parse_channel(1, 1)?, - parse_channel(2, 2)?, - ), - 4 => Color::from_rgba( - parse_channel(1, 1)?, - parse_channel(2, 2)?, - parse_channel(3, 3)?, - parse_channel(0, 0)?, - ), - 6 => Color::from_rgb( - parse_channel(0, 1)?, - parse_channel(2, 3)?, - parse_channel(4, 5)?, - ), - 8 => Color::from_rgba( - parse_channel(2, 3)?, - parse_channel(4, 5)?, - parse_channel(6, 7)?, - parse_channel(0, 1)?, - ), - _ => None?, - }) -} - -pub fn mix(color1: Color, color2: Color, p2: f32) -> Color { - if p2 <= 0.0 { - return color1; - } else if p2 >= 1.0 { - return color2; - } - - let p1 = 1.0 - p2; - - if color1.a != 1.0 || color2.a != 1.0 { - let a = color1.a * p1 + color2.a * p2; - if a > 0.0 { - let c1 = color1.into_linear().map(|c| c * color1.a * p1); - let c2 = color2.into_linear().map(|c| c * color2.a * p2); - - let [r, g, b] = - [c1[0] + c2[0], c1[1] + c2[1], c1[2] + c2[2]].map(|u| u / a); - - return Color::from_linear_rgba(r, g, b, a); - } - } - - let c1 = color1.into_linear().map(|c| c * p1); - let c2 = color2.into_linear().map(|c| c * p2); - - Color::from_linear_rgba( - c1[0] + c2[0], - c1[1] + c2[1], - c1[2] + c2[2], - c1[3] + c2[3], - ) -} - -#[cfg(test)] -mod tests { - use super::{Color, mix}; - - #[test] - fn mixing_works() { - let base = Color::from_rgba(1.0, 0.0, 0.0, 0.7); - let overlay = Color::from_rgba(0.0, 1.0, 0.0, 0.2); - - assert_eq!( - mix(base, overlay, 0.75).into_rgba8(), - Color::from_linear_rgba(0.53846, 0.46154, 0.0, 0.325).into_rgba8() - ); - } -} -- cgit v1.2.3