core_animation/
lib.rs

1//! Rust bindings for macOS Core Animation with ergonomic builder APIs.
2//!
3//! # Builders
4//!
5//! | Builder | Purpose |
6//! |---------|---------|
7//! | [`WindowBuilder`] | Layer-backed windows with background, border, transparency |
8//! | [`CALayerBuilder`] | Base layers with bounds, position, sublayers |
9//! | [`CAShapeLayerBuilder`] | Vector shapes with path, fill, stroke, shadows |
10//! | [`CATextLayerBuilder`] | Text rendering layers |
11//! | [`CAEmitterLayerBuilder`](particles::CAEmitterLayerBuilder) | Particle systems with closure-based cell configuration |
12//! | [`PointBurstBuilder`](particles::PointBurstBuilder) | Convenience API for radial particle bursts |
13//! | [`CABasicAnimationBuilder`](animation_builder::CABasicAnimationBuilder) | Standalone GPU-accelerated animations |
14//!
15//! # Quick Start
16//!
17//! ```ignore
18//! use core_animation::prelude::*;
19//!
20//! let window = WindowBuilder::new()
21//!     .title("Demo")
22//!     .size(400.0, 400.0)
23//!     .centered()
24//!     .background_color(Color::rgb(0.1, 0.1, 0.15))
25//!     .build();
26//!
27//! let circle = CAShapeLayerBuilder::new()
28//!     .circle(80.0)
29//!     .position(CGPoint::new(200.0, 200.0))
30//!     .fill_color(Color::CYAN)
31//!     .animate("pulse", KeyPath::TransformScale, |a| {
32//!         a.values(0.85, 1.15)
33//!             .duration(1.seconds())
34//!             .easing(Easing::InOut)
35//!             .autoreverses()
36//!             .repeat(Repeat::Forever)
37//!     })
38//!     .build();
39//!
40//! window.container().add_sublayer(&circle);
41//! window.show_for(10.seconds());
42//! ```
43//!
44//! # Animations
45//!
46//! All layer builders support `.animate()` for GPU-accelerated animations:
47//!
48//! ```ignore
49//! .animate("name", KeyPath::TransformScale, |a| {
50//!     a.values(0.8, 1.2)              // from/to values
51//!         .duration(500.millis())      // timing
52//!         .easing(Easing::InOut)       // curve
53//!         .autoreverses()              // ping-pong
54//!         .repeat(Repeat::Forever)     // loop
55//!         .phase_offset(0.5)           // stagger multiple animations
56//! })
57//! ```
58//!
59//! **Animatable properties:** [`TransformScale`](animation_builder::KeyPath::TransformScale),
60//! [`TransformRotation`](animation_builder::KeyPath::TransformRotation),
61//! [`Opacity`](animation_builder::KeyPath::Opacity),
62//! [`ShadowRadius`](animation_builder::KeyPath::ShadowRadius),
63//! [`ShadowOpacity`](animation_builder::KeyPath::ShadowOpacity),
64//! [`Custom`](animation_builder::KeyPath::Custom)
65//!
66//! **Easing curves:** [`Linear`](animation_builder::Easing::Linear),
67//! [`In`](animation_builder::Easing::In),
68//! [`Out`](animation_builder::Easing::Out),
69//! [`InOut`](animation_builder::Easing::InOut)
70//!
71//! # Particle Systems
72//!
73//! ```ignore
74//! use std::f64::consts::PI;
75//!
76//! let emitter = CAEmitterLayerBuilder::new()
77//!     .position(320.0, 240.0)
78//!     .shape(EmitterShape::Point)
79//!     .particle(|p| {
80//!         p.birth_rate(100.0)
81//!             .lifetime(5.0)
82//!             .velocity(80.0)
83//!             .emission_range(PI * 2.0)
84//!             .color(Color::CYAN)
85//!             .image(ParticleImage::soft_glow(64))
86//!     })
87//!     .build();
88//! ```
89//!
90//! Or use the convenience builder:
91//!
92//! ```ignore
93//! let burst = PointBurstBuilder::new(320.0, 240.0)
94//!     .velocity(100.0)
95//!     .color(Color::PINK)
96//!     .build();
97//! ```
98//!
99//! **Particle images:** [`soft_glow`](particles::ParticleImage::soft_glow),
100//! [`circle`](particles::ParticleImage::circle),
101//! [`star`](particles::ParticleImage::star),
102//! [`spark`](particles::ParticleImage::spark)
103//!
104//! # Examples
105//!
106//! See the [examples](https://github.com/sassman/core-animation-rs/tree/main/examples)
107//! for runnable demos with screenshots.
108//!
109//! ```bash
110//! cargo run --example window_builder
111//! ```
112//!
113//! Use [`prelude`] to import common types.
114
115#[cfg(all(not(docsrs), not(any(target_vendor = "apple"))))]
116compile_error!("`core-animation` only works on Apple platforms. Pass `--target aarch64-apple-darwin` or similar to compile for macOS.");
117
118pub mod animation_builder;
119mod color;
120mod duration_ext;
121mod layer_builder;
122mod layer_ext;
123pub mod particles;
124mod shape_layer_builder;
125mod text_layer_builder;
126pub mod window;
127
128// Re-export Color type
129pub use color::Color;
130
131// Re-export the main types from objc2-quartz-core
132pub use objc2_quartz_core::{CALayer, CAShapeLayer, CATextLayer, CATransform3D};
133
134// Re-export our builders
135pub use layer_builder::CALayerBuilder;
136pub use shape_layer_builder::CAShapeLayerBuilder;
137pub use text_layer_builder::{CATextLayerBuilder, TextAlign, Truncation};
138
139// Re-export window types
140pub use window::{Screen, Window, WindowBuilder, WindowLevel, WindowStyle};
141
142// Re-export duration extension
143pub use duration_ext::DurationExt;
144
145// Re-export layer extension
146pub use layer_ext::CALayerExt;
147
148// Re-export dependencies for convenience
149pub use objc2_core_foundation;
150pub use objc2_core_graphics;
151pub use objc2_core_text;
152pub use objc2_quartz_core;
153
154/// Prelude module for convenient imports.
155pub mod prelude {
156    // Color type
157    pub use crate::color::Color;
158
159    // Animation builder types
160    pub use crate::animation_builder::{CABasicAnimationBuilder, Easing, KeyPath, Repeat};
161
162    // Builders
163    pub use crate::layer_builder::CALayerBuilder;
164    pub use crate::particles::{
165        CAEmitterCellBuilder, CAEmitterLayerBuilder, EmitterMode, EmitterShape, ParticleImage,
166        PointBurstBuilder, RenderMode,
167    };
168    pub use crate::shape_layer_builder::CAShapeLayerBuilder;
169    pub use crate::text_layer_builder::{CATextLayerBuilder, TextAlign, Truncation};
170    pub use crate::window::{Screen, Window, WindowBuilder, WindowLevel, WindowStyle};
171
172    // Duration extension for ergonomic timing
173    pub use crate::duration_ext::DurationExt;
174
175    // Layer extension for snake_case methods
176    pub use crate::layer_ext::CALayerExt;
177
178    // Core Animation types
179    pub use crate::{CALayer, CAShapeLayer, CATextLayer, CATransform3D};
180    pub use objc2_quartz_core::CABasicAnimation;
181
182    // Core Foundation types (geometry, strings, collections, run loop)
183    pub use objc2_core_foundation::{
184        kCFRunLoopDefaultMode, kCFTypeDictionaryKeyCallBacks, kCFTypeDictionaryValueCallBacks,
185        CFAttributedString, CFDictionary, CFDictionaryKeyCallBacks, CFDictionaryValueCallBacks,
186        CFIndex, CFRetained, CFRunLoop, CFString, CFStringBuiltInEncodings, CFTimeInterval,
187        CGAffineTransform, CGFloat, CGPoint, CGRect, CGSize,
188    };
189
190    // Core Graphics types (context, colors, paths, transforms, display)
191    pub use objc2_core_graphics::{
192        CGAffineTransformIdentity, CGColor, CGContext, CGDirectDisplayID, CGDisplayBounds,
193        CGMainDisplayID, CGPath,
194    };
195
196    // Core Text types (fonts, lines, string attributes)
197    pub use objc2_core_text::{
198        kCTFontAttributeName, kCTForegroundColorAttributeName, CTFont, CTLine,
199    };
200
201    // AppKit types (NSApplication)
202    pub use objc2_app_kit::NSApplication;
203
204    // Smart pointer for Objective-C objects
205    pub use objc2::rc::Retained;
206}