add filters
This commit is contained in:
parent
ec10e5a89d
commit
f7db3333c5
5 changed files with 274 additions and 1 deletions
|
@ -1,3 +1,5 @@
|
|||
#![feature(const_vec_string_slice)]
|
||||
|
||||
use tokio::sync::OnceCell;
|
||||
|
||||
pub mod auth;
|
||||
|
|
|
@ -26,6 +26,9 @@ pub mod prelude {
|
|||
pub use super::primitives::container::Container;
|
||||
pub use super::primitives::cursor::Cursor;
|
||||
pub use super::primitives::div::Div;
|
||||
pub use super::primitives::filter::{
|
||||
Blur, Brightness, Contrast, Grayscale, HueRotate, Invert, Saturate, Sepia,
|
||||
};
|
||||
pub use super::primitives::flex::{
|
||||
Direction, Flex, FlexBasis, FlexGrow, Justify, Order, Strategy, Wrap,
|
||||
};
|
||||
|
|
265
src/ui/primitives/filter.rs
Normal file
265
src/ui/primitives/filter.rs
Normal file
|
@ -0,0 +1,265 @@
|
|||
use crate::ui::UIWidget;
|
||||
use maud::{Markup, Render, html};
|
||||
|
||||
use super::Size;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Blur<T: UIWidget + 'static>(amount: Size, inner: T) -> BlurWidget {
|
||||
BlurWidget(Box::new(inner), amount, false)
|
||||
}
|
||||
|
||||
pub struct BlurWidget(Box<dyn UIWidget>, Size, bool);
|
||||
|
||||
impl BlurWidget {
|
||||
pub fn backdrop(mut self) -> Self {
|
||||
self.2 = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for BlurWidget {
|
||||
fn render(&self) -> Markup {
|
||||
self.render_with_class("")
|
||||
}
|
||||
}
|
||||
|
||||
impl UIWidget for BlurWidget {
|
||||
fn can_inherit(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn base_class(&self) -> Vec<String> {
|
||||
let class = match &self.1 {
|
||||
Size::Custom(s) => &format!(" blur-[{s}]"),
|
||||
Size::None => "blur-none",
|
||||
Size::Small => "blur-sm",
|
||||
Size::Regular => "blur",
|
||||
Size::Medium => "blur-md",
|
||||
Size::Large => "blur-lg",
|
||||
Size::XL => "blur-xl",
|
||||
Size::_2XL => "blur-2xl",
|
||||
Size::_3XL => "blur-3xl",
|
||||
Size::Full => "blur-3xl",
|
||||
};
|
||||
|
||||
if self.2 {
|
||||
return vec![format!("backdrop-{class}")];
|
||||
}
|
||||
|
||||
vec![class.to_string()]
|
||||
}
|
||||
|
||||
fn extended_class(&self) -> Vec<String> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! build_value_widget {
|
||||
($constr:ident, $widget:ident, $class:literal) => {
|
||||
#[allow(non_snake_case)]
|
||||
pub fn $constr<T: UIWidget + 'static>(value: f64, inner: T) -> $widget {
|
||||
$widget(Box::new(inner), value, false)
|
||||
}
|
||||
|
||||
pub struct $widget(Box<dyn UIWidget>, f64, bool);
|
||||
|
||||
impl $widget {
|
||||
pub fn backdrop(mut self) -> Self {
|
||||
self.2 = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for $widget {
|
||||
fn render(&self) -> Markup {
|
||||
self.render_with_class("")
|
||||
}
|
||||
}
|
||||
|
||||
impl UIWidget for $widget {
|
||||
fn can_inherit(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn base_class(&self) -> Vec<String> {
|
||||
let mut ret = $class.to_string();
|
||||
ret.push_str(&format!("-[{:.2}]", self.1));
|
||||
|
||||
if self.2 {
|
||||
return vec![format!("backdrop-{ret}")];
|
||||
}
|
||||
|
||||
vec![ret]
|
||||
}
|
||||
|
||||
fn extended_class(&self) -> Vec<String> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
build_value_widget!(Brightness, BrightnessWidget, "brightness");
|
||||
build_value_widget!(Contrast, ConstrastWidget, "contrast");
|
||||
build_value_widget!(Saturate, SaturationWidget, "saturate");
|
||||
|
||||
macro_rules! build_on_off_widget {
|
||||
($constr:ident, $widget:ident, $class:literal) => {
|
||||
#[allow(non_snake_case)]
|
||||
pub fn $constr<T: UIWidget + 'static>(inner: T) -> $widget {
|
||||
$widget(Box::new(inner), true, false)
|
||||
}
|
||||
|
||||
pub struct $widget(Box<dyn UIWidget>, bool, bool);
|
||||
|
||||
impl $widget {
|
||||
pub fn none(mut self) -> Self {
|
||||
self.1 = false;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn backdrop(mut self) -> Self {
|
||||
self.2 = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for $widget {
|
||||
fn render(&self) -> Markup {
|
||||
self.render_with_class("")
|
||||
}
|
||||
}
|
||||
|
||||
impl UIWidget for $widget {
|
||||
fn can_inherit(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn base_class(&self) -> Vec<String> {
|
||||
let class = if self.1 {
|
||||
$class.to_string()
|
||||
} else {
|
||||
concat!($class, "-0").to_string()
|
||||
};
|
||||
|
||||
if self.2 {
|
||||
return vec![format!("backdrop-{class}")];
|
||||
}
|
||||
|
||||
vec![class]
|
||||
}
|
||||
|
||||
fn extended_class(&self) -> Vec<String> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
build_on_off_widget!(Grayscale, GrayscaleWidget, "grayscale");
|
||||
build_on_off_widget!(Invert, InvertWidget, "invert");
|
||||
build_on_off_widget!(Sepia, SepiaWidget, "sepia");
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn HueRotate<T: UIWidget + 'static>(deg: u32, inner: T) -> HueRotateWidget {
|
||||
HueRotateWidget(Box::new(inner), deg, false)
|
||||
}
|
||||
|
||||
pub struct HueRotateWidget(Box<dyn UIWidget>, u32, bool);
|
||||
|
||||
impl HueRotateWidget {
|
||||
pub fn backdrop(mut self) -> Self {
|
||||
self.2 = true;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for HueRotateWidget {
|
||||
fn render(&self) -> Markup {
|
||||
self.render_with_class("")
|
||||
}
|
||||
}
|
||||
|
||||
impl UIWidget for HueRotateWidget {
|
||||
fn can_inherit(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn base_class(&self) -> Vec<String> {
|
||||
let class = format!("hue-rotate-[{:.2}deg]", self.1);
|
||||
|
||||
if self.2 {
|
||||
return vec![format!("backdrop-{class}")];
|
||||
}
|
||||
|
||||
vec![class]
|
||||
}
|
||||
|
||||
fn extended_class(&self) -> Vec<String> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ pub mod background;
|
|||
pub mod container;
|
||||
pub mod cursor;
|
||||
pub mod div;
|
||||
pub mod filter;
|
||||
pub mod flex;
|
||||
pub mod header;
|
||||
pub mod height;
|
||||
|
@ -62,6 +63,7 @@ pub fn script(script: &str) -> PreEscaped<String> {
|
|||
}
|
||||
|
||||
pub enum Size {
|
||||
Custom(String),
|
||||
None,
|
||||
Small,
|
||||
Regular,
|
||||
|
@ -77,6 +79,7 @@ impl Size {
|
|||
#[must_use]
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
Self::Custom(str) => str.as_str(),
|
||||
Self::None => "none",
|
||||
Self::Small => "sm",
|
||||
Self::Regular => "",
|
||||
|
|
|
@ -12,7 +12,7 @@ pub struct RoundedWidget(Box<dyn UIWidget>, Option<Size>, Option<Side>);
|
|||
|
||||
impl RoundedWidget {
|
||||
#[must_use]
|
||||
pub const fn size(mut self, size: Size) -> Self {
|
||||
pub fn size(mut self, size: Size) -> Self {
|
||||
self.1 = Some(size);
|
||||
self
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue