Skip to main content

ferroui_base/media/
poly_line_segment.rs

1use crate::media::{PathSegment, PathSegmentImpl, Points};
2use crate::platform::IGeometryContext;
3use crate::{
4    ferro_class, ferro_property, instantiate, FerroObjectImpl, FerroObjectImplExt, FerroProperty, Point, Ref,
5    StyledProperty,
6};
7
8/// Represents a set of line segments defined by a points collection with each
9/// point specifying the end point of a line segment.
10#[repr(C)]
11pub struct PolyLineSegment {
12    base: PathSegment,
13}
14
15ferro_class!(PolyLineSegment: PathSegment);
16crate::ferro_class_info!(PolyLineSegment { new: PolyLineSegment::new });
17
18impl FerroObjectImpl for PolyLineSegment {
19    fn constructed(this: &Self) {
20        Self::parent_constructed(this);
21        this.set_points(Points::new());
22    }
23}
24
25impl PathSegmentImpl for PolyLineSegment {
26    fn apply_to(this: &Self, ctx: &mut dyn IGeometryContext) {
27        let is_stroked = this.is_stroked();
28        for point in this.points().iter() {
29            ctx.line_to(point, is_stroked);
30        }
31    }
32
33    fn to_string(this: &Self) -> String {
34        let points = this.points();
35        if points.is_empty() {
36            return String::new();
37        }
38        let points: Vec<String> = points.iter().map(|point| point.to_string()).collect();
39        format!("L {}", points.join(" "))
40    }
41}
42
43crate::ferro_properties! { impl PolyLineSegment {
44    ferro_property!(pub fn points_property() -> StyledProperty<Option<Points>> {
45        FerroProperty::register::<PolyLineSegment, _>("Points", None)
46    });
47} }
48
49impl PolyLineSegment {
50    /// Creates the class data.
51    pub fn construct() -> Self {
52        Self { base: PathSegment::construct() }
53    }
54
55    /// Creates a segment with an empty points collection.
56    pub fn new() -> Ref<Self> {
57        instantiate(Self::construct())
58    }
59
60    /// Creates a segment with a copy of the given points.
61    pub fn with_points(points: impl IntoIterator<Item = Point>) -> Ref<Self> {
62        let result = Self::new();
63        result.set_points(Points::from_items(points));
64        result
65    }
66
67    /// The points. Panics if the property has been cleared.
68    pub fn points(&self) -> Points {
69        self.get_value(Self::points_property()).expect("Points is not set")
70    }
71
72    pub fn set_points(&self, value: Points) {
73        self.set_value(Self::points_property(), Some(value))
74    }
75}