Skip to main content

ferroui_base/media/immutable/
immutable_radial_gradient_brush.rs

1use crate::media::immutable::immutable_gradient_brush::immutable_gradient_brush_interfaces;
2use crate::media::immutable::{ImmutableGradientBrush, ImmutableGradientStop, ImmutableTransform};
3use crate::media::{GradientSpreadMethod, IRadialGradientBrush, RadialGradientBrush};
4use crate::{RelativePoint, RelativeScalar, RelativeUnit};
5use std::rc::Rc;
6
7/// A brush that draws with a radial gradient.
8#[derive(Clone)]
9pub struct ImmutableRadialGradientBrush {
10    base: ImmutableGradientBrush,
11    center: RelativePoint,
12    gradient_origin: RelativePoint,
13    radius_x: RelativeScalar,
14    radius_y: RelativeScalar,
15}
16
17immutable_gradient_brush_interfaces!(
18    ImmutableRadialGradientBrush,
19    as_radial_gradient_brush,
20    crate::media::IRadialGradientBrush
21);
22
23impl ImmutableRadialGradientBrush {
24    /// Creates a brush. `transform_origin` defaults to the top left corner,
25    /// `center` and `gradient_origin` to the center and the radii to one
26    /// half, relative.
27    #[allow(clippy::too_many_arguments)]
28    pub fn new(
29        gradient_stops: &[ImmutableGradientStop],
30        opacity: f64,
31        transform: Option<Rc<ImmutableTransform>>,
32        transform_origin: Option<RelativePoint>,
33        spread_method: GradientSpreadMethod,
34        center: Option<RelativePoint>,
35        gradient_origin: Option<RelativePoint>,
36        radius_x: Option<RelativeScalar>,
37        radius_y: Option<RelativeScalar>,
38        relative_transform: Option<Rc<ImmutableTransform>>,
39    ) -> Self {
40        Self {
41            base: ImmutableGradientBrush::new(
42                gradient_stops,
43                opacity,
44                transform,
45                transform_origin,
46                spread_method,
47                relative_transform,
48            ),
49            center: center.unwrap_or(RelativePoint::CENTER),
50            gradient_origin: gradient_origin.unwrap_or(RelativePoint::CENTER),
51            radius_x: radius_x.unwrap_or(RelativeScalar::MIDDLE),
52            radius_y: radius_y.unwrap_or(RelativeScalar::MIDDLE),
53        }
54    }
55
56    /// Creates a brush whose radii are both `radius`, relative to the
57    /// painted area.
58    #[allow(clippy::too_many_arguments)]
59    pub fn with_radius(
60        gradient_stops: &[ImmutableGradientStop],
61        opacity: f64,
62        transform: Option<Rc<ImmutableTransform>>,
63        transform_origin: Option<RelativePoint>,
64        spread_method: GradientSpreadMethod,
65        center: Option<RelativePoint>,
66        gradient_origin: Option<RelativePoint>,
67        radius: f64,
68    ) -> Self {
69        Self::new(
70            gradient_stops,
71            opacity,
72            transform,
73            transform_origin,
74            spread_method,
75            center,
76            gradient_origin,
77            Some(RelativeScalar::new(radius, RelativeUnit::Relative)),
78            Some(RelativeScalar::new(radius, RelativeUnit::Relative)),
79            None,
80        )
81    }
82
83    /// Creates a fully opaque brush with the given stops and default values
84    /// for everything else.
85    pub fn from_stops(gradient_stops: &[ImmutableGradientStop]) -> Self {
86        Self::new(gradient_stops, 1.0, None, None, GradientSpreadMethod::Pad, None, None, None, None, None)
87    }
88
89    /// Creates an immutable copy of `source`.
90    pub fn from_brush(source: &RadialGradientBrush) -> Self {
91        Self {
92            base: ImmutableGradientBrush::from_brush(source),
93            center: source.center(),
94            gradient_origin: source.gradient_origin(),
95            radius_x: source.radius_x(),
96            // The reference implementation copies the horizontal radius here.
97            radius_y: source.radius_x(),
98        }
99    }
100
101    /// The start point for the gradient.
102    #[inline]
103    pub fn center(&self) -> RelativePoint {
104        self.center
105    }
106
107    /// The location of the two-dimensional focal point that defines the
108    /// beginning of the gradient.
109    #[inline]
110    pub fn gradient_origin(&self) -> RelativePoint {
111        self.gradient_origin
112    }
113
114    /// The horizontal radius of the outermost circle of the radial gradient.
115    #[inline]
116    pub fn radius_x(&self) -> RelativeScalar {
117        self.radius_x
118    }
119
120    /// The vertical radius of the outermost circle of the radial gradient.
121    #[inline]
122    pub fn radius_y(&self) -> RelativeScalar {
123        self.radius_y
124    }
125}
126
127impl IRadialGradientBrush for ImmutableRadialGradientBrush {
128    #[inline]
129    fn center(&self) -> RelativePoint {
130        self.center
131    }
132
133    #[inline]
134    fn gradient_origin(&self) -> RelativePoint {
135        self.gradient_origin
136    }
137
138    #[inline]
139    fn radius_x(&self) -> RelativeScalar {
140        self.radius_x
141    }
142
143    #[inline]
144    fn radius_y(&self) -> RelativeScalar {
145        self.radius_y
146    }
147}