add more borders

This commit is contained in:
JMARyA 2025-01-20 09:20:15 +01:00
parent bc27b457ea
commit ddd2e363c2
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
2 changed files with 234 additions and 1 deletions

View file

@ -23,7 +23,9 @@ pub mod prelude {
pub use super::primitives::animation::{Animated, Animation, Delay, Duration, Scope, Timing}; pub use super::primitives::animation::{Animated, Animation, Delay, Duration, Scope, Timing};
pub use super::primitives::aspect::Aspect; pub use super::primitives::aspect::Aspect;
pub use super::primitives::background::Background; pub use super::primitives::background::Background;
pub use super::primitives::border::{Border, BorderSide, BorderSize, BorderStyle}; pub use super::primitives::border::{
Border, BorderSide, BorderSize, BorderStyle, Outline, OutlineStyle, Ring,
};
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;

View file

@ -164,3 +164,234 @@ impl UIWidget for BorderWidget {
} }
} }
} }
pub enum OutlineStyle {
Solid,
Dashed,
Dotted,
Double,
None,
}
impl OutlineStyle {
pub const fn to_value(&self) -> &str {
match self {
OutlineStyle::Solid => "outline",
OutlineStyle::Dashed => "outline-dashed",
OutlineStyle::Dotted => "outline-dotted",
OutlineStyle::Double => "outline-double",
OutlineStyle::None => "outline-none",
}
}
}
#[allow(non_snake_case)]
pub fn Outline<T: UIWidget + 'static>(width: u32, inner: T) -> OutlineWidget {
OutlineWidget(Box::new(inner), width, None, None, 0)
}
pub struct OutlineWidget(
Box<dyn UIWidget>,
u32,
Option<Box<dyn UIColor>>,
Option<OutlineStyle>,
u32,
);
impl OutlineWidget {
#[must_use]
pub const fn offset(mut self, offset: u32) -> Self {
self.4 = offset;
self
}
#[must_use]
pub const fn style(mut self, style: OutlineStyle) -> Self {
self.3 = Some(style);
self
}
#[must_use]
pub fn color<C: UIColor + 'static>(mut self, color: C) -> Self {
self.2 = Some(Box::new(color));
self
}
}
impl Render for OutlineWidget {
fn render(&self) -> Markup {
self.render_with_class("")
}
}
impl UIWidget for OutlineWidget {
fn can_inherit(&self) -> bool {
true
}
fn base_class(&self) -> Vec<String> {
let class = match self.1 {
0 => "outline-0",
1 => "outline-1",
2 => "outline-2",
4 => "outline-4",
8 => "outline-8",
_ => &format!("outline-[{}px]", self.1),
};
let mut ret = vec![class.to_string()];
if let Some(color) = &self.2 {
ret.push(format!("outline-{}", color.color_class()));
}
if let Some(style) = &self.3 {
ret.push(style.to_value().to_string());
}
ret.push(match self.4 {
0 => "outline-offset-0".to_string(),
1 => "outline-offset-1".to_string(),
2 => "outline-offset-2".to_string(),
4 => "outline-offset-4".to_string(),
8 => "outline-offset-8".to_string(),
_ => format!("outline-offset-[{}px]", self.4),
});
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())
}
}
}
}
}
#[allow(non_snake_case)]
pub fn Ring<T: UIWidget + 'static>(width: u32, inner: T) -> RingWidget {
RingWidget(Box::new(inner), width, None, false, 0, None)
}
pub struct RingWidget(
// Inner
Box<dyn UIWidget>,
// Size
u32,
// Color
Option<Box<dyn UIColor>>,
// Inset
bool,
// Offset Width
u32,
// Offset Color
Option<Box<dyn UIColor>>,
);
impl RingWidget {
#[must_use]
pub const fn inset(mut self) -> Self {
self.3 = true;
self
}
#[must_use]
pub const fn offset_width(mut self, offset: u32) -> Self {
self.4 = offset;
self
}
#[must_use]
pub fn offset_color<C: UIColor + 'static>(mut self, color: C) -> Self {
self.5 = Some(Box::new(color));
self
}
#[must_use]
pub fn color<C: UIColor + 'static>(mut self, color: C) -> Self {
self.2 = Some(Box::new(color));
self
}
}
impl Render for RingWidget {
fn render(&self) -> Markup {
self.render_with_class("")
}
}
impl UIWidget for RingWidget {
fn can_inherit(&self) -> bool {
true
}
fn base_class(&self) -> Vec<String> {
let class = match self.1 {
0 => "ring-0",
1 => "ring-1",
2 => "ring-2",
4 => "ring-4",
8 => "ring-8",
_ => &format!("ring-[{}px]", self.1),
};
let mut ret = vec![class.to_string()];
if let Some(color) = &self.2 {
ret.push(format!("ring-{}", color.color_class()));
}
if self.3 {
ret.push("ring-inset".to_string());
}
ret.push(match self.4 {
0 => "ring-offset-0".to_string(),
1 => "ring-offset-1".to_string(),
2 => "ring-offset-2".to_string(),
4 => "ring-offset-4".to_string(),
8 => "ring-offset-8".to_string(),
_ => format!("ring-offset-[{}px]", self.4),
});
if let Some(color) = &self.5 {
ret.push(format!("ring-offset-{}", color.color_class()));
}
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())
}
}
}
}
}