freya_core/values/
fill.rs

1use std::fmt;
2
3use freya_engine::prelude::{
4    Color,
5    Paint,
6};
7use torin::prelude::Area;
8
9use super::{
10    ConicGradient,
11    DisplayColor,
12    LinearGradient,
13    RadialGradient,
14};
15use crate::parsing::{
16    Parse,
17    ParseError,
18};
19
20#[derive(Clone, Debug, PartialEq)]
21pub enum Fill {
22    Color(Color),
23    LinearGradient(Box<LinearGradient>),
24    RadialGradient(Box<RadialGradient>),
25    ConicGradient(Box<ConicGradient>),
26}
27
28impl Fill {
29    pub fn set_a(&mut self, a: u8) {
30        if let Fill::Color(color) = self {
31            *color = color.with_a(a);
32        }
33    }
34
35    pub fn apply_to_paint(&self, paint: &mut Paint, area: Area) {
36        match &self {
37            Fill::Color(color) => {
38                paint.set_color(*color);
39            }
40            Fill::LinearGradient(gradient) => {
41                paint.set_shader(gradient.into_shader(area));
42            }
43            Fill::RadialGradient(gradient) => {
44                paint.set_shader(gradient.into_shader(area));
45            }
46            Fill::ConicGradient(gradient) => {
47                paint.set_shader(gradient.into_shader(area));
48            }
49        }
50    }
51}
52
53impl Default for Fill {
54    fn default() -> Self {
55        Self::Color(Color::default())
56    }
57}
58
59impl From<Color> for Fill {
60    fn from(color: Color) -> Self {
61        Fill::Color(color)
62    }
63}
64
65impl Parse for Fill {
66    fn parse(value: &str) -> Result<Self, ParseError> {
67        Ok(if value.starts_with("linear-gradient(") {
68            Self::LinearGradient(Box::new(
69                LinearGradient::parse(value).map_err(|_| ParseError)?,
70            ))
71        } else if value.starts_with("radial-gradient(") {
72            Self::RadialGradient(Box::new(
73                RadialGradient::parse(value).map_err(|_| ParseError)?,
74            ))
75        } else if value.starts_with("conic-gradient(") {
76            Self::ConicGradient(Box::new(
77                ConicGradient::parse(value).map_err(|_| ParseError)?,
78            ))
79        } else {
80            Self::Color(Color::parse(value).map_err(|_| ParseError)?)
81        })
82    }
83}
84
85impl fmt::Display for Fill {
86    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87        match self {
88            Self::Color(color) => color.fmt_rgb(f),
89            Self::LinearGradient(gradient) => gradient.fmt(f),
90            Self::RadialGradient(gradient) => gradient.fmt(f),
91            Self::ConicGradient(gradient) => gradient.fmt(f),
92        }
93    }
94}