1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use block::ConcreteBlock;
use objc::{class, msg_send, sel, sel_impl};
use crate::foundation::id;
/// A very, very basic wrapper around NSAnimationContext. 100% subject to change.
#[derive(Debug)]
pub struct AnimationContext(id);
impl AnimationContext {
/// Wraps an NSAnimationContext pointer.
pub fn new(ctx: id) -> Self {
Self(ctx)
}
/// Sets the animation duration.
pub fn set_duration(&mut self, duration: f64) {
unsafe {
let _: () = msg_send![self.0, setDuration: duration];
}
}
/// Pass it a block, and the changes in that block will be animated, provided they're
/// properties that support animation.
///
/// [https://developer.apple.com/documentation/appkit/nsanimationcontext?language=objc]
///
/// For more information, you should consult the documentation for NSAnimationContext, then skim
/// the supported methods here.
pub fn run<F>(animation: F)
where
F: Fn(&mut AnimationContext) + Send + Sync + 'static
{
let block = ConcreteBlock::new(move |ctx| {
let mut context = AnimationContext(ctx);
animation(&mut context);
});
let block = block.copy();
unsafe {
//let context: id = msg_send![class!(NSAnimationContext), currentContext];
let _: () = msg_send![class!(NSAnimationContext), runAnimationGroup: block];
}
}
/// Pass it a block, and the changes in that block will be animated, provided they're
/// properties that support animation.
///
/// [https://developer.apple.com/documentation/appkit/nsanimationcontext?language=objc]
///
/// For more information, you should consult the documentation for NSAnimationContext, then skim
/// the supported methods here.
pub fn run_with_completion_handler<F, C>(animation: F, completion_handler: C)
where
F: Fn(&mut AnimationContext) + Send + Sync + 'static,
C: Fn() + Send + Sync + 'static
{
let block = ConcreteBlock::new(move |ctx| {
let mut context = AnimationContext(ctx);
animation(&mut context);
});
let block = block.copy();
let completion_block = ConcreteBlock::new(completion_handler);
let completion_block = completion_block.copy();
unsafe {
//let context: id = msg_send![class!(NSAnimationContext), currentContext];
let _: () = msg_send![class!(NSAnimationContext), runAnimationGroup:block
completionHandler:completion_block];
}
}
}