rive_rs/shapes/
rectangle.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::rc::Rc;
6
7use crate::component::Component;
8use crate::component_dirt::ComponentDirt;
9use crate::core::{Core, Object, ObjectRef, OnAdded, Property};
10use crate::shapes::{ParametricPath, Path, StraightVertex};
11
12use super::PathVertex;
13
14#[derive(Debug)]
15pub struct Rectangle {
16    parametric_path: ParametricPath,
17    corner_radius: Property<f32>,
18    vertex1: Rc<StraightVertex>,
19    vertex2: Rc<StraightVertex>,
20    vertex3: Rc<StraightVertex>,
21    vertex4: Rc<StraightVertex>,
22}
23
24impl ObjectRef<'_, Rectangle> {
25    pub fn corner_radius(&self) -> f32 {
26        self.corner_radius.get()
27    }
28
29    pub fn set_corner_radius(&self, corner_radius: f32) {
30        self.corner_radius.set(corner_radius);
31        self.cast::<Path>().mark_path_dirty();
32    }
33}
34
35impl ObjectRef<'_, Rectangle> {
36    pub fn update(&self, value: ComponentDirt) {
37        if Component::value_has_dirt(value, ComponentDirt::PATH) {
38            let radius = self.corner_radius();
39            let parametric_path = self.cast::<ParametricPath>();
40
41            let width = parametric_path.width();
42            let height = parametric_path.height();
43
44            let ox = -parametric_path.origin_x() * width;
45            let oy = -parametric_path.origin_y() * height;
46
47            let vertex1_ref = ObjectRef::from(&*self.vertex1);
48            vertex1_ref.cast::<PathVertex>().set_x(ox);
49            vertex1_ref.cast::<PathVertex>().set_y(oy);
50            vertex1_ref.set_radius(radius);
51
52            let vertex2_ref = ObjectRef::from(&*self.vertex2);
53            vertex2_ref.cast::<PathVertex>().set_x(ox + width);
54            vertex2_ref.cast::<PathVertex>().set_y(oy);
55            vertex2_ref.set_radius(radius);
56
57            let vertex3_ref = ObjectRef::from(&*self.vertex3);
58            vertex3_ref.cast::<PathVertex>().set_x(ox + width);
59            vertex3_ref.cast::<PathVertex>().set_y(oy + height);
60            vertex3_ref.set_radius(radius);
61
62            let vertex4_ref = ObjectRef::from(&*self.vertex4);
63            vertex4_ref.cast::<PathVertex>().set_x(ox);
64            vertex4_ref.cast::<PathVertex>().set_y(oy + height);
65            vertex4_ref.set_radius(radius);
66        }
67
68        self.cast::<Path>().update(value);
69    }
70}
71
72impl Core for Rectangle {
73    parent_types![(parametric_path, ParametricPath)];
74
75    properties![(31, corner_radius, set_corner_radius), parametric_path];
76}
77
78impl OnAdded for ObjectRef<'_, Rectangle> {
79    on_added!(ParametricPath);
80}
81
82impl Default for Rectangle {
83    fn default() -> Self {
84        let rectangle = Self {
85            parametric_path: ParametricPath::default(),
86            corner_radius: Property::new(0.0),
87            vertex1: Rc::new(StraightVertex::default()),
88            vertex2: Rc::new(StraightVertex::default()),
89            vertex3: Rc::new(StraightVertex::default()),
90            vertex4: Rc::new(StraightVertex::default()),
91        };
92
93        let rectangle_ref = ObjectRef::from(&rectangle);
94        let path = rectangle_ref.cast::<Path>();
95
96        path.push_vertex(Object::new(&(rectangle.vertex1.clone() as Rc<dyn Core>)));
97        path.push_vertex(Object::new(&(rectangle.vertex2.clone() as Rc<dyn Core>)));
98        path.push_vertex(Object::new(&(rectangle.vertex3.clone() as Rc<dyn Core>)));
99        path.push_vertex(Object::new(&(rectangle.vertex4.clone() as Rc<dyn Core>)));
100
101        rectangle
102    }
103}