use core::ptr::NonNull;
use std::ffi::{CStr, CString, c_void};
use crate::ffi::{
noesis_animation_begin_on, noesis_animation_set_easing_function, noesis_base_component_release,
noesis_color_animation_add_keyframe, noesis_color_animation_create,
noesis_color_animation_keyframes_create, noesis_color_animation_set_by,
noesis_color_animation_set_from, noesis_color_animation_set_to,
noesis_double_animation_add_keyframe, noesis_double_animation_create,
noesis_double_animation_keyframes_create, noesis_double_animation_set_by,
noesis_double_animation_set_from, noesis_double_animation_set_to,
noesis_easing_function_create, noesis_easing_function_set_amplitude,
noesis_easing_function_set_exponent, noesis_easing_function_set_oscillations,
noesis_easing_function_set_power, noesis_easing_function_set_springiness,
noesis_point_animation_create, noesis_point_animation_set_by, noesis_point_animation_set_from,
noesis_point_animation_set_to, noesis_storyboard_add_child, noesis_storyboard_begin,
noesis_storyboard_begin_handoff, noesis_storyboard_child_count, noesis_storyboard_create,
noesis_storyboard_is_paused, noesis_storyboard_is_playing, noesis_storyboard_pause,
noesis_storyboard_resume, noesis_storyboard_seek, noesis_storyboard_set_target_name,
noesis_storyboard_set_target_property, noesis_storyboard_stop,
noesis_thickness_animation_create, noesis_thickness_animation_set_by,
noesis_thickness_animation_set_from, noesis_thickness_animation_set_to,
noesis_timeline_get_duration_seconds, noesis_timeline_set_auto_reverse,
noesis_timeline_set_begin_time_seconds, noesis_timeline_set_duration_auto,
noesis_timeline_set_duration_forever, noesis_timeline_set_duration_seconds,
noesis_timeline_set_fill_behavior, noesis_timeline_set_repeat_count,
noesis_timeline_set_repeat_duration, noesis_timeline_set_repeat_forever,
noesis_timeline_set_speed_ratio,
};
use crate::ffi::{
noesis_animation_begin_storyboard_create, noesis_animation_begin_storyboard_get_handoff,
noesis_animation_begin_storyboard_get_name, noesis_animation_begin_storyboard_get_storyboard,
noesis_animation_begin_storyboard_set_handoff, noesis_animation_begin_storyboard_set_name,
noesis_animation_begin_storyboard_set_storyboard, noesis_animation_int16_animation_create,
noesis_animation_int16_animation_get_by, noesis_animation_int16_animation_get_from,
noesis_animation_int16_animation_get_to, noesis_animation_int16_animation_set_by,
noesis_animation_int16_animation_set_from, noesis_animation_int16_animation_set_to,
noesis_animation_int16_keyframes_add, noesis_animation_int16_keyframes_count,
noesis_animation_int16_keyframes_create, noesis_animation_int16_keyframes_get_key_time,
noesis_animation_int16_keyframes_get_value, noesis_animation_int32_animation_create,
noesis_animation_int32_animation_get_by, noesis_animation_int32_animation_get_from,
noesis_animation_int32_animation_get_to, noesis_animation_int32_animation_set_by,
noesis_animation_int32_animation_set_from, noesis_animation_int32_animation_set_to,
noesis_animation_int32_keyframes_add, noesis_animation_int32_keyframes_count,
noesis_animation_int32_keyframes_create, noesis_animation_int32_keyframes_get_key_time,
noesis_animation_int32_keyframes_get_value, noesis_animation_int64_animation_create,
noesis_animation_int64_animation_get_by, noesis_animation_int64_animation_get_from,
noesis_animation_int64_animation_get_to, noesis_animation_int64_animation_set_by,
noesis_animation_int64_animation_set_from, noesis_animation_int64_animation_set_to,
noesis_animation_int64_keyframes_add, noesis_animation_int64_keyframes_count,
noesis_animation_int64_keyframes_create, noesis_animation_int64_keyframes_get_key_time,
noesis_animation_int64_keyframes_get_value, noesis_animation_keyspline_create,
noesis_animation_keyspline_get_control_point1, noesis_animation_keyspline_get_control_point2,
noesis_animation_keyspline_set_control_point1, noesis_animation_keyspline_set_control_point2,
noesis_animation_matrix_keyframes_add, noesis_animation_matrix_keyframes_count,
noesis_animation_matrix_keyframes_create, noesis_animation_matrix_keyframes_get_key_time,
noesis_animation_matrix_keyframes_get_value, noesis_animation_object_keyframes_add,
noesis_animation_object_keyframes_count, noesis_animation_object_keyframes_create,
noesis_animation_object_keyframes_get_key_time, noesis_animation_object_keyframes_get_value,
noesis_animation_rect_animation_create, noesis_animation_rect_animation_get_by,
noesis_animation_rect_animation_get_from, noesis_animation_rect_animation_get_to,
noesis_animation_rect_animation_set_by, noesis_animation_rect_animation_set_from,
noesis_animation_rect_animation_set_to, noesis_animation_rect_keyframes_add,
noesis_animation_rect_keyframes_count, noesis_animation_rect_keyframes_create,
noesis_animation_rect_keyframes_get_key_time, noesis_animation_rect_keyframes_get_value,
noesis_animation_size_animation_create, noesis_animation_size_animation_get_by,
noesis_animation_size_animation_get_from, noesis_animation_size_animation_get_to,
noesis_animation_size_animation_set_by, noesis_animation_size_animation_set_from,
noesis_animation_size_animation_set_to, noesis_animation_size_keyframes_add,
noesis_animation_size_keyframes_count, noesis_animation_size_keyframes_create,
noesis_animation_size_keyframes_get_key_time, noesis_animation_size_keyframes_get_value,
};
use crate::ffi::{
noesis_animation_boolean_keyframes_add, noesis_animation_boolean_keyframes_count,
noesis_animation_boolean_keyframes_create, noesis_animation_boolean_keyframes_get_key_time,
noesis_animation_boolean_keyframes_get_value, noesis_animation_parallel_timeline_add_child,
noesis_animation_parallel_timeline_child_count, noesis_animation_parallel_timeline_create,
noesis_animation_point_keyframes_add, noesis_animation_point_keyframes_count,
noesis_animation_point_keyframes_create, noesis_animation_point_keyframes_get_key_time,
noesis_animation_point_keyframes_get_value, noesis_animation_string_keyframes_add,
noesis_animation_string_keyframes_count, noesis_animation_string_keyframes_create,
noesis_animation_string_keyframes_get_key_time, noesis_animation_string_keyframes_get_value,
noesis_animation_thickness_keyframes_add, noesis_animation_thickness_keyframes_count,
noesis_animation_thickness_keyframes_create, noesis_animation_thickness_keyframes_get_key_time,
noesis_animation_thickness_keyframes_get_value,
};
use crate::view::FrameworkElement;
#[repr(i32)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum EasingMode {
EaseOut = 0,
EaseIn = 1,
EaseInOut = 2,
}
#[repr(i32)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum EasingKind {
Quadratic = 0,
Cubic = 1,
Quartic = 2,
Quintic = 3,
Sine = 4,
Circle = 5,
Back = 6,
Bounce = 7,
Elastic = 8,
Exponential = 9,
Power = 10,
}
#[repr(i32)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum FillBehavior {
HoldEnd = 0,
Stop = 1,
}
#[repr(i32)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum HandoffBehavior {
SnapshotAndReplace = 0,
Compose = 1,
}
#[repr(i32)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum KeyFrameKind {
Discrete = 0,
Linear = 1,
Easing = 2,
Spline = 3,
}
#[derive(Copy, Clone)]
pub enum KeyFrameInterp<'a> {
None,
Easing(&'a EasingFunction),
Spline(&'a KeySpline),
}
impl KeyFrameInterp<'_> {
fn raw(self) -> *mut c_void {
match self {
KeyFrameInterp::None => core::ptr::null_mut(),
KeyFrameInterp::Easing(e) => e.raw(),
KeyFrameInterp::Spline(s) => s.raw(),
}
}
}
pub trait AsComponent {
fn component_raw(&self) -> *mut c_void;
}
macro_rules! base_component_handle {
($name:ident) => {
unsafe impl Send for $name {}
impl $name {
#[must_use]
pub fn raw(&self) -> *mut c_void {
self.ptr.as_ptr()
}
}
impl AsComponent for $name {
fn component_raw(&self) -> *mut c_void {
self.ptr.as_ptr()
}
}
impl Drop for $name {
fn drop(&mut self) {
unsafe { noesis_base_component_release(self.ptr.as_ptr()) }
}
}
};
}
pub trait Timeline {
fn timeline_raw(&self) -> *mut c_void;
fn set_duration_secs(&mut self, seconds: f64) -> bool {
unsafe { noesis_timeline_set_duration_seconds(self.timeline_raw(), seconds) }
}
fn set_duration_auto(&mut self) -> bool {
unsafe { noesis_timeline_set_duration_auto(self.timeline_raw()) }
}
fn set_duration_forever(&mut self) -> bool {
unsafe { noesis_timeline_set_duration_forever(self.timeline_raw()) }
}
fn duration_secs(&self) -> Option<f64> {
let s = unsafe { noesis_timeline_get_duration_seconds(self.timeline_raw()) };
(s >= 0.0).then_some(s)
}
fn set_begin_time_secs(&mut self, seconds: f64) -> bool {
unsafe { noesis_timeline_set_begin_time_seconds(self.timeline_raw(), seconds) }
}
fn set_auto_reverse(&mut self, value: bool) -> bool {
unsafe { noesis_timeline_set_auto_reverse(self.timeline_raw(), value) }
}
fn set_speed_ratio(&mut self, value: f32) -> bool {
unsafe { noesis_timeline_set_speed_ratio(self.timeline_raw(), value) }
}
fn set_fill_behavior(&mut self, behavior: FillBehavior) -> bool {
unsafe { noesis_timeline_set_fill_behavior(self.timeline_raw(), behavior as i32) }
}
fn set_repeat_count(&mut self, count: f32) -> bool {
unsafe { noesis_timeline_set_repeat_count(self.timeline_raw(), count) }
}
fn set_repeat_duration_secs(&mut self, seconds: f64) -> bool {
unsafe { noesis_timeline_set_repeat_duration(self.timeline_raw(), seconds) }
}
fn set_repeat_forever(&mut self) -> bool {
unsafe { noesis_timeline_set_repeat_forever(self.timeline_raw()) }
}
}
pub trait Animation: Timeline {
fn animation_raw(&self) -> *mut c_void;
fn set_target_name(&mut self, name: &str) -> bool {
let c = CString::new(name).expect("target name contained interior NUL");
unsafe { noesis_storyboard_set_target_name(self.animation_raw(), c.as_ptr()) }
}
fn set_target_property(&mut self, path: &str) -> bool {
let c = CString::new(path).expect("target property contained interior NUL");
unsafe { noesis_storyboard_set_target_property(self.animation_raw(), c.as_ptr()) }
}
fn set_easing(&mut self, easing: &EasingFunction) -> bool {
unsafe { noesis_animation_set_easing_function(self.animation_raw(), easing.raw()) }
}
fn begin_on(
&mut self,
target: &FrameworkElement,
dp_name: &str,
handoff: HandoffBehavior,
) -> bool {
let c = CString::new(dp_name).expect("dp name contained interior NUL");
unsafe {
noesis_animation_begin_on(
self.animation_raw(),
target.raw(),
c.as_ptr(),
handoff as i32,
)
}
}
}
pub struct Storyboard {
ptr: NonNull<c_void>,
}
base_component_handle!(Storyboard);
impl Timeline for Storyboard {
fn timeline_raw(&self) -> *mut c_void {
self.raw()
}
}
impl Default for Storyboard {
fn default() -> Self {
Self::new()
}
}
impl Storyboard {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_storyboard_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_storyboard_create returned null"),
}
}
pub fn add_child<A: Animation>(&mut self, anim: &A) -> bool {
unsafe { noesis_storyboard_add_child(self.raw(), anim.animation_raw()) }
}
#[must_use]
pub fn child_count(&self) -> Option<u32> {
let n = unsafe { noesis_storyboard_child_count(self.raw()) };
u32::try_from(n).ok()
}
pub fn begin(&mut self, root: &FrameworkElement, controllable: bool) -> bool {
unsafe { noesis_storyboard_begin(self.raw(), root.raw(), controllable) }
}
pub fn begin_with_handoff(
&mut self,
root: &FrameworkElement,
handoff: HandoffBehavior,
controllable: bool,
) -> bool {
unsafe {
noesis_storyboard_begin_handoff(self.raw(), root.raw(), handoff as i32, controllable)
}
}
pub fn pause(&mut self, root: &FrameworkElement) -> bool {
unsafe { noesis_storyboard_pause(self.raw(), root.raw()) }
}
pub fn resume(&mut self, root: &FrameworkElement) -> bool {
unsafe { noesis_storyboard_resume(self.raw(), root.raw()) }
}
pub fn stop(&mut self, root: &FrameworkElement) -> bool {
unsafe { noesis_storyboard_stop(self.raw(), root.raw()) }
}
pub fn seek(&mut self, root: &FrameworkElement, seconds: f64) -> bool {
unsafe { noesis_storyboard_seek(self.raw(), root.raw(), seconds) }
}
#[must_use]
pub fn is_playing(&self, root: &FrameworkElement) -> bool {
unsafe { noesis_storyboard_is_playing(self.raw(), root.raw()) }
}
#[must_use]
pub fn is_paused(&self, root: &FrameworkElement) -> bool {
unsafe { noesis_storyboard_is_paused(self.raw(), root.raw()) }
}
}
pub struct EasingFunction {
ptr: NonNull<c_void>,
}
base_component_handle!(EasingFunction);
impl EasingFunction {
#[must_use]
pub fn new(kind: EasingKind, mode: EasingMode) -> Self {
let ptr = unsafe { noesis_easing_function_create(kind as i32, mode as i32) };
Self {
ptr: NonNull::new(ptr).expect("noesis_easing_function_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_amplitude(&mut self, value: f32) -> bool {
unsafe { noesis_easing_function_set_amplitude(self.raw(), value) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_power(&mut self, value: f32) -> bool {
unsafe { noesis_easing_function_set_power(self.raw(), value) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_exponent(&mut self, value: f32) -> bool {
unsafe { noesis_easing_function_set_exponent(self.raw(), value) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_oscillations(&mut self, value: i32) -> bool {
unsafe { noesis_easing_function_set_oscillations(self.raw(), value) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_springiness(&mut self, value: f32) -> bool {
unsafe { noesis_easing_function_set_springiness(self.raw(), value) }
}
}
macro_rules! animation_impls {
($name:ident) => {
base_component_handle!($name);
impl Timeline for $name {
fn timeline_raw(&self) -> *mut c_void {
self.raw()
}
}
impl Animation for $name {
fn animation_raw(&self) -> *mut c_void {
self.raw()
}
}
};
}
pub struct DoubleAnimation {
ptr: NonNull<c_void>,
}
animation_impls!(DoubleAnimation);
impl Default for DoubleAnimation {
fn default() -> Self {
Self::new()
}
}
impl DoubleAnimation {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_double_animation_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_double_animation_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_from(&mut self, value: Option<f32>) -> bool {
unsafe {
noesis_double_animation_set_from(self.raw(), value.is_some(), value.unwrap_or(0.0))
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_to(&mut self, value: Option<f32>) -> bool {
unsafe { noesis_double_animation_set_to(self.raw(), value.is_some(), value.unwrap_or(0.0)) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_by(&mut self, value: Option<f32>) -> bool {
unsafe { noesis_double_animation_set_by(self.raw(), value.is_some(), value.unwrap_or(0.0)) }
}
}
pub struct ColorAnimation {
ptr: NonNull<c_void>,
}
animation_impls!(ColorAnimation);
impl Default for ColorAnimation {
fn default() -> Self {
Self::new()
}
}
impl ColorAnimation {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_color_animation_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_color_animation_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_from(&mut self, rgba: Option<[f32; 4]>) -> bool {
let v = rgba.unwrap_or([0.0; 4]);
unsafe { noesis_color_animation_set_from(self.raw(), rgba.is_some(), v.as_ptr()) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_to(&mut self, rgba: Option<[f32; 4]>) -> bool {
let v = rgba.unwrap_or([0.0; 4]);
unsafe { noesis_color_animation_set_to(self.raw(), rgba.is_some(), v.as_ptr()) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_by(&mut self, rgba: Option<[f32; 4]>) -> bool {
let v = rgba.unwrap_or([0.0; 4]);
unsafe { noesis_color_animation_set_by(self.raw(), rgba.is_some(), v.as_ptr()) }
}
}
pub struct ThicknessAnimation {
ptr: NonNull<c_void>,
}
animation_impls!(ThicknessAnimation);
impl Default for ThicknessAnimation {
fn default() -> Self {
Self::new()
}
}
impl ThicknessAnimation {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_thickness_animation_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_thickness_animation_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_from(&mut self, value: Option<[f32; 4]>) -> bool {
let v = value.unwrap_or([0.0; 4]);
unsafe { noesis_thickness_animation_set_from(self.raw(), value.is_some(), v.as_ptr()) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_to(&mut self, value: Option<[f32; 4]>) -> bool {
let v = value.unwrap_or([0.0; 4]);
unsafe { noesis_thickness_animation_set_to(self.raw(), value.is_some(), v.as_ptr()) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_by(&mut self, value: Option<[f32; 4]>) -> bool {
let v = value.unwrap_or([0.0; 4]);
unsafe { noesis_thickness_animation_set_by(self.raw(), value.is_some(), v.as_ptr()) }
}
}
pub struct PointAnimation {
ptr: NonNull<c_void>,
}
animation_impls!(PointAnimation);
impl Default for PointAnimation {
fn default() -> Self {
Self::new()
}
}
impl PointAnimation {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_point_animation_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_point_animation_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_from(&mut self, value: Option<(f32, f32)>) -> bool {
let (x, y) = value.unwrap_or((0.0, 0.0));
unsafe { noesis_point_animation_set_from(self.raw(), value.is_some(), x, y) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_to(&mut self, value: Option<(f32, f32)>) -> bool {
let (x, y) = value.unwrap_or((0.0, 0.0));
unsafe { noesis_point_animation_set_to(self.raw(), value.is_some(), x, y) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_by(&mut self, value: Option<(f32, f32)>) -> bool {
let (x, y) = value.unwrap_or((0.0, 0.0));
unsafe { noesis_point_animation_set_by(self.raw(), value.is_some(), x, y) }
}
}
pub struct DoubleAnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(DoubleAnimationUsingKeyFrames);
impl Default for DoubleAnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl DoubleAnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_double_animation_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_double_animation_keyframes_create returned null"),
}
}
pub fn add_key_frame(
&mut self,
kind: KeyFrameKind,
key_time_secs: f64,
value: f32,
interp: KeyFrameInterp,
) -> bool {
unsafe {
noesis_double_animation_add_keyframe(
self.raw(),
kind as i32,
key_time_secs,
value,
interp.raw(),
)
}
}
}
pub struct ColorAnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(ColorAnimationUsingKeyFrames);
impl Default for ColorAnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl ColorAnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_color_animation_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_color_animation_keyframes_create returned null"),
}
}
pub fn add_key_frame(
&mut self,
kind: KeyFrameKind,
key_time_secs: f64,
rgba: [f32; 4],
interp: KeyFrameInterp,
) -> bool {
unsafe {
noesis_color_animation_add_keyframe(
self.raw(),
kind as i32,
key_time_secs,
rgba.as_ptr(),
interp.raw(),
)
}
}
}
pub struct RectAnimation {
ptr: NonNull<c_void>,
}
animation_impls!(RectAnimation);
impl Default for RectAnimation {
fn default() -> Self {
Self::new()
}
}
impl RectAnimation {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_rect_animation_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_rect_animation_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_from(&mut self, value: Option<[f32; 4]>) -> bool {
let v = value.unwrap_or([0.0; 4]);
unsafe { noesis_animation_rect_animation_set_from(self.raw(), value.is_some(), v.as_ptr()) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_to(&mut self, value: Option<[f32; 4]>) -> bool {
let v = value.unwrap_or([0.0; 4]);
unsafe { noesis_animation_rect_animation_set_to(self.raw(), value.is_some(), v.as_ptr()) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_by(&mut self, value: Option<[f32; 4]>) -> bool {
let v = value.unwrap_or([0.0; 4]);
unsafe { noesis_animation_rect_animation_set_by(self.raw(), value.is_some(), v.as_ptr()) }
}
#[must_use]
pub fn from(&self) -> Option<[f32; 4]> {
let mut out = [0.0f32; 4];
let has = unsafe { noesis_animation_rect_animation_get_from(self.raw(), out.as_mut_ptr()) };
has.then_some(out)
}
#[must_use]
pub fn to(&self) -> Option<[f32; 4]> {
let mut out = [0.0f32; 4];
let has = unsafe { noesis_animation_rect_animation_get_to(self.raw(), out.as_mut_ptr()) };
has.then_some(out)
}
#[must_use]
pub fn by(&self) -> Option<[f32; 4]> {
let mut out = [0.0f32; 4];
let has = unsafe { noesis_animation_rect_animation_get_by(self.raw(), out.as_mut_ptr()) };
has.then_some(out)
}
}
pub struct SizeAnimation {
ptr: NonNull<c_void>,
}
animation_impls!(SizeAnimation);
impl Default for SizeAnimation {
fn default() -> Self {
Self::new()
}
}
impl SizeAnimation {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_size_animation_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_size_animation_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_from(&mut self, value: Option<[f32; 2]>) -> bool {
let v = value.unwrap_or([0.0; 2]);
unsafe { noesis_animation_size_animation_set_from(self.raw(), value.is_some(), v.as_ptr()) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_to(&mut self, value: Option<[f32; 2]>) -> bool {
let v = value.unwrap_or([0.0; 2]);
unsafe { noesis_animation_size_animation_set_to(self.raw(), value.is_some(), v.as_ptr()) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_by(&mut self, value: Option<[f32; 2]>) -> bool {
let v = value.unwrap_or([0.0; 2]);
unsafe { noesis_animation_size_animation_set_by(self.raw(), value.is_some(), v.as_ptr()) }
}
#[must_use]
pub fn from(&self) -> Option<[f32; 2]> {
let mut out = [0.0f32; 2];
let has = unsafe { noesis_animation_size_animation_get_from(self.raw(), out.as_mut_ptr()) };
has.then_some(out)
}
#[must_use]
pub fn to(&self) -> Option<[f32; 2]> {
let mut out = [0.0f32; 2];
let has = unsafe { noesis_animation_size_animation_get_to(self.raw(), out.as_mut_ptr()) };
has.then_some(out)
}
#[must_use]
pub fn by(&self) -> Option<[f32; 2]> {
let mut out = [0.0f32; 2];
let has = unsafe { noesis_animation_size_animation_get_by(self.raw(), out.as_mut_ptr()) };
has.then_some(out)
}
}
pub struct Int16Animation {
ptr: NonNull<c_void>,
}
animation_impls!(Int16Animation);
impl Default for Int16Animation {
fn default() -> Self {
Self::new()
}
}
impl Int16Animation {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_int16_animation_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_int16_animation_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_from(&mut self, value: Option<i16>) -> bool {
unsafe {
noesis_animation_int16_animation_set_from(
self.raw(),
value.is_some(),
i32::from(value.unwrap_or(0)),
)
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_to(&mut self, value: Option<i16>) -> bool {
unsafe {
noesis_animation_int16_animation_set_to(
self.raw(),
value.is_some(),
i32::from(value.unwrap_or(0)),
)
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_by(&mut self, value: Option<i16>) -> bool {
unsafe {
noesis_animation_int16_animation_set_by(
self.raw(),
value.is_some(),
i32::from(value.unwrap_or(0)),
)
}
}
#[must_use]
pub fn from(&self) -> Option<i16> {
let mut out = 0i32;
let has = unsafe { noesis_animation_int16_animation_get_from(self.raw(), &mut out) };
has.then_some(out as i16)
}
#[must_use]
pub fn to(&self) -> Option<i16> {
let mut out = 0i32;
let has = unsafe { noesis_animation_int16_animation_get_to(self.raw(), &mut out) };
has.then_some(out as i16)
}
#[must_use]
pub fn by(&self) -> Option<i16> {
let mut out = 0i32;
let has = unsafe { noesis_animation_int16_animation_get_by(self.raw(), &mut out) };
has.then_some(out as i16)
}
}
pub struct Int32Animation {
ptr: NonNull<c_void>,
}
animation_impls!(Int32Animation);
impl Default for Int32Animation {
fn default() -> Self {
Self::new()
}
}
impl Int32Animation {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_int32_animation_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_int32_animation_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_from(&mut self, value: Option<i32>) -> bool {
unsafe {
noesis_animation_int32_animation_set_from(
self.raw(),
value.is_some(),
value.unwrap_or(0),
)
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_to(&mut self, value: Option<i32>) -> bool {
unsafe {
noesis_animation_int32_animation_set_to(self.raw(), value.is_some(), value.unwrap_or(0))
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_by(&mut self, value: Option<i32>) -> bool {
unsafe {
noesis_animation_int32_animation_set_by(self.raw(), value.is_some(), value.unwrap_or(0))
}
}
#[must_use]
pub fn from(&self) -> Option<i32> {
let mut out = 0i32;
let has = unsafe { noesis_animation_int32_animation_get_from(self.raw(), &mut out) };
has.then_some(out)
}
#[must_use]
pub fn to(&self) -> Option<i32> {
let mut out = 0i32;
let has = unsafe { noesis_animation_int32_animation_get_to(self.raw(), &mut out) };
has.then_some(out)
}
#[must_use]
pub fn by(&self) -> Option<i32> {
let mut out = 0i32;
let has = unsafe { noesis_animation_int32_animation_get_by(self.raw(), &mut out) };
has.then_some(out)
}
}
pub struct Int64Animation {
ptr: NonNull<c_void>,
}
animation_impls!(Int64Animation);
impl Default for Int64Animation {
fn default() -> Self {
Self::new()
}
}
impl Int64Animation {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_int64_animation_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_int64_animation_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_from(&mut self, value: Option<i64>) -> bool {
unsafe {
noesis_animation_int64_animation_set_from(
self.raw(),
value.is_some(),
value.unwrap_or(0),
)
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_to(&mut self, value: Option<i64>) -> bool {
unsafe {
noesis_animation_int64_animation_set_to(self.raw(), value.is_some(), value.unwrap_or(0))
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_by(&mut self, value: Option<i64>) -> bool {
unsafe {
noesis_animation_int64_animation_set_by(self.raw(), value.is_some(), value.unwrap_or(0))
}
}
#[must_use]
pub fn from(&self) -> Option<i64> {
let mut out = 0i64;
let has = unsafe { noesis_animation_int64_animation_get_from(self.raw(), &mut out) };
has.then_some(out)
}
#[must_use]
pub fn to(&self) -> Option<i64> {
let mut out = 0i64;
let has = unsafe { noesis_animation_int64_animation_get_to(self.raw(), &mut out) };
has.then_some(out)
}
#[must_use]
pub fn by(&self) -> Option<i64> {
let mut out = 0i64;
let has = unsafe { noesis_animation_int64_animation_get_by(self.raw(), &mut out) };
has.then_some(out)
}
}
pub struct KeySpline {
ptr: NonNull<c_void>,
}
base_component_handle!(KeySpline);
impl KeySpline {
#[must_use]
pub fn new(control_point1: (f32, f32), control_point2: (f32, f32)) -> Self {
let ptr = unsafe {
noesis_animation_keyspline_create(
control_point1.0,
control_point1.1,
control_point2.0,
control_point2.1,
)
};
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_keyspline_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_control_point1(&mut self, x: f32, y: f32) -> bool {
unsafe { noesis_animation_keyspline_set_control_point1(self.raw(), x, y) }
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_control_point2(&mut self, x: f32, y: f32) -> bool {
unsafe { noesis_animation_keyspline_set_control_point2(self.raw(), x, y) }
}
#[must_use]
pub fn control_point1(&self) -> Option<(f32, f32)> {
let mut out = [0.0f32; 2];
let ok =
unsafe { noesis_animation_keyspline_get_control_point1(self.raw(), out.as_mut_ptr()) };
ok.then_some((out[0], out[1]))
}
#[must_use]
pub fn control_point2(&self) -> Option<(f32, f32)> {
let mut out = [0.0f32; 2];
let ok =
unsafe { noesis_animation_keyspline_get_control_point2(self.raw(), out.as_mut_ptr()) };
ok.then_some((out[0], out[1]))
}
}
pub struct RectAnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(RectAnimationUsingKeyFrames);
impl Default for RectAnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl RectAnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_rect_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_rect_keyframes_create returned null"),
}
}
pub fn add_key_frame(
&mut self,
kind: KeyFrameKind,
key_time_secs: f64,
value: [f32; 4],
interp: KeyFrameInterp,
) -> bool {
unsafe {
noesis_animation_rect_keyframes_add(
self.raw(),
kind as i32,
key_time_secs,
value.as_ptr(),
interp.raw(),
)
}
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_rect_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<[f32; 4]> {
let mut out = [0.0f32; 4];
let ok = unsafe {
noesis_animation_rect_keyframes_get_value(self.raw(), index as i32, out.as_mut_ptr())
};
ok.then_some(out)
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t = unsafe { noesis_animation_rect_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct SizeAnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(SizeAnimationUsingKeyFrames);
impl Default for SizeAnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl SizeAnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_size_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_size_keyframes_create returned null"),
}
}
pub fn add_key_frame(
&mut self,
kind: KeyFrameKind,
key_time_secs: f64,
value: [f32; 2],
interp: KeyFrameInterp,
) -> bool {
unsafe {
noesis_animation_size_keyframes_add(
self.raw(),
kind as i32,
key_time_secs,
value.as_ptr(),
interp.raw(),
)
}
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_size_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<[f32; 2]> {
let mut out = [0.0f32; 2];
let ok = unsafe {
noesis_animation_size_keyframes_get_value(self.raw(), index as i32, out.as_mut_ptr())
};
ok.then_some(out)
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t = unsafe { noesis_animation_size_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct Int16AnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(Int16AnimationUsingKeyFrames);
impl Default for Int16AnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl Int16AnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_int16_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_int16_keyframes_create returned null"),
}
}
pub fn add_key_frame(
&mut self,
kind: KeyFrameKind,
key_time_secs: f64,
value: i16,
interp: KeyFrameInterp,
) -> bool {
unsafe {
noesis_animation_int16_keyframes_add(
self.raw(),
kind as i32,
key_time_secs,
i32::from(value),
interp.raw(),
)
}
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_int16_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<i16> {
let mut out = 0i32;
let ok = unsafe {
noesis_animation_int16_keyframes_get_value(self.raw(), index as i32, &mut out)
};
ok.then_some(out as i16)
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t = unsafe { noesis_animation_int16_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct Int32AnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(Int32AnimationUsingKeyFrames);
impl Default for Int32AnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl Int32AnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_int32_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_int32_keyframes_create returned null"),
}
}
pub fn add_key_frame(
&mut self,
kind: KeyFrameKind,
key_time_secs: f64,
value: i32,
interp: KeyFrameInterp,
) -> bool {
unsafe {
noesis_animation_int32_keyframes_add(
self.raw(),
kind as i32,
key_time_secs,
value,
interp.raw(),
)
}
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_int32_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<i32> {
let mut out = 0i32;
let ok = unsafe {
noesis_animation_int32_keyframes_get_value(self.raw(), index as i32, &mut out)
};
ok.then_some(out)
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t = unsafe { noesis_animation_int32_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct Int64AnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(Int64AnimationUsingKeyFrames);
impl Default for Int64AnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl Int64AnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_int64_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_int64_keyframes_create returned null"),
}
}
pub fn add_key_frame(
&mut self,
kind: KeyFrameKind,
key_time_secs: f64,
value: i64,
interp: KeyFrameInterp,
) -> bool {
unsafe {
noesis_animation_int64_keyframes_add(
self.raw(),
kind as i32,
key_time_secs,
value,
interp.raw(),
)
}
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_int64_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<i64> {
let mut out = 0i64;
let ok = unsafe {
noesis_animation_int64_keyframes_get_value(self.raw(), index as i32, &mut out)
};
ok.then_some(out)
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t = unsafe { noesis_animation_int64_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct PointAnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(PointAnimationUsingKeyFrames);
impl Default for PointAnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl PointAnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_point_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_point_keyframes_create returned null"),
}
}
pub fn add_key_frame(
&mut self,
kind: KeyFrameKind,
key_time_secs: f64,
value: (f32, f32),
interp: KeyFrameInterp,
) -> bool {
let p = [value.0, value.1];
unsafe {
noesis_animation_point_keyframes_add(
self.raw(),
kind as i32,
key_time_secs,
p.as_ptr(),
interp.raw(),
)
}
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_point_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<(f32, f32)> {
let mut out = [0.0f32; 2];
let ok = unsafe {
noesis_animation_point_keyframes_get_value(self.raw(), index as i32, out.as_mut_ptr())
};
ok.then_some((out[0], out[1]))
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t = unsafe { noesis_animation_point_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct ThicknessAnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(ThicknessAnimationUsingKeyFrames);
impl Default for ThicknessAnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl ThicknessAnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_thickness_keyframes_create() };
Self {
ptr: NonNull::new(ptr)
.expect("noesis_animation_thickness_keyframes_create returned null"),
}
}
pub fn add_key_frame(
&mut self,
kind: KeyFrameKind,
key_time_secs: f64,
value: [f32; 4],
interp: KeyFrameInterp,
) -> bool {
unsafe {
noesis_animation_thickness_keyframes_add(
self.raw(),
kind as i32,
key_time_secs,
value.as_ptr(),
interp.raw(),
)
}
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_thickness_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<[f32; 4]> {
let mut out = [0.0f32; 4];
let ok = unsafe {
noesis_animation_thickness_keyframes_get_value(
self.raw(),
index as i32,
out.as_mut_ptr(),
)
};
ok.then_some(out)
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t =
unsafe { noesis_animation_thickness_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct BooleanAnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(BooleanAnimationUsingKeyFrames);
impl Default for BooleanAnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl BooleanAnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_boolean_keyframes_create() };
Self {
ptr: NonNull::new(ptr)
.expect("noesis_animation_boolean_keyframes_create returned null"),
}
}
pub fn add_key_frame(&mut self, key_time_secs: f64, value: bool) -> bool {
unsafe { noesis_animation_boolean_keyframes_add(self.raw(), key_time_secs, value) }
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_boolean_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<bool> {
let mut out = false;
let ok = unsafe {
noesis_animation_boolean_keyframes_get_value(self.raw(), index as i32, &mut out)
};
ok.then_some(out)
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t =
unsafe { noesis_animation_boolean_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct StringAnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(StringAnimationUsingKeyFrames);
impl Default for StringAnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl StringAnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_string_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_string_keyframes_create returned null"),
}
}
pub fn add_key_frame(&mut self, key_time_secs: f64, value: &str) -> bool {
let c = CString::new(value).expect("key frame value contained interior NUL");
unsafe { noesis_animation_string_keyframes_add(self.raw(), key_time_secs, c.as_ptr()) }
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_string_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<String> {
let p = unsafe { noesis_animation_string_keyframes_get_value(self.raw(), index as i32) };
if p.is_null() {
return None;
}
Some(unsafe { CStr::from_ptr(p) }.to_string_lossy().into_owned())
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t = unsafe { noesis_animation_string_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct OwnedComponent {
ptr: NonNull<c_void>,
}
base_component_handle!(OwnedComponent);
pub struct ObjectAnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(ObjectAnimationUsingKeyFrames);
impl Default for ObjectAnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl ObjectAnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_object_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_object_keyframes_create returned null"),
}
}
pub fn add_key_frame<C: AsComponent>(&mut self, key_time_secs: f64, value: &C) -> bool {
unsafe {
noesis_animation_object_keyframes_add(self.raw(), key_time_secs, value.component_raw())
}
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_object_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<OwnedComponent> {
let ptr = unsafe { noesis_animation_object_keyframes_get_value(self.raw(), index as i32) };
NonNull::new(ptr).map(|ptr| OwnedComponent { ptr })
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t = unsafe { noesis_animation_object_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct MatrixAnimationUsingKeyFrames {
ptr: NonNull<c_void>,
}
animation_impls!(MatrixAnimationUsingKeyFrames);
impl Default for MatrixAnimationUsingKeyFrames {
fn default() -> Self {
Self::new()
}
}
impl MatrixAnimationUsingKeyFrames {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_matrix_keyframes_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_matrix_keyframes_create returned null"),
}
}
pub fn add_key_frame(&mut self, key_time_secs: f64, value: [f32; 6]) -> bool {
unsafe { noesis_animation_matrix_keyframes_add(self.raw(), key_time_secs, value.as_ptr()) }
}
#[must_use]
pub fn key_frame_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_matrix_keyframes_count(self.raw()) };
u32::try_from(n).ok()
}
#[must_use]
pub fn key_frame_value(&self, index: u32) -> Option<[f32; 6]> {
let mut out = [0.0f32; 6];
let ok = unsafe {
noesis_animation_matrix_keyframes_get_value(self.raw(), index as i32, out.as_mut_ptr())
};
ok.then_some(out)
}
#[must_use]
pub fn key_frame_time(&self, index: u32) -> Option<f64> {
let t = unsafe { noesis_animation_matrix_keyframes_get_key_time(self.raw(), index as i32) };
(t >= 0.0).then_some(t)
}
}
pub struct BeginStoryboard {
ptr: NonNull<c_void>,
}
base_component_handle!(BeginStoryboard);
impl Default for BeginStoryboard {
fn default() -> Self {
Self::new()
}
}
impl BeginStoryboard {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_begin_storyboard_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_animation_begin_storyboard_create returned null"),
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_storyboard(&mut self, storyboard: &Storyboard) -> bool {
unsafe { noesis_animation_begin_storyboard_set_storyboard(self.raw(), storyboard.raw()) }
}
#[must_use]
pub fn has_storyboard(&self) -> bool {
let ptr = unsafe { noesis_animation_begin_storyboard_get_storyboard(self.raw()) };
if ptr.is_null() {
false
} else {
unsafe { noesis_base_component_release(ptr) };
true
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_handoff(&mut self, handoff: HandoffBehavior) -> bool {
unsafe { noesis_animation_begin_storyboard_set_handoff(self.raw(), handoff as i32) }
}
#[must_use]
pub fn handoff(&self) -> Option<HandoffBehavior> {
match unsafe { noesis_animation_begin_storyboard_get_handoff(self.raw()) } {
0 => Some(HandoffBehavior::SnapshotAndReplace),
1 => Some(HandoffBehavior::Compose),
_ => None,
}
}
#[must_use = "a false return means the property was not set (unknown name / type mismatch / read-only)"]
pub fn set_name(&mut self, name: &str) -> bool {
let c = CString::new(name).expect("name contained interior NUL");
unsafe { noesis_animation_begin_storyboard_set_name(self.raw(), c.as_ptr()) }
}
#[must_use]
pub fn name(&self) -> Option<String> {
let p = unsafe { noesis_animation_begin_storyboard_get_name(self.raw()) };
if p.is_null() {
return None;
}
let s = unsafe { CStr::from_ptr(p) }.to_string_lossy().into_owned();
(!s.is_empty()).then_some(s)
}
}
pub struct ParallelTimeline {
ptr: NonNull<c_void>,
}
base_component_handle!(ParallelTimeline);
impl Timeline for ParallelTimeline {
fn timeline_raw(&self) -> *mut c_void {
self.raw()
}
}
impl Default for ParallelTimeline {
fn default() -> Self {
Self::new()
}
}
impl ParallelTimeline {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_animation_parallel_timeline_create() };
Self {
ptr: NonNull::new(ptr)
.expect("noesis_animation_parallel_timeline_create returned null"),
}
}
pub fn add_child<T: Timeline>(&mut self, child: &T) -> bool {
unsafe { noesis_animation_parallel_timeline_add_child(self.raw(), child.timeline_raw()) }
}
#[must_use]
pub fn child_count(&self) -> Option<u32> {
let n = unsafe { noesis_animation_parallel_timeline_child_count(self.raw()) };
u32::try_from(n).ok()
}
}
macro_rules! fromto_builder {
($anim:ident, $builder:ident, $val:ty, $vname:literal) => {
impl $anim {
#[doc = concat!("Start a [`", stringify!($builder), "`] for fluent construction.")]
pub fn builder() -> $builder {
$builder {
anim: <$anim>::new(),
}
}
}
#[doc = concat!("Fluent builder for a [`", stringify!($anim), "`]. Sets the ", $vname,
" `from`/`to`/`by` plus the common timeline knobs (duration, begin time,\n\
auto-reverse, repeat, fill behavior, speed) and an easing function, then\n\
[`build`](Self::build)s the animation.")]
#[must_use]
pub struct $builder {
anim: $anim,
}
impl $builder {
#[doc = concat!("Set the starting ", $vname, " (`From`).")]
pub fn from(mut self, value: $val) -> Self {
let _ = self.anim.set_from(Some(value));
self
}
#[doc = concat!("Set the ending ", $vname, " (`To`).")]
pub fn to(mut self, value: $val) -> Self {
let _ = self.anim.set_to(Some(value));
self
}
#[doc = concat!("Set the relative ", $vname, " offset (`By`).")]
pub fn by(mut self, value: $val) -> Self {
let _ = self.anim.set_by(Some(value));
self
}
pub fn duration_secs(mut self, seconds: f64) -> Self {
let _ = self.anim.set_duration_secs(seconds);
self
}
pub fn begin_time_secs(mut self, seconds: f64) -> Self {
let _ = self.anim.set_begin_time_secs(seconds);
self
}
pub fn auto_reverse(mut self, value: bool) -> Self {
let _ = self.anim.set_auto_reverse(value);
self
}
pub fn speed_ratio(mut self, value: f32) -> Self {
let _ = self.anim.set_speed_ratio(value);
self
}
pub fn fill_behavior(mut self, behavior: FillBehavior) -> Self {
let _ = self.anim.set_fill_behavior(behavior);
self
}
pub fn repeat_count(mut self, count: f32) -> Self {
let _ = self.anim.set_repeat_count(count);
self
}
pub fn repeat_duration_secs(mut self, seconds: f64) -> Self {
let _ = self.anim.set_repeat_duration_secs(seconds);
self
}
pub fn repeat_forever(mut self) -> Self {
let _ = self.anim.set_repeat_forever();
self
}
pub fn easing(mut self, easing: &EasingFunction) -> Self {
let _ = self.anim.set_easing(easing);
self
}
#[doc = concat!("Finish and return the built [`", stringify!($anim), "`].")]
#[must_use]
pub fn build(self) -> $anim {
self.anim
}
}
};
}
fromto_builder!(DoubleAnimation, DoubleAnimationBuilder, f32, "value");
fromto_builder!(ColorAnimation, ColorAnimationBuilder, [f32; 4], "color");
fromto_builder!(
ThicknessAnimation,
ThicknessAnimationBuilder,
[f32; 4],
"thickness"
);
fromto_builder!(PointAnimation, PointAnimationBuilder, (f32, f32), "point");
fromto_builder!(RectAnimation, RectAnimationBuilder, [f32; 4], "rect");
fromto_builder!(SizeAnimation, SizeAnimationBuilder, [f32; 2], "size");
fromto_builder!(Int16Animation, Int16AnimationBuilder, i16, "value");
fromto_builder!(Int32Animation, Int32AnimationBuilder, i32, "value");
fromto_builder!(Int64Animation, Int64AnimationBuilder, i64, "value");