321 lines
7.8 KiB
Rust
321 lines
7.8 KiB
Rust
use maud::{Markup, Render, html};
|
|
|
|
use crate::ui::{
|
|
UIWidget,
|
|
color::{Gradient, UIColor},
|
|
};
|
|
|
|
#[allow(non_snake_case)]
|
|
pub fn Background<T: UIWidget + 'static>(inner: T) -> BackgroundWidget {
|
|
BackgroundWidget(
|
|
Box::new(inner),
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
)
|
|
}
|
|
|
|
pub struct BackgroundWidget(
|
|
// Inner
|
|
Box<dyn UIWidget>,
|
|
// Background Color
|
|
Option<Box<dyn UIColor>>,
|
|
// Background Attachment
|
|
Option<BackgroundScrollAttachment>,
|
|
Option<BackgroundClip>,
|
|
Option<BackgroundOrigin>,
|
|
Option<BackgroundRepeat>,
|
|
Option<BackgroundSize>,
|
|
// Background Image URL
|
|
Option<String>,
|
|
// Gradient
|
|
Option<BackgroundGradient>,
|
|
Option<Gradient>,
|
|
Option<BackgroundPosition>,
|
|
);
|
|
|
|
impl BackgroundWidget {
|
|
pub fn color<C: UIColor + 'static>(mut self, color: C) -> Self {
|
|
self.1 = Some(Box::new(color));
|
|
self
|
|
}
|
|
|
|
pub fn image(mut self, url: &str) -> Self {
|
|
self.7 = Some(url.to_string());
|
|
self
|
|
}
|
|
|
|
pub fn none(mut self) -> Self {
|
|
self.8 = Some(BackgroundGradient::None);
|
|
self
|
|
}
|
|
|
|
pub fn gradient(mut self, direction: BackgroundGradient, gradient: Gradient) -> Self {
|
|
self.8 = Some(direction);
|
|
self.9 = Some(gradient);
|
|
self
|
|
}
|
|
|
|
pub fn position(mut self, position: BackgroundPosition) -> Self {
|
|
self.10 = Some(position);
|
|
self
|
|
}
|
|
|
|
pub fn scroll(mut self, attachment: BackgroundScrollAttachment) -> Self {
|
|
self.2 = Some(attachment);
|
|
self
|
|
}
|
|
|
|
pub fn clip(mut self, clip: BackgroundClip) -> Self {
|
|
self.3 = Some(clip);
|
|
self
|
|
}
|
|
|
|
pub fn origin(mut self, origin: BackgroundOrigin) -> Self {
|
|
self.4 = Some(origin);
|
|
self
|
|
}
|
|
|
|
pub fn repeat(mut self, repeat: BackgroundRepeat) -> Self {
|
|
self.5 = Some(repeat);
|
|
self
|
|
}
|
|
|
|
pub fn size(mut self, size: BackgroundSize) -> Self {
|
|
self.6 = Some(size);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl Render for BackgroundWidget {
|
|
fn render(&self) -> Markup {
|
|
self.render_with_class("")
|
|
}
|
|
}
|
|
|
|
impl UIWidget for BackgroundWidget {
|
|
fn can_inherit(&self) -> bool {
|
|
true
|
|
}
|
|
|
|
fn base_class(&self) -> Vec<String> {
|
|
let mut ret = Vec::new();
|
|
|
|
if let Some(color) = &self.1 {
|
|
ret.push(format!("bg-{}", color.color_class()));
|
|
}
|
|
|
|
if let Some(attachment) = &self.2 {
|
|
ret.push(attachment.to_value().to_string());
|
|
}
|
|
|
|
if let Some(clip) = &self.3 {
|
|
ret.push(clip.to_value().to_string());
|
|
}
|
|
|
|
if let Some(origin) = &self.4 {
|
|
ret.push(origin.to_value().to_string());
|
|
}
|
|
|
|
if let Some(repeat) = &self.5 {
|
|
ret.push(repeat.to_value().to_string());
|
|
}
|
|
|
|
if let Some(size) = &self.6 {
|
|
ret.push(size.to_value().to_string());
|
|
}
|
|
|
|
if let Some(image) = &self.7 {
|
|
ret.push(format!("bg-[url('{image}')]"));
|
|
}
|
|
|
|
if let Some(gradient) = &self.8 {
|
|
ret.push(gradient.to_value().to_string());
|
|
}
|
|
|
|
if let Some(gradient) = &self.9 {
|
|
ret.extend_from_slice(&gradient.color_class());
|
|
}
|
|
|
|
if let Some(position) = &self.10 {
|
|
ret.push(position.to_value().to_string());
|
|
}
|
|
|
|
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())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Controlling how a background image behaves when scrolling.
|
|
pub enum BackgroundScrollAttachment {
|
|
/// Fix the background image relative to the viewport.
|
|
Fixed,
|
|
/// Scroll the background image with the container and the viewport.
|
|
Local,
|
|
/// Scroll the background image with the viewport, but not with the container.
|
|
Scroll,
|
|
}
|
|
|
|
impl BackgroundScrollAttachment {
|
|
pub const fn to_value(&self) -> &str {
|
|
match self {
|
|
BackgroundScrollAttachment::Fixed => "bg-fixed",
|
|
BackgroundScrollAttachment::Local => "bg-local",
|
|
BackgroundScrollAttachment::Scroll => "bg-scroll",
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum BackgroundClip {
|
|
Border,
|
|
Padding,
|
|
Content,
|
|
Text,
|
|
}
|
|
|
|
impl BackgroundClip {
|
|
pub const fn to_value(&self) -> &str {
|
|
match self {
|
|
BackgroundClip::Border => "bg-clip-border",
|
|
BackgroundClip::Padding => "bg-clip-padding",
|
|
BackgroundClip::Content => "bg-clip-content",
|
|
BackgroundClip::Text => "bg-clip-text",
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum BackgroundOrigin {
|
|
Border,
|
|
Padding,
|
|
Content,
|
|
}
|
|
|
|
impl BackgroundOrigin {
|
|
pub const fn to_value(&self) -> &str {
|
|
match self {
|
|
BackgroundOrigin::Border => "bg-origin-border",
|
|
BackgroundOrigin::Padding => "bg-origin-padding",
|
|
BackgroundOrigin::Content => "bg-origin-content",
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum BackgroundRepeat {
|
|
Repeat,
|
|
NoRepeat,
|
|
RepeatX,
|
|
RepeatY,
|
|
Round,
|
|
Space,
|
|
}
|
|
|
|
impl BackgroundRepeat {
|
|
pub const fn to_value(&self) -> &str {
|
|
match self {
|
|
BackgroundRepeat::Repeat => "bg-repeat",
|
|
BackgroundRepeat::NoRepeat => "bg-no-repeat",
|
|
BackgroundRepeat::RepeatX => "bg-repeat-x",
|
|
BackgroundRepeat::RepeatY => "bg-repeat-y",
|
|
BackgroundRepeat::Round => "bg-repeat-round",
|
|
BackgroundRepeat::Space => "bg-repeat-space",
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum BackgroundSize {
|
|
Auto,
|
|
Cover,
|
|
Contain,
|
|
}
|
|
|
|
impl BackgroundSize {
|
|
pub const fn to_value(&self) -> &str {
|
|
match self {
|
|
BackgroundSize::Auto => "bg-auto",
|
|
BackgroundSize::Cover => "bg-cover",
|
|
BackgroundSize::Contain => "bg-contain",
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum BackgroundGradient {
|
|
None,
|
|
ToTop,
|
|
ToTopRight,
|
|
ToRight,
|
|
ToBottomRight,
|
|
ToBottom,
|
|
ToBottomLeft,
|
|
ToLeft,
|
|
ToTopLeft,
|
|
}
|
|
|
|
impl BackgroundGradient {
|
|
pub const fn to_value(&self) -> &str {
|
|
match self {
|
|
BackgroundGradient::None => "bg-none",
|
|
BackgroundGradient::ToTop => "bg-gradient-to-t",
|
|
BackgroundGradient::ToTopRight => "bg-gradient-to-tr",
|
|
BackgroundGradient::ToRight => "bg-gradient-to-r",
|
|
BackgroundGradient::ToBottomRight => "bg-gradient-to-br",
|
|
BackgroundGradient::ToBottom => "bg-gradient-to-b",
|
|
BackgroundGradient::ToBottomLeft => "bg-gradient-to-bl",
|
|
BackgroundGradient::ToLeft => "bg-gradient-to-l",
|
|
BackgroundGradient::ToTopLeft => "bg-gradient-to-tl",
|
|
}
|
|
}
|
|
}
|
|
|
|
pub enum BackgroundPosition {
|
|
Bottom,
|
|
Center,
|
|
Left,
|
|
LeftBottom,
|
|
LeftTop,
|
|
Right,
|
|
RightBottom,
|
|
RightTop,
|
|
Top,
|
|
}
|
|
|
|
impl BackgroundPosition {
|
|
pub const fn to_value(&self) -> &str {
|
|
match self {
|
|
BackgroundPosition::Bottom => "bg-bottom",
|
|
BackgroundPosition::Center => "bg-center",
|
|
BackgroundPosition::Left => "bg-left",
|
|
BackgroundPosition::LeftBottom => "bg-left-bottom",
|
|
BackgroundPosition::LeftTop => "bg-left-top",
|
|
BackgroundPosition::Right => "bg-right",
|
|
BackgroundPosition::RightBottom => "bg-right-bottom",
|
|
BackgroundPosition::RightTop => "bg-right-top",
|
|
BackgroundPosition::Top => "bg-top",
|
|
}
|
|
}
|
|
}
|