From 5d4aa21eddde93f31e52c2b44e5b72b7ca364f9a Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 20 Jan 2025 06:09:56 +0100 Subject: [PATCH] update --- src/ui/primitives/filter.rs | 214 ++++++++++++++++++++++++++++++++++++ src/ui/primitives/shadow.rs | 49 ++++++--- 2 files changed, 247 insertions(+), 16 deletions(-) diff --git a/src/ui/primitives/filter.rs b/src/ui/primitives/filter.rs index 7598bc9..3218387 100644 --- a/src/ui/primitives/filter.rs +++ b/src/ui/primitives/filter.rs @@ -263,3 +263,217 @@ impl UIWidget for HueRotateWidget { } } } + +#[allow(non_snake_case)] +pub fn Opacity(value: f64, inner: T) -> OpacityWidget { + OpacityWidget(Box::new(inner), value, false) +} + +pub struct OpacityWidget(Box, f64, bool); + +impl OpacityWidget { + pub fn backdrop(mut self) -> Self { + self.2 = true; + self + } +} + +impl Render for OpacityWidget { + fn render(&self) -> Markup { + self.render_with_class("") + } +} + +impl UIWidget for OpacityWidget { + fn can_inherit(&self) -> bool { + true + } + + fn base_class(&self) -> Vec { + let class = match self.1 { + 0.0 => "opacity-0", + 0.05 => "opacity-5", + 0.1 => "opacity-10", + 0.15 => "opacity-15", + 0.2 => "opacity-20", + 0.25 => "opacity-25", + 0.3 => "opacity-30", + 0.35 => "opacity-35", + 0.4 => "opacity-40", + 0.45 => "opacity-45", + 0.5 => "opacity-50", + 0.55 => "opacity-55", + 0.6 => "opacity-60", + 0.65 => "opacity-65", + 0.7 => "opacity-70", + 0.75 => "opacity-75", + 0.8 => "opacity-80", + 0.85 => "opacity-85", + 0.9 => "opacity-90", + 0.95 => "opacity-95", + 1.0 => "opacity-100", + _ => &format!("opacity-[{:.2}]", self.1), + }; + + if self.2 { + return vec![format!("backdrop-{class}")]; + } + + vec![class.to_string()] + } + + fn extended_class(&self) -> Vec { + let mut c = self.base_class(); + c.extend_from_slice(&self.0.extended_class()); + c + } + + fn render_with_class(&self, class: &str) -> Markup { + if self.0.as_ref().can_inherit() { + self.0 + .as_ref() + .render_with_class(&format!("{} {class}", self.base_class().join(" "))) + } else { + html! { + div class=(format!("{} {class}", self.base_class().join(" "))) { + (self.0.as_ref()) + } + } + } + } +} + +pub enum BlendMode { + Normal, + Multiply, + Screen, + Overlay, + Darken, + Lighten, + ColorDodge, + ColorBurn, + HardLight, + SoftLight, + Difference, + Exclusion, + Hue, + Saturation, + Color, + Luminosity, + PlusDarker, + PlusLighter, +} + +impl BlendMode { + pub const fn to_value(&self) -> &str { + match self { + BlendMode::Normal => "normal", + BlendMode::Multiply => "multiply", + BlendMode::Screen => "screen", + BlendMode::Overlay => "overlay", + BlendMode::Darken => "darken", + BlendMode::Lighten => "lighten", + BlendMode::ColorDodge => "color-dodge", + BlendMode::ColorBurn => "color-burn", + BlendMode::HardLight => "hard-light", + BlendMode::SoftLight => "soft-light", + BlendMode::Difference => "difference", + BlendMode::Exclusion => "exclusion", + BlendMode::Hue => "hue", + BlendMode::Saturation => "saturation", + BlendMode::Color => "color", + BlendMode::Luminosity => "luminosity", + BlendMode::PlusDarker => "plus-darker", + BlendMode::PlusLighter => "plus-lighter", + } + } +} + +#[allow(non_snake_case)] +pub fn MixBlendMode(mode: BlendMode, inner: T) -> MixBlendModeWidget { + MixBlendModeWidget(Box::new(inner), mode) +} + +pub struct MixBlendModeWidget(Box, BlendMode); + +impl Render for MixBlendModeWidget { + fn render(&self) -> Markup { + self.render_with_class("") + } +} + +impl UIWidget for MixBlendModeWidget { + fn can_inherit(&self) -> bool { + true + } + + fn base_class(&self) -> Vec { + vec![format!("mix-blend-{}", self.1.to_value())] + } + + fn extended_class(&self) -> Vec { + let mut c = self.base_class(); + c.extend_from_slice(&self.0.extended_class()); + c + } + + fn render_with_class(&self, class: &str) -> Markup { + if self.0.as_ref().can_inherit() { + self.0 + .as_ref() + .render_with_class(&format!("{} {class}", self.base_class().join(" "))) + } else { + html! { + div class=(format!("{} {class}", self.base_class().join(" "))) { + (self.0.as_ref()) + } + } + } + } +} + +#[allow(non_snake_case)] +pub fn BackgroundBlendMode( + mode: BlendMode, + inner: T, +) -> BackgroundBlendModeWidget { + BackgroundBlendModeWidget(Box::new(inner), mode) +} + +pub struct BackgroundBlendModeWidget(Box, BlendMode); + +impl Render for BackgroundBlendModeWidget { + fn render(&self) -> Markup { + self.render_with_class("") + } +} + +impl UIWidget for BackgroundBlendModeWidget { + fn can_inherit(&self) -> bool { + true + } + + fn base_class(&self) -> Vec { + vec![format!("bg-blend-{}", self.1.to_value())] + } + + fn extended_class(&self) -> Vec { + let mut c = self.base_class(); + c.extend_from_slice(&self.0.extended_class()); + c + } + + fn render_with_class(&self, class: &str) -> Markup { + if self.0.as_ref().can_inherit() { + self.0 + .as_ref() + .render_with_class(&format!("{} {class}", self.base_class().join(" "))) + } else { + html! { + div class=(format!("{} {class}", self.base_class().join(" "))) { + (self.0.as_ref()) + } + } + } + } +} diff --git a/src/ui/primitives/shadow.rs b/src/ui/primitives/shadow.rs index 92f2323..5e3cc64 100644 --- a/src/ui/primitives/shadow.rs +++ b/src/ui/primitives/shadow.rs @@ -1,35 +1,46 @@ -use crate::ui::UIWidget; +use crate::ui::{UIWidget, color::UIColor}; use maud::{Markup, Render, html}; -pub struct Shadow(Box, String); +pub struct Shadow(Box, String, Option>); impl Shadow { - pub fn medium(inner: T) -> Self { - Self(Box::new(inner), "md".to_owned()) - } - pub fn small(inner: T) -> Self { - Self(Box::new(inner), "sm".to_owned()) + Self(Box::new(inner), "sm".to_owned(), None) } pub fn regular(inner: T) -> Self { - Self(Box::new(inner), String::new()) + Self(Box::new(inner), String::new(), None) + } + + pub fn medium(inner: T) -> Self { + Self(Box::new(inner), "md".to_owned(), None) } pub fn large(inner: T) -> Self { - Self(Box::new(inner), "lg".to_owned()) - } - - pub fn none(inner: T) -> Self { - Self(Box::new(inner), "none".to_owned()) + Self(Box::new(inner), "lg".to_owned(), None) } pub fn xl(inner: T) -> Self { - Self(Box::new(inner), "xl".to_owned()) + Self(Box::new(inner), "xl".to_owned(), None) } pub fn _2xl(inner: T) -> Self { - Self(Box::new(inner), "2xl".to_owned()) + Self(Box::new(inner), "2xl".to_owned(), None) + } + + pub fn inner(inner: T) -> Self { + Self(Box::new(inner), "inner".to_owned(), None) + } + + pub fn none(inner: T) -> Self { + Self(Box::new(inner), "none".to_owned(), None) + } +} + +impl Shadow { + pub fn color(mut self, color: C) -> Self { + self.2 = Some(Box::new(color)); + self } } @@ -45,11 +56,17 @@ impl UIWidget for Shadow { } fn base_class(&self) -> Vec { - if self.1.is_empty() { + let mut ret = if self.1.is_empty() { vec!["shadow".to_string()] } else { vec![format!("shadow-{}", self.1)] + }; + + if let Some(color) = &self.2 { + ret.push(format!("shadow-{}", color.color_class())); } + + ret } fn extended_class(&self) -> Vec {