1use super::composition_object_impls::composition_object_impls;
13use super::generated::{
14 CompositionEllipseGeometryHooks, CompositionEllipseGeometryProps, CompositionGeometryHooks,
15 CompositionGeometryProps, CompositionLineGeometryHooks, CompositionLineGeometryProps,
16 CompositionPathGeometryHooks, CompositionPathGeometryProps, CompositionRectangleGeometryHooks,
17 CompositionRectangleGeometryProps, CompositionRoundedRectangleGeometryHooks,
18 CompositionRoundedRectangleGeometryProps, ServerCompositionEllipseGeometryProps,
19 ServerCompositionLineGeometryProps, ServerCompositionPathGeometryProps, ServerCompositionRectangleGeometryProps,
20 ServerCompositionRoundedRectangleGeometryProps,
21};
22use super::server::{
23 IServerObject, ServerCompositionEllipseGeometry, ServerCompositionLineGeometry, ServerCompositionPathGeometry,
24 ServerCompositionRectangleGeometry, ServerCompositionRoundedRectangleGeometry, ServerCompositor, ServerObjectId,
25};
26use super::{CompositionObject, Compositor};
27use crate::media::Geometry;
28use crate::platform::IGeometryImpl;
29use crate::utilities::FormatError;
30use crate::{Rect, Vector};
31use std::ops::Deref;
32use std::rc::{Rc, Weak};
33use std::sync::Arc;
34
35#[derive(Clone)]
45pub struct CompositionPath {
46 geometry: Arc<dyn IGeometryImpl>,
47}
48
49impl CompositionPath {
50 pub fn new(geometry: Arc<dyn IGeometryImpl>) -> CompositionPath {
52 CompositionPath { geometry }
53 }
54
55 pub fn from_geometry(geometry: &Geometry) -> Option<CompositionPath> {
58 geometry.platform_impl().map(CompositionPath::new)
59 }
60
61 pub fn parse(data: &str) -> Result<CompositionPath, FormatError> {
64 let geometry = Geometry::parse(data)?;
65 let platform = geometry.platform_impl().expect("a parsed stream geometry has a platform geometry");
66 Ok(CompositionPath::new(platform))
67 }
68
69 pub fn geometry(&self) -> &Arc<dyn IGeometryImpl> {
71 &self.geometry
72 }
73
74 pub fn bounds(&self) -> Rect {
76 self.geometry.bounds()
77 }
78}
79
80impl std::fmt::Debug for CompositionPath {
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 f.debug_struct("CompositionPath").field("bounds", &self.geometry.bounds()).finish()
83 }
84}
85
86pub(crate) enum CompositionGeometryKind {
88 Rectangle(CompositionRectangleGeometryProps),
89 RoundedRectangle(CompositionRoundedRectangleGeometryProps),
90 Ellipse(CompositionEllipseGeometryProps),
91 Line(CompositionLineGeometryProps),
92 Path(CompositionPathGeometryProps),
93}
94
95pub struct CompositionGeometry {
101 this: Weak<CompositionGeometry>,
102 object: CompositionObject,
103 kind: CompositionGeometryKind,
104}
105
106impl CompositionGeometry {
107 fn create(
108 compositor: &Rc<Compositor>,
109 kind: CompositionGeometryKind,
110 server: impl FnOnce(&Rc<ServerCompositor>) -> Rc<dyn IServerObject> + Send + 'static,
111 ) -> Rc<CompositionGeometry> {
112 let server = compositor.create_server_object(move |compositor, _| server(compositor));
113 let geometry = Rc::new_cyclic(|this: &Weak<CompositionGeometry>| CompositionGeometry {
114 this: this.clone(),
115 object: CompositionObject::new(compositor, Some(server)),
116 kind,
117 });
118 match &geometry.kind {
119 CompositionGeometryKind::Rectangle(props) => props.initialize_defaults(&*geometry),
120 CompositionGeometryKind::RoundedRectangle(props) => props.initialize_defaults(&*geometry),
121 CompositionGeometryKind::Ellipse(props) => props.initialize_defaults(&*geometry),
122 CompositionGeometryKind::Line(props) => props.initialize_defaults(&*geometry),
123 CompositionGeometryKind::Path(props) => props.initialize_defaults(&*geometry),
124 }
125 geometry
126 }
127
128 pub fn geometry_props(&self) -> &CompositionGeometryProps {
130 match &self.kind {
131 CompositionGeometryKind::Rectangle(props) => props.base(),
132 CompositionGeometryKind::RoundedRectangle(props) => props.base(),
133 CompositionGeometryKind::Ellipse(props) => props.base(),
134 CompositionGeometryKind::Line(props) => props.base(),
135 CompositionGeometryKind::Path(props) => props.base(),
136 }
137 }
138
139 pub fn compositor(&self) -> &Rc<Compositor> {
140 self.object.compositor()
141 }
142
143 pub fn object(&self) -> &CompositionObject {
145 &self.object
146 }
147
148 pub fn server(&self) -> ServerObjectId {
150 self.object.required_server()
151 }
152
153 pub fn is_disposed(&self) -> bool {
154 self.object.is_disposed()
155 }
156
157 pub fn dispose(&self) {
158 self.object.dispose();
159 }
160
161 pub fn type_name(&self) -> &'static str {
163 match &self.kind {
164 CompositionGeometryKind::Rectangle(_) => "CompositionRectangleGeometry",
165 CompositionGeometryKind::RoundedRectangle(_) => "CompositionRoundedRectangleGeometry",
166 CompositionGeometryKind::Ellipse(_) => "CompositionEllipseGeometry",
167 CompositionGeometryKind::Line(_) => "CompositionLineGeometry",
168 CompositionGeometryKind::Path(_) => "CompositionPathGeometry",
169 }
170 }
171
172 pub fn trim_end(&self) -> f32 {
175 self.geometry_props().trim_end()
176 }
177
178 pub fn set_trim_end(&self, value: f32) {
179 self.geometry_props().set_trim_end(self, value)
180 }
181
182 pub fn trim_offset(&self) -> f32 {
185 self.geometry_props().trim_offset()
186 }
187
188 pub fn set_trim_offset(&self, value: f32) {
189 self.geometry_props().set_trim_offset(self, value)
190 }
191
192 pub fn trim_start(&self) -> f32 {
195 self.geometry_props().trim_start()
196 }
197
198 pub fn set_trim_start(&self, value: f32) {
199 self.geometry_props().set_trim_start(self, value)
200 }
201}
202
203impl CompositionGeometryHooks for CompositionGeometry {}
204
205impl CompositionRectangleGeometryHooks for CompositionGeometry {}
206
207impl CompositionRoundedRectangleGeometryHooks for CompositionGeometry {}
208
209impl CompositionEllipseGeometryHooks for CompositionGeometry {}
210
211impl CompositionLineGeometryHooks for CompositionGeometry {}
212
213impl CompositionPathGeometryHooks for CompositionGeometry {}
214
215composition_object_impls!(
216 CompositionGeometry, "CompositionGeometry",
217 serialize: |this, writer| match &this.kind {
218 CompositionGeometryKind::Rectangle(props) => props.serialize_changes_core(this, writer),
219 CompositionGeometryKind::RoundedRectangle(props) => props.serialize_changes_core(this, writer),
220 CompositionGeometryKind::Ellipse(props) => props.serialize_changes_core(this, writer),
221 CompositionGeometryKind::Line(props) => props.serialize_changes_core(this, writer),
222 CompositionGeometryKind::Path(props) => props.serialize_changes_core(this, writer),
223 },
224 start_animation: |this, name, animation, final_value| match &this.kind {
225 CompositionGeometryKind::Rectangle(props) => props.start_animation(this, name, animation, final_value),
226 CompositionGeometryKind::RoundedRectangle(props) => props.start_animation(this, name, animation, final_value),
227 CompositionGeometryKind::Ellipse(props) => props.start_animation(this, name, animation, final_value),
228 CompositionGeometryKind::Line(props) => props.start_animation(this, name, animation, final_value),
229 CompositionGeometryKind::Path(props) => props.start_animation(this, name, animation, final_value),
230 },
231 composition_property: |this, name| match &this.kind {
232 CompositionGeometryKind::Rectangle(_) => ServerCompositionRectangleGeometryProps::get_composition_property(name),
233 CompositionGeometryKind::RoundedRectangle(_) => {
234 ServerCompositionRoundedRectangleGeometryProps::get_composition_property(name)
235 }
236 CompositionGeometryKind::Ellipse(_) => ServerCompositionEllipseGeometryProps::get_composition_property(name),
237 CompositionGeometryKind::Line(_) => ServerCompositionLineGeometryProps::get_composition_property(name),
238 CompositionGeometryKind::Path(_) => ServerCompositionPathGeometryProps::get_composition_property(name),
239 },
240);
241
242macro_rules! geometry_handle {
245 ($(#[$meta:meta])* $name:ident, $variant:ident, $props:ident, $what:literal) => {
246 $(#[$meta])*
247 #[derive(Clone)]
248 pub struct $name(Rc<CompositionGeometry>);
249
250 impl Deref for $name {
251 type Target = Rc<CompositionGeometry>;
252
253 fn deref(&self) -> &Rc<CompositionGeometry> {
254 &self.0
255 }
256 }
257
258 impl $name {
259 #[doc = concat!("The handle of `geometry` as ", $what, ", if it is one.")]
260 pub fn from_geometry(geometry: &Rc<CompositionGeometry>) -> Option<$name> {
261 matches!(geometry.kind, CompositionGeometryKind::$variant(_)).then(|| $name(geometry.clone()))
262 }
263
264 pub fn geometry(&self) -> &Rc<CompositionGeometry> {
266 &self.0
267 }
268
269 fn props(&self) -> &$props {
270 match &self.0.kind {
271 CompositionGeometryKind::$variant(props) => props,
272 _ => unreachable!(concat!("the handle wraps ", $what)),
273 }
274 }
275 }
276 };
277}
278
279geometry_handle!(
280 CompositionRectangleGeometry,
283 Rectangle,
284 CompositionRectangleGeometryProps,
285 "a rectangle geometry"
286);
287
288impl CompositionRectangleGeometry {
289 pub(crate) fn new(compositor: &Rc<Compositor>) -> CompositionRectangleGeometry {
290 CompositionRectangleGeometry(CompositionGeometry::create(
291 compositor,
292 CompositionGeometryKind::Rectangle(CompositionRectangleGeometryProps::new()),
293 |c| ServerCompositionRectangleGeometry::new(c),
294 ))
295 }
296
297 pub fn offset(&self) -> Vector {
299 self.props().offset()
300 }
301
302 pub fn set_offset(&self, value: Vector) {
303 self.props().set_offset(&*self.0, value)
304 }
305
306 pub fn size(&self) -> Vector {
308 self.props().size()
309 }
310
311 pub fn set_size(&self, value: Vector) {
312 self.props().set_size(&*self.0, value)
313 }
314}
315
316geometry_handle!(
317 CompositionRoundedRectangleGeometry,
323 RoundedRectangle,
324 CompositionRoundedRectangleGeometryProps,
325 "a rounded rectangle geometry"
326);
327
328impl CompositionRoundedRectangleGeometry {
329 pub(crate) fn new(compositor: &Rc<Compositor>) -> CompositionRoundedRectangleGeometry {
330 CompositionRoundedRectangleGeometry(CompositionGeometry::create(
331 compositor,
332 CompositionGeometryKind::RoundedRectangle(CompositionRoundedRectangleGeometryProps::new()),
333 |c| ServerCompositionRoundedRectangleGeometry::new(c),
334 ))
335 }
336
337 pub fn corner_radius(&self) -> Vector {
339 self.props().corner_radius()
340 }
341
342 pub fn set_corner_radius(&self, value: Vector) {
343 self.props().set_corner_radius(&*self.0, value)
344 }
345
346 pub fn offset(&self) -> Vector {
348 self.props().offset()
349 }
350
351 pub fn set_offset(&self, value: Vector) {
352 self.props().set_offset(&*self.0, value)
353 }
354
355 pub fn size(&self) -> Vector {
357 self.props().size()
358 }
359
360 pub fn set_size(&self, value: Vector) {
361 self.props().set_size(&*self.0, value)
362 }
363}
364
365geometry_handle!(
366 CompositionEllipseGeometry,
370 Ellipse,
371 CompositionEllipseGeometryProps,
372 "an ellipse geometry"
373);
374
375impl CompositionEllipseGeometry {
376 pub(crate) fn new(compositor: &Rc<Compositor>) -> CompositionEllipseGeometry {
377 CompositionEllipseGeometry(CompositionGeometry::create(
378 compositor,
379 CompositionGeometryKind::Ellipse(CompositionEllipseGeometryProps::new()),
380 |c| ServerCompositionEllipseGeometry::new(c),
381 ))
382 }
383
384 pub fn center(&self) -> Vector {
386 self.props().center()
387 }
388
389 pub fn set_center(&self, value: Vector) {
390 self.props().set_center(&*self.0, value)
391 }
392
393 pub fn radius(&self) -> Vector {
395 self.props().radius()
396 }
397
398 pub fn set_radius(&self, value: Vector) {
399 self.props().set_radius(&*self.0, value)
400 }
401}
402
403geometry_handle!(
404 CompositionLineGeometry,
407 Line,
408 CompositionLineGeometryProps,
409 "a line geometry"
410);
411
412impl CompositionLineGeometry {
413 pub(crate) fn new(compositor: &Rc<Compositor>) -> CompositionLineGeometry {
414 CompositionLineGeometry(CompositionGeometry::create(
415 compositor,
416 CompositionGeometryKind::Line(CompositionLineGeometryProps::new()),
417 |c| ServerCompositionLineGeometry::new(c),
418 ))
419 }
420
421 pub fn start(&self) -> Vector {
423 self.props().start()
424 }
425
426 pub fn set_start(&self, value: Vector) {
427 self.props().set_start(&*self.0, value)
428 }
429
430 pub fn end(&self) -> Vector {
432 self.props().end()
433 }
434
435 pub fn set_end(&self, value: Vector) {
436 self.props().set_end(&*self.0, value)
437 }
438}
439
440geometry_handle!(
441 CompositionPathGeometry,
444 Path,
445 CompositionPathGeometryProps,
446 "a path geometry"
447);
448
449impl CompositionPathGeometry {
450 pub(crate) fn new(compositor: &Rc<Compositor>) -> CompositionPathGeometry {
451 CompositionPathGeometry(CompositionGeometry::create(
452 compositor,
453 CompositionGeometryKind::Path(CompositionPathGeometryProps::new()),
454 |c| ServerCompositionPathGeometry::new(c),
455 ))
456 }
457
458 pub(crate) fn with_path(compositor: &Rc<Compositor>, path: Option<CompositionPath>) -> CompositionPathGeometry {
459 let geometry = Self::new(compositor);
460 geometry.set_path(path);
461 geometry
462 }
463
464 pub fn path(&self) -> Option<CompositionPath> {
466 self.props().path().map(|path| (*path).clone())
467 }
468
469 pub fn set_path(&self, value: Option<CompositionPath>) {
470 self.props().set_path(&*self.0, value.map(Arc::new))
471 }
472}