freya_core/style/
border.rs

1use std::fmt;
2
3use freya_engine::prelude::{
4    SkPath,
5    SkRRect,
6};
7use torin::scaled::Scaled;
8
9use crate::prelude::Color;
10
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12#[derive(Default, Clone, Copy, Debug, PartialEq)]
13pub struct BorderWidth {
14    pub top: f32,
15    pub right: f32,
16    pub bottom: f32,
17    pub left: f32,
18}
19
20impl Scaled for BorderWidth {
21    fn scale(&mut self, scale_factor: f32) {
22        self.top *= scale_factor;
23        self.left *= scale_factor;
24        self.bottom *= scale_factor;
25        self.right *= scale_factor;
26    }
27}
28
29impl From<f32> for BorderWidth {
30    fn from(value: f32) -> Self {
31        BorderWidth {
32            top: value,
33            right: value,
34            bottom: value,
35            left: value,
36        }
37    }
38}
39
40impl fmt::Display for BorderWidth {
41    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42        write!(
43            f,
44            "{} {} {} {}",
45            self.top, self.right, self.bottom, self.left,
46        )
47    }
48}
49
50#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
51#[derive(Default, Clone, Copy, Debug, PartialEq)]
52pub enum BorderAlignment {
53    #[default]
54    Inner,
55    Outer,
56    Center,
57}
58
59pub enum BorderShape {
60    DRRect(SkRRect, SkRRect),
61    Path(SkPath),
62}
63
64#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
65#[derive(Default, Clone, Debug, PartialEq)]
66pub struct Border {
67    pub fill: Color,
68    pub width: BorderWidth,
69    pub alignment: BorderAlignment,
70}
71
72impl Border {
73    pub fn new() -> Self {
74        Self::default()
75    }
76
77    pub fn fill(mut self, color: impl Into<Color>) -> Self {
78        self.fill = color.into();
79        self
80    }
81
82    pub fn width(mut self, width: impl Into<BorderWidth>) -> Self {
83        self.width = width.into();
84        self
85    }
86
87    pub fn alignment(mut self, aligment: impl Into<BorderAlignment>) -> Self {
88        self.alignment = aligment.into();
89        self
90    }
91
92    #[inline]
93    pub(crate) fn is_visible(&self) -> bool {
94        !(self.width.top == 0.0
95            && self.width.left == 0.0
96            && self.width.bottom == 0.0
97            && self.width.right == 0.0)
98            && self.fill != Color::TRANSPARENT
99    }
100
101    pub fn pretty(&self) -> String {
102        format!("{} {:?}", self.width, self.alignment)
103    }
104}
105
106impl Scaled for Border {
107    fn scale(&mut self, scale_factor: f32) {
108        self.width.scale(scale_factor);
109    }
110}