rive_rs/shapes/
path_vertex.rsuse std::cell::Cell;
use crate::bones::Weight;
use crate::container_component::ContainerComponent;
use crate::core::{Core, CoreContext, Object, ObjectRef, OnAdded, Property};
use crate::math::{self, Mat};
use crate::option_cell::OptionCell;
use crate::shapes::Path;
use crate::status_code::StatusCode;
use crate::Component;
use super::CubicVertex;
#[derive(Debug, Default)]
pub struct PathVertex {
container_component: ContainerComponent,
x: Property<f32>,
y: Property<f32>,
weight: OptionCell<Object<Weight>>,
}
impl ObjectRef<'_, PathVertex> {
pub fn x(&self) -> f32 {
self.x.get()
}
pub fn set_x(&self, x: f32) {
if self.x() == x {
return;
}
self.x.set(x);
self.mark_path_dirty();
if let Some(cubic_vertex) = self.try_cast::<CubicVertex>() {
cubic_vertex.invalidate_in();
cubic_vertex.invalidate_out();
}
}
pub fn y(&self) -> f32 {
self.y.get()
}
pub fn set_y(&self, y: f32) {
if self.y() == y {
return;
}
self.y.set(y);
self.mark_path_dirty();
if let Some(cubic_vertex) = self.try_cast::<CubicVertex>() {
cubic_vertex.invalidate_in();
cubic_vertex.invalidate_out();
}
}
}
impl ObjectRef<'_, PathVertex> {
fn parent_path(&self) -> Option<Object<Path>> {
self.cast::<Component>().parent().and_then(|parent| parent.try_cast::<Path>())
}
pub(crate) fn mark_path_dirty(&self) {
if let Some(path) = self.parent_path() {
path.as_ref().mark_path_dirty();
}
}
pub fn weight(&self) -> Option<Object<Weight>> {
self.weight.get()
}
pub(crate) fn set_weight(&self, weight: Object<Weight>) {
self.weight.set(Some(weight));
}
pub fn deform(&self, world_transform: Mat, bone_transforms: &[Cell<Mat>]) {
if let Some(weight) = self.weight() {
let weight = weight.as_ref();
weight.set_translation(Weight::deform(
self.x(),
self.y(),
weight.indices() as usize,
weight.values() as usize,
world_transform,
bone_transforms,
));
}
if let Some(cubic_vertex) = self.try_cast::<CubicVertex>() {
cubic_vertex.deform(world_transform, bone_transforms);
}
}
pub fn render_translation(&self) -> math::Vec {
self.weight()
.map(|weight| weight.as_ref().translation())
.unwrap_or_else(|| math::Vec::new(self.x(), self.y()))
}
}
impl Core for PathVertex {
parent_types![(container_component, ContainerComponent)];
properties![(24, x, set_x), (25, y, set_y), container_component];
}
impl OnAdded for ObjectRef<'_, PathVertex> {
on_added!([on_added_clean, import], ContainerComponent);
fn on_added_dirty(&self, context: &dyn CoreContext) -> StatusCode {
let code = self.cast::<ContainerComponent>().on_added_dirty(context);
if code != StatusCode::Ok {
return code;
}
if let Some(path) = self.parent_path() {
path.as_ref().push_vertex(self.as_object());
StatusCode::Ok
} else {
StatusCode::MissingObject
}
}
}