use core::ptr::NonNull;
use std::ffi::c_void;
use crate::ffi::{
noesis_base_component_release, noesis_composite_transform_create,
noesis_composite_transform_get, noesis_composite_transform3d_create,
noesis_composite_transform3d_get, noesis_composite_transform3d_set,
noesis_matrix_transform_create, noesis_matrix_transform_get, noesis_matrix_transform_set,
noesis_matrix_transform3d_create, noesis_matrix_transform3d_get, noesis_matrix_transform3d_set,
noesis_rotate_transform_create, noesis_rotate_transform_get, noesis_rotate_transform_set_angle,
noesis_scale_transform_create, noesis_scale_transform_get, noesis_scale_transform_set,
noesis_skew_transform_create, noesis_skew_transform_get, noesis_transform_group_add_child,
noesis_transform_group_child_count, noesis_transform_group_create,
noesis_translate_transform_create, noesis_translate_transform_get,
noesis_translate_transform_set,
};
pub trait Transform {
fn transform_raw(&self) -> *mut c_void;
}
macro_rules! transform_handle {
($name:ident) => {
unsafe impl Send for $name {}
impl $name {
#[must_use]
pub fn raw(&self) -> *mut c_void {
self.ptr.as_ptr()
}
}
impl Transform for $name {
fn transform_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 struct AnyTransform {
ptr: NonNull<c_void>,
}
transform_handle!(AnyTransform);
impl AnyTransform {
pub(crate) unsafe fn from_owned(ptr: NonNull<c_void>) -> Self {
Self { ptr }
}
}
pub struct TranslateTransform {
ptr: NonNull<c_void>,
}
transform_handle!(TranslateTransform);
impl TranslateTransform {
#[must_use]
pub fn new(x: f32, y: f32) -> Self {
let ptr = unsafe { noesis_translate_transform_create(x, y) };
Self {
ptr: NonNull::new(ptr).expect("noesis_translate_transform_create returned null"),
}
}
pub fn set(&mut self, x: f32, y: f32) {
unsafe { noesis_translate_transform_set(self.ptr.as_ptr(), x, y) };
}
#[must_use]
pub fn get(&self) -> (f32, f32) {
let mut x = 0.0f32;
let mut y = 0.0f32;
unsafe {
noesis_translate_transform_get(
self.ptr.as_ptr(),
&mut x as *mut f32,
&mut y as *mut f32,
)
};
(x, y)
}
}
pub struct ScaleTransform {
ptr: NonNull<c_void>,
}
transform_handle!(ScaleTransform);
impl ScaleTransform {
#[must_use]
pub fn new(scale_x: f32, scale_y: f32, center_x: f32, center_y: f32) -> Self {
let ptr = unsafe { noesis_scale_transform_create(scale_x, scale_y, center_x, center_y) };
Self {
ptr: NonNull::new(ptr).expect("noesis_scale_transform_create returned null"),
}
}
pub fn set(&mut self, scale_x: f32, scale_y: f32, center_x: f32, center_y: f32) {
unsafe {
noesis_scale_transform_set(self.ptr.as_ptr(), scale_x, scale_y, center_x, center_y)
};
}
#[must_use]
pub fn get(&self) -> [f32; 4] {
let mut out = [0.0f32; 4];
unsafe { noesis_scale_transform_get(self.ptr.as_ptr(), out.as_mut_ptr()) };
out
}
}
pub struct RotateTransform {
ptr: NonNull<c_void>,
}
transform_handle!(RotateTransform);
impl RotateTransform {
#[must_use]
pub fn new(angle: f32, center_x: f32, center_y: f32) -> Self {
let ptr = unsafe { noesis_rotate_transform_create(angle, center_x, center_y) };
Self {
ptr: NonNull::new(ptr).expect("noesis_rotate_transform_create returned null"),
}
}
pub fn set_angle(&mut self, angle: f32) {
unsafe { noesis_rotate_transform_set_angle(self.ptr.as_ptr(), angle) };
}
#[must_use]
pub fn get(&self) -> [f32; 3] {
let mut out = [0.0f32; 3];
unsafe { noesis_rotate_transform_get(self.ptr.as_ptr(), out.as_mut_ptr()) };
out
}
#[must_use]
pub fn angle(&self) -> f32 {
self.get()[0]
}
}
pub struct SkewTransform {
ptr: NonNull<c_void>,
}
transform_handle!(SkewTransform);
impl SkewTransform {
#[must_use]
pub fn new(angle_x: f32, angle_y: f32, center_x: f32, center_y: f32) -> Self {
let ptr = unsafe { noesis_skew_transform_create(angle_x, angle_y, center_x, center_y) };
Self {
ptr: NonNull::new(ptr).expect("noesis_skew_transform_create returned null"),
}
}
#[must_use]
pub fn get(&self) -> [f32; 4] {
let mut out = [0.0f32; 4];
unsafe { noesis_skew_transform_get(self.ptr.as_ptr(), out.as_mut_ptr()) };
out
}
}
pub struct MatrixTransform {
ptr: NonNull<c_void>,
}
transform_handle!(MatrixTransform);
impl MatrixTransform {
#[must_use]
pub fn new(matrix: [f32; 6]) -> Self {
let ptr = unsafe { noesis_matrix_transform_create(matrix.as_ptr()) };
Self {
ptr: NonNull::new(ptr).expect("noesis_matrix_transform_create returned null"),
}
}
pub fn set(&mut self, matrix: [f32; 6]) {
unsafe { noesis_matrix_transform_set(self.ptr.as_ptr(), matrix.as_ptr()) };
}
#[must_use]
pub fn get(&self) -> [f32; 6] {
let mut out = [0.0f32; 6];
unsafe { noesis_matrix_transform_get(self.ptr.as_ptr(), out.as_mut_ptr()) };
out
}
}
pub struct TransformGroup {
ptr: NonNull<c_void>,
}
transform_handle!(TransformGroup);
impl Default for TransformGroup {
fn default() -> Self {
Self::new()
}
}
impl TransformGroup {
#[must_use]
pub fn new() -> Self {
let ptr = unsafe { noesis_transform_group_create() };
Self {
ptr: NonNull::new(ptr).expect("noesis_transform_group_create returned null"),
}
}
pub fn add_child<T: Transform>(&mut self, child: &T) -> bool {
unsafe { noesis_transform_group_add_child(self.ptr.as_ptr(), child.transform_raw()) }
}
#[must_use]
pub fn child_count(&self) -> usize {
let n = unsafe { noesis_transform_group_child_count(self.ptr.as_ptr()) };
n.max(0) as usize
}
}
pub struct CompositeTransform {
ptr: NonNull<c_void>,
}
transform_handle!(CompositeTransform);
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct CompositeFields {
pub center_x: f32,
pub center_y: f32,
pub scale_x: f32,
pub scale_y: f32,
pub skew_x: f32,
pub skew_y: f32,
pub rotation: f32,
pub translate_x: f32,
pub translate_y: f32,
}
impl Default for CompositeFields {
fn default() -> Self {
Self {
center_x: 0.0,
center_y: 0.0,
scale_x: 1.0,
scale_y: 1.0,
skew_x: 0.0,
skew_y: 0.0,
rotation: 0.0,
translate_x: 0.0,
translate_y: 0.0,
}
}
}
impl CompositeFields {
fn to_array(self) -> [f32; 9] {
[
self.center_x,
self.center_y,
self.scale_x,
self.scale_y,
self.skew_x,
self.skew_y,
self.rotation,
self.translate_x,
self.translate_y,
]
}
fn from_array(a: [f32; 9]) -> Self {
Self {
center_x: a[0],
center_y: a[1],
scale_x: a[2],
scale_y: a[3],
skew_x: a[4],
skew_y: a[5],
rotation: a[6],
translate_x: a[7],
translate_y: a[8],
}
}
}
impl CompositeTransform {
#[must_use]
pub fn new(fields: CompositeFields) -> Self {
let arr = fields.to_array();
let ptr = unsafe { noesis_composite_transform_create(arr.as_ptr()) };
Self {
ptr: NonNull::new(ptr).expect("noesis_composite_transform_create returned null"),
}
}
#[must_use]
pub fn get(&self) -> CompositeFields {
let mut out = [0.0f32; 9];
unsafe { noesis_composite_transform_get(self.ptr.as_ptr(), out.as_mut_ptr()) };
CompositeFields::from_array(out)
}
}
pub trait Transform3D {
fn transform3d_raw(&self) -> *mut c_void;
}
macro_rules! transform3d_handle {
($name:ident) => {
unsafe impl Send for $name {}
impl $name {
#[must_use]
pub fn raw(&self) -> *mut c_void {
self.ptr.as_ptr()
}
}
impl Transform3D for $name {
fn transform3d_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 struct AnyTransform3D {
ptr: NonNull<c_void>,
}
transform3d_handle!(AnyTransform3D);
impl AnyTransform3D {
pub(crate) unsafe fn from_owned(ptr: NonNull<c_void>) -> Self {
Self { ptr }
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Composite3DFields {
pub center_x: f32,
pub center_y: f32,
pub center_z: f32,
pub rotation_x: f32,
pub rotation_y: f32,
pub rotation_z: f32,
pub scale_x: f32,
pub scale_y: f32,
pub scale_z: f32,
pub translate_x: f32,
pub translate_y: f32,
pub translate_z: f32,
}
impl Default for Composite3DFields {
fn default() -> Self {
Self {
center_x: 0.0,
center_y: 0.0,
center_z: 0.0,
rotation_x: 0.0,
rotation_y: 0.0,
rotation_z: 0.0,
scale_x: 1.0,
scale_y: 1.0,
scale_z: 1.0,
translate_x: 0.0,
translate_y: 0.0,
translate_z: 0.0,
}
}
}
impl Composite3DFields {
fn to_array(self) -> [f32; 12] {
[
self.center_x,
self.center_y,
self.center_z,
self.rotation_x,
self.rotation_y,
self.rotation_z,
self.scale_x,
self.scale_y,
self.scale_z,
self.translate_x,
self.translate_y,
self.translate_z,
]
}
fn from_array(a: [f32; 12]) -> Self {
Self {
center_x: a[0],
center_y: a[1],
center_z: a[2],
rotation_x: a[3],
rotation_y: a[4],
rotation_z: a[5],
scale_x: a[6],
scale_y: a[7],
scale_z: a[8],
translate_x: a[9],
translate_y: a[10],
translate_z: a[11],
}
}
}
pub struct CompositeTransform3D {
ptr: NonNull<c_void>,
}
transform3d_handle!(CompositeTransform3D);
impl CompositeTransform3D {
#[must_use]
pub fn new(fields: Composite3DFields) -> Self {
let arr = fields.to_array();
let ptr = unsafe { noesis_composite_transform3d_create(arr.as_ptr()) };
Self {
ptr: NonNull::new(ptr).expect("noesis_composite_transform3d_create returned null"),
}
}
pub fn set(&mut self, fields: Composite3DFields) {
let arr = fields.to_array();
unsafe { noesis_composite_transform3d_set(self.ptr.as_ptr(), arr.as_ptr()) };
}
#[must_use]
pub fn get(&self) -> Composite3DFields {
let mut out = [0.0f32; 12];
unsafe { noesis_composite_transform3d_get(self.ptr.as_ptr(), out.as_mut_ptr()) };
Composite3DFields::from_array(out)
}
}
pub struct MatrixTransform3D {
ptr: NonNull<c_void>,
}
transform3d_handle!(MatrixTransform3D);
impl MatrixTransform3D {
#[must_use]
pub fn new(matrix: [f32; 12]) -> Self {
let ptr = unsafe { noesis_matrix_transform3d_create(matrix.as_ptr()) };
Self {
ptr: NonNull::new(ptr).expect("noesis_matrix_transform3d_create returned null"),
}
}
pub fn set(&mut self, matrix: [f32; 12]) {
unsafe { noesis_matrix_transform3d_set(self.ptr.as_ptr(), matrix.as_ptr()) };
}
#[must_use]
pub fn get(&self) -> [f32; 12] {
let mut out = [0.0f32; 12];
unsafe { noesis_matrix_transform3d_get(self.ptr.as_ptr(), out.as_mut_ptr()) };
out
}
}