Skip to main content

windows_composition/
shape.rs

1use super::*;
2
3/// The base type shared by every composition shape. A [`Shape`] can be turned
4/// into one via [`Shape::as_shape`] to append it to a
5/// [`CompositionShapeCollection`].
6#[derive(Clone)]
7pub struct CompositionShape(pub(crate) bindings::CompositionShape);
8
9/// A shape that can be appended to a [`CompositionShapeCollection`].
10///
11/// This trait is sealed: only the shape types in this crate implement it.
12pub trait Shape: Sealed {
13    /// Returns this shape as the shared [`CompositionShape`] base type.
14    fn as_shape(&self) -> CompositionShape;
15}
16
17/// The base type shared by every composition geometry.
18#[derive(Clone)]
19pub struct CompositionGeometry(pub(crate) bindings::CompositionGeometry);
20
21/// An ellipse (or circle) geometry, defined by its radii.
22#[derive(Clone)]
23pub struct CompositionEllipseGeometry(pub(crate) bindings::CompositionEllipseGeometry);
24
25impl CompositionEllipseGeometry {
26    /// Sets the geometry's x and y radii, in DIPs.
27    pub fn set_radius(&self, radius: Vector2) {
28        self.0.SetRadius(radius).unwrap();
29    }
30
31    pub(crate) fn as_geometry(&self) -> CompositionGeometry {
32        CompositionGeometry(self.0.cast().unwrap())
33    }
34}
35
36/// A shape that fills a geometry with a [`Brush`].
37#[derive(Clone)]
38pub struct CompositionSpriteShape(pub(crate) bindings::CompositionSpriteShape);
39
40impl CompositionSpriteShape {
41    /// Sets the brush used to fill the shape's geometry.
42    pub fn set_fill_brush(&self, brush: &impl Brush) {
43        self.0.SetFillBrush(&brush.as_brush().0).unwrap();
44    }
45
46    /// Sets the shape's offset from its parent, in DIPs.
47    pub fn set_offset(&self, offset: Vector2) {
48        let shape: bindings::ICompositionShape = self.0.cast().unwrap();
49        shape.SetOffset(offset).unwrap();
50    }
51}
52
53impl Sealed for CompositionSpriteShape {}
54
55impl Shape for CompositionSpriteShape {
56    fn as_shape(&self) -> CompositionShape {
57        CompositionShape(self.0.cast().unwrap())
58    }
59}
60
61/// A shape that groups a child [`shapes`](Self::shapes) collection.
62#[derive(Clone)]
63pub struct CompositionContainerShape(pub(crate) bindings::CompositionContainerShape);
64
65impl CompositionContainerShape {
66    /// Returns the collection of child shapes.
67    pub fn shapes(&self) -> CompositionShapeCollection {
68        CompositionShapeCollection(self.0.Shapes().unwrap())
69    }
70}
71
72impl Sealed for CompositionContainerShape {}
73
74impl Shape for CompositionContainerShape {
75    fn as_shape(&self) -> CompositionShape {
76        CompositionShape(self.0.cast().unwrap())
77    }
78}
79
80/// An ordered collection of shapes owned by a [`ShapeVisual`] or a
81/// [`CompositionContainerShape`].
82#[derive(Clone)]
83pub struct CompositionShapeCollection(pub(crate) bindings::CompositionShapeCollection);
84
85impl CompositionShapeCollection {
86    /// Appends a shape to the end of the collection.
87    pub fn append(&self, shape: &impl Shape) {
88        let vector: windows_collections::IVector<bindings::CompositionShape> =
89            self.0.cast().unwrap();
90        vector.Append(&shape.as_shape().0).unwrap();
91    }
92}
93
94/// A visual that renders a collection of composition [`shapes`](Self::shapes).
95/// Derefs to [`Visual`], so a shape visual can be positioned and sized directly.
96#[derive(Clone)]
97pub struct ShapeVisual {
98    visual: Visual,
99    shape_visual: bindings::ShapeVisual,
100}
101
102impl ShapeVisual {
103    pub(crate) fn new(shape_visual: bindings::ShapeVisual) -> Self {
104        Self {
105            visual: Visual(shape_visual.cast().unwrap()),
106            shape_visual,
107        }
108    }
109
110    /// Returns the collection of shapes rendered by the visual.
111    pub fn shapes(&self) -> CompositionShapeCollection {
112        CompositionShapeCollection(self.shape_visual.Shapes().unwrap())
113    }
114}
115
116impl core::ops::Deref for ShapeVisual {
117    type Target = Visual;
118    fn deref(&self) -> &Visual {
119        &self.visual
120    }
121}