rive_rs/
drawable.rs
1use crate::core::{Core, Object, ObjectRef, OnAdded, Property};
6use crate::draw_rules::DrawRules;
7use crate::dyn_vec::DynVec;
8use crate::math::Mat;
9use crate::node::Node;
10use crate::option_cell::OptionCell;
11use crate::shapes::paint::BlendMode;
12use crate::shapes::{ClippingShape, CommandPath, CommandPathBuilder, Shape};
13use crate::Renderer;
14
15#[derive(Debug)]
16pub struct Drawable {
17 node: Node,
18 blend_mode: Property<BlendMode>,
19 drawable_flags: Property<u64>,
20 clipping_shapes: DynVec<Object<ClippingShape>>,
21 pub(crate) flattened_draw_rules: OptionCell<Object<DrawRules>>,
22 pub(crate) prev: OptionCell<Object<Self>>,
23 pub(crate) next: OptionCell<Object<Self>>,
24}
25
26impl ObjectRef<'_, Drawable> {
27 pub fn blend_mode(&self) -> BlendMode {
28 self.blend_mode.get()
29 }
30
31 pub fn set_blend_mode(&self, blend_mode: BlendMode) {
32 self.blend_mode.set(blend_mode);
33 }
34
35 pub fn drawable_flags(&self) -> u64 {
36 self.drawable_flags.get()
37 }
38
39 pub fn set_drawable_flags(&self, drawable_flags: u64) {
40 self.drawable_flags.set(drawable_flags);
41 }
42}
43
44impl ObjectRef<'_, Drawable> {
45 pub fn push_clipping_shape(&self, clipping_shape: Object<ClippingShape>) {
46 self.clipping_shapes.push(clipping_shape);
47 }
48
49 pub fn clip(&self) -> Option<CommandPath> {
50 self.clipping_shapes
51 .iter()
52 .fold(None, |mut option, clipping_shape| {
53 let builder = option.get_or_insert_with(CommandPathBuilder::new);
54
55 clipping_shape.as_ref().with_command_path(|path| {
56 if let Some(path) = path {
57 builder.path(path, None);
58 }
59 });
60
61 option
62 })
63 .map(|builder| builder.build())
64 }
65
66 pub fn draw(&self, renderer: &mut impl Renderer, transform: Mat) {
67 if let Some(shape) = self.try_cast::<Shape>() {
68 return shape.draw(renderer, transform);
69 }
70
71 unreachable!()
72 }
73}
74
75impl Core for Drawable {
76 parent_types![(node, Node)];
77
78 properties![(23, blend_mode, set_blend_mode), (129, drawable_flags, set_drawable_flags), node];
79}
80
81impl OnAdded for ObjectRef<'_, Drawable> {
82 on_added!(Node);
83}
84
85impl Default for Drawable {
86 fn default() -> Self {
87 Self {
88 node: Node::default(),
89 blend_mode: Property::new(BlendMode::SrcOver),
90 drawable_flags: Property::new(0),
91 clipping_shapes: DynVec::new(),
92 flattened_draw_rules: OptionCell::new(),
93 prev: OptionCell::new(),
94 next: OptionCell::new(),
95 }
96 }
97}