ferroui_base/media/immutable/
immutable_gradient_brush.rs1use crate::media::immutable::{ImmutableGradientStop, ImmutableTransform};
2use crate::media::{GradientBrush, GradientSpreadMethod, IGradientStop, ITransform, TransformExtensions};
3use crate::RelativePoint;
4use std::rc::Rc;
5
6#[derive(Clone)]
8pub struct ImmutableGradientBrush {
9 gradient_stops: Vec<Rc<dyn IGradientStop>>,
10 opacity: f64,
11 transform: Option<Rc<dyn ITransform>>,
12 transform_origin: RelativePoint,
13 spread_method: GradientSpreadMethod,
14 relative_transform: Option<Rc<dyn ITransform>>,
15 pub(crate) shared: std::sync::OnceLock<Option<crate::media::SharedBrush>>,
17}
18
19impl ImmutableGradientBrush {
20 pub fn new(
23 gradient_stops: &[ImmutableGradientStop],
24 opacity: f64,
25 transform: Option<Rc<ImmutableTransform>>,
26 transform_origin: Option<RelativePoint>,
27 spread_method: GradientSpreadMethod,
28 relative_transform: Option<Rc<ImmutableTransform>>,
29 ) -> Self {
30 Self {
31 gradient_stops: gradient_stops.iter().map(|stop| Rc::new(*stop) as Rc<dyn IGradientStop>).collect(),
32 opacity,
33 transform: transform.map(|t| t as Rc<dyn ITransform>),
34 transform_origin: transform_origin.unwrap_or(RelativePoint::TOP_LEFT),
35 spread_method,
36 relative_transform: relative_transform.map(|t| t as Rc<dyn ITransform>),
37 shared: std::sync::OnceLock::new(),
38 }
39 }
40
41 pub fn from_brush(source: &GradientBrush) -> Self {
43 Self::new(
44 &source.gradient_stops().to_immutable(),
45 source.opacity(),
46 source.transform().map(|t| Rc::new(TransformExtensions::to_immutable(&*t))),
47 Some(source.transform_origin()),
48 source.spread_method(),
49 source.relative_transform().map(|t| Rc::new(TransformExtensions::to_immutable(&*t))),
50 )
51 }
52
53 #[inline]
55 pub fn gradient_stops(&self) -> &[Rc<dyn IGradientStop>] {
56 &self.gradient_stops
57 }
58
59 #[inline]
61 pub fn opacity(&self) -> f64 {
62 self.opacity
63 }
64
65 #[inline]
67 pub fn transform(&self) -> Option<Rc<dyn ITransform>> {
68 self.transform.clone()
69 }
70
71 #[inline]
73 pub fn transform_origin(&self) -> RelativePoint {
74 self.transform_origin
75 }
76
77 #[inline]
79 pub fn spread_method(&self) -> GradientSpreadMethod {
80 self.spread_method
81 }
82
83 #[inline]
86 pub fn relative_transform(&self) -> Option<Rc<dyn ITransform>> {
87 self.relative_transform.clone()
88 }
89}
90
91macro_rules! immutable_gradient_brush_interfaces {
94 ($name:ty, $as_fn:ident, $iface:path) => {
95 impl ::std::ops::Deref for $name {
96 type Target = $crate::media::immutable::ImmutableGradientBrush;
97 #[inline]
98 fn deref(&self) -> &Self::Target {
99 &self.base
100 }
101 }
102
103 impl $crate::media::IBrush for $name {
104 #[inline]
105 fn opacity(&self) -> f64 {
106 self.base.opacity()
107 }
108
109 fn transform(&self) -> Option<::std::rc::Rc<dyn $crate::media::ITransform>> {
110 self.base.transform()
111 }
112
113 #[inline]
114 fn transform_origin(&self) -> $crate::RelativePoint {
115 self.base.transform_origin()
116 }
117
118 fn relative_transform(&self) -> Option<::std::rc::Rc<dyn $crate::media::ITransform>> {
119 self.base.relative_transform()
120 }
121
122 fn as_immutable_brush(&self) -> Option<&dyn $crate::media::IImmutableBrush> {
123 Some(self)
124 }
125
126 fn as_any(&self) -> &dyn ::std::any::Any {
127 self
128 }
129
130 fn as_gradient_brush(&self) -> Option<&dyn $crate::media::IGradientBrush> {
131 Some(self)
132 }
133
134 fn $as_fn(&self) -> Option<&dyn $iface> {
135 Some(self)
136 }
137
138 fn into_immutable_brush(
139 self: ::std::rc::Rc<Self>,
140 ) -> Option<::std::rc::Rc<dyn $crate::media::IImmutableBrush>> {
141 Some(self)
142 }
143
144 fn to_shared(&self) -> Option<$crate::media::SharedBrush> {
145 self.base.shared.get_or_init(|| $crate::media::SharedBrush::from_brush(self)).clone()
146 }
147 }
148
149 impl $crate::media::IGradientBrush for $name {
150 fn gradient_stops(&self) -> Vec<::std::rc::Rc<dyn $crate::media::IGradientStop>> {
151 self.base.gradient_stops().to_vec()
152 }
153
154 #[inline]
155 fn spread_method(&self) -> $crate::media::GradientSpreadMethod {
156 self.base.spread_method()
157 }
158 }
159
160 impl $crate::media::IImmutableBrush for $name {}
161 };
162}
163
164pub(crate) use immutable_gradient_brush_interfaces;