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;
|
use tokio::sync::OnceCell;
|
||||||
|
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
|
|
|
@ -26,6 +26,9 @@ pub mod prelude {
|
||||||
pub use super::primitives::container::Container;
|
pub use super::primitives::container::Container;
|
||||||
pub use super::primitives::cursor::Cursor;
|
pub use super::primitives::cursor::Cursor;
|
||||||
pub use super::primitives::div::Div;
|
pub use super::primitives::div::Div;
|
||||||
|
pub use super::primitives::filter::{
|
||||||
|
Blur, Brightness, Contrast, Grayscale, HueRotate, Invert, Saturate, Sepia,
|
||||||
|
};
|
||||||
pub use super::primitives::flex::{
|
pub use super::primitives::flex::{
|
||||||
Direction, Flex, FlexBasis, FlexGrow, Justify, Order, Strategy, Wrap,
|
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 container;
|
||||||
pub mod cursor;
|
pub mod cursor;
|
||||||
pub mod div;
|
pub mod div;
|
||||||
|
pub mod filter;
|
||||||
pub mod flex;
|
pub mod flex;
|
||||||
pub mod header;
|
pub mod header;
|
||||||
pub mod height;
|
pub mod height;
|
||||||
|
@ -62,6 +63,7 @@ pub fn script(script: &str) -> PreEscaped<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Size {
|
pub enum Size {
|
||||||
|
Custom(String),
|
||||||
None,
|
None,
|
||||||
Small,
|
Small,
|
||||||
Regular,
|
Regular,
|
||||||
|
@ -77,6 +79,7 @@ impl Size {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn to_value(&self) -> &str {
|
pub const fn to_value(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
|
Self::Custom(str) => str.as_str(),
|
||||||
Self::None => "none",
|
Self::None => "none",
|
||||||
Self::Small => "sm",
|
Self::Small => "sm",
|
||||||
Self::Regular => "",
|
Self::Regular => "",
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub struct RoundedWidget(Box<dyn UIWidget>, Option<Size>, Option<Side>);
|
||||||
|
|
||||||
impl RoundedWidget {
|
impl RoundedWidget {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn size(mut self, size: Size) -> Self {
|
pub fn size(mut self, size: Size) -> Self {
|
||||||
self.1 = Some(size);
|
self.1 = Some(size);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue