Skip to main content

ferroui_base/media/
arc_segment.rs

1use crate::media::{PathSegment, PathSegmentImpl, SweepDirection};
2use crate::platform::IGeometryContext;
3use crate::utilities::span_helpers::write_double;
4use crate::{
5    ferro_class, ferro_impl_classes, ferro_property, instantiate, FerroObjectImpl, FerroProperty, Point, Size, Ref,
6    StyledProperty,
7};
8
9/// An elliptical arc segment of a path figure.
10#[repr(C)]
11pub struct ArcSegment {
12    base: PathSegment,
13}
14
15ferro_class!(ArcSegment: PathSegment);
16crate::ferro_class_info!(ArcSegment { new: ArcSegment::new });
17ferro_impl_classes!(ArcSegment: FerroObjectImpl);
18
19impl PathSegmentImpl for ArcSegment {
20    fn apply_to(this: &Self, ctx: &mut dyn IGeometryContext) {
21        ctx.arc_to(
22            this.point(),
23            this.size(),
24            this.rotation_angle(),
25            this.is_large_arc(),
26            this.sweep_direction(),
27            this.is_stroked(),
28        );
29    }
30
31    fn to_string(this: &Self) -> String {
32        let mut rotation_angle = String::new();
33        let _ = write_double(&mut rotation_angle, this.rotation_angle());
34        format!(
35            "A {} {} {} {} {}",
36            this.size(),
37            rotation_angle,
38            if this.is_large_arc() { 1 } else { 0 },
39            this.sweep_direction() as i32,
40            this.point()
41        )
42    }
43}
44
45crate::ferro_properties! { impl ArcSegment {
46    ferro_property!(pub fn is_large_arc_property() -> StyledProperty<bool> {
47        FerroProperty::register::<ArcSegment, _>("IsLargeArc", false)
48    });
49
50    ferro_property!(pub fn point_property() -> StyledProperty<Point> {
51        FerroProperty::register::<ArcSegment, _>("Point", Point::default())
52    });
53
54    ferro_property!(pub fn rotation_angle_property() -> StyledProperty<f64> {
55        FerroProperty::register::<ArcSegment, _>("RotationAngle", 0.0)
56    });
57
58    ferro_property!(pub fn size_property() -> StyledProperty<Size> {
59        FerroProperty::register::<ArcSegment, _>("Size", Size::default())
60    });
61
62    ferro_property!(pub fn sweep_direction_property() -> StyledProperty<SweepDirection> {
63        FerroProperty::register::<ArcSegment, _>("SweepDirection", SweepDirection::Clockwise)
64    });
65} }
66
67impl ArcSegment {
68    /// Creates the class data.
69    pub fn construct() -> Self {
70        Self { base: PathSegment::construct() }
71    }
72
73    pub fn new() -> Ref<Self> {
74        instantiate(Self::construct())
75    }
76
77    /// Whether the arc should follow the longer path around an ellipse
78    /// rather than the shorter one.
79    ///
80    /// `true` to draw the arc greater than 180 degrees; otherwise, `false`.
81    pub fn is_large_arc(&self) -> bool {
82        self.get_value(Self::is_large_arc_property())
83    }
84
85    pub fn set_is_large_arc(&self, value: bool) {
86        self.set_value(Self::is_large_arc_property(), value)
87    }
88
89    /// The destination point where the arc ends.
90    pub fn point(&self) -> Point {
91        self.get_value(Self::point_property())
92    }
93
94    pub fn set_point(&self, value: Point) {
95        self.set_value(Self::point_property(), value)
96    }
97
98    /// The rotation angle (in degrees) of the ellipse that specifies the
99    /// path of the arc; positive values are clockwise.
100    ///
101    /// This will rotate the entire arc relative to the X-axis and is not
102    /// commonly used.
103    pub fn rotation_angle(&self) -> f64 {
104        self.get_value(Self::rotation_angle_property())
105    }
106
107    pub fn set_rotation_angle(&self, value: f64) {
108        self.set_value(Self::rotation_angle_property(), value)
109    }
110
111    /// The radii of the ellipse whose path is used to draw the arc.
112    pub fn size(&self) -> Size {
113        self.get_value(Self::size_property())
114    }
115
116    pub fn set_size(&self, value: Size) {
117        self.set_value(Self::size_property(), value)
118    }
119
120    /// The sweep direction which indicates whether the arc is drawn in the
121    /// Clockwise or Counterclockwise direction.
122    pub fn sweep_direction(&self) -> SweepDirection {
123        self.get_value(Self::sweep_direction_property())
124    }
125
126    pub fn set_sweep_direction(&self, value: SweepDirection) {
127        self.set_value(Self::sweep_direction_property(), value)
128    }
129}