ferroui_base/media/
poly_bezier_segment.rs1use crate::media::{PathSegment, PathSegmentImpl, Points};
2use crate::platform::IGeometryContext;
3use crate::{
4 ferro_class, ferro_impl_classes, ferro_property, instantiate, DirectProperty, FerroObjectImpl, FerroProperty,
5 Point, Ref,
6};
7use std::cell::RefCell;
8
9#[repr(C)]
12pub struct PolyBezierSegment {
13 base: PathSegment,
14 points: RefCell<Option<Points>>,
15}
16
17ferro_class!(PolyBezierSegment: PathSegment);
18crate::ferro_class_info!(PolyBezierSegment { new: PolyBezierSegment::new });
19ferro_impl_classes!(PolyBezierSegment: FerroObjectImpl);
20
21impl PathSegmentImpl for PolyBezierSegment {
22 fn apply_to(this: &Self, ctx: &mut dyn IGeometryContext) {
23 let is_stroked = this.is_stroked();
24 if let Some(points) = this.points() {
25 let points = points.to_vec();
26 for curve in points.chunks_exact(3) {
29 ctx.cubic_bezier_to(curve[0], curve[1], curve[2], is_stroked);
30 }
31 }
32 }
33
34 fn to_string(this: &Self) -> String {
35 match this.points() {
36 Some(points) if !points.is_empty() => {
37 let points: Vec<String> = points.iter().map(|point| point.to_string()).collect();
38 format!("C {}", points.join(" "))
39 }
40 _ => String::new(),
41 }
42 }
43}
44
45crate::ferro_properties! { impl PolyBezierSegment {
46 ferro_property!(pub fn points_property() -> DirectProperty<PolyBezierSegment, Option<Points>> {
47 FerroProperty::register_direct::<PolyBezierSegment, _>(
48 "Points",
49 |o| o.points.borrow().clone(),
50 Some(|o, v| o.set_points(v)),
51 None,
52 )
53 });
54} }
55
56impl PolyBezierSegment {
57 pub fn construct() -> Self {
59 Self { base: PathSegment::construct(), points: RefCell::new(Some(Points::new())) }
60 }
61
62 pub fn new() -> Ref<Self> {
64 instantiate(Self::construct())
65 }
66
67 pub fn with_points(points: impl IntoIterator<Item = Point>, is_stroked: bool) -> Ref<Self> {
69 let result = Self::new();
70 result.set_points(Some(Points::from_items(points)));
71 result.set_is_stroked(is_stroked);
72 result
73 }
74
75 pub fn points(&self) -> Option<Points> {
77 self.points.borrow().clone()
78 }
79
80 pub fn set_points(&self, value: Option<Points>) {
81 self.set_and_raise(Self::points_property(), &self.points, value);
82 }
83}