150 lines
4.0 KiB
Objective-C
150 lines
4.0 KiB
Objective-C
// -*- Mode: ObjC; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
//
|
|
// This file is part of the LibreOffice project.
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
#import "MLOAnimation.h"
|
|
|
|
|
|
typedef CGFloat (^MLOAnimationCurve)(CGFloat time);
|
|
|
|
@interface MLOAnimation ()
|
|
@property BOOL active,didPost,cancelled;
|
|
@property CGFloat frameCount;
|
|
@property NSDate * startDate;
|
|
@property MLOAnimationBehavior behavior;
|
|
@property MLOAnimationFractionType fractionType;
|
|
@property (nonatomic,strong) MLOAnimationBlock animation;
|
|
@property (nonatomic,strong) MLOAnimationCurve curve;
|
|
@end
|
|
|
|
@implementation MLOAnimation
|
|
|
|
-(void) linearCurve{
|
|
static const MLOAnimationCurve LINEAR = ^(CGFloat completedFraction){
|
|
return completedFraction;
|
|
};
|
|
[self setCurve:LINEAR name:@"LINEAR"];
|
|
}
|
|
-(void) easeOutCurve{
|
|
static const MLOAnimationCurve EASE_OUT = ^(CGFloat completedFraction){
|
|
return 1 - completedFraction*completedFraction;
|
|
};
|
|
[self setCurve:EASE_OUT name:@"EASE_OUT"];
|
|
}
|
|
|
|
-(void) easeInCurve{
|
|
static const MLOAnimationCurve EASE_IN = ^(CGFloat completedFraction){
|
|
return completedFraction*completedFraction;
|
|
};
|
|
|
|
[self setCurve:EASE_IN name:@"EASE_IN"];
|
|
}
|
|
|
|
-(void)setCurve:(MLOAnimationCurve) curve name:(NSString *) name{
|
|
self.curve = curve;
|
|
NSLog(@"MLOAnimation curve set to: %@",name);
|
|
}
|
|
|
|
-(void) cancel{
|
|
if(_behavior == CANCELABLE){
|
|
self.cancelled= YES;
|
|
self.active = NO;
|
|
[self doPost:nil];
|
|
|
|
if(_startDate){
|
|
|
|
NSLog(@"MLOAnimation cancelled after %f millis",[_startDate timeIntervalSinceNow]);
|
|
}else{
|
|
NSLog(@"MLOAnimation aborted");
|
|
}
|
|
}else{
|
|
NSLog(@"CLOAnimation cannot be cancelled");
|
|
}
|
|
}
|
|
-(BOOL) isCancelled{
|
|
return self.cancelled;
|
|
}
|
|
|
|
-(id)initWithBehavior:(BOOL) behavior fractionType:(MLOAnimationFractionType) fractionType animation:(MLOAnimationBlock) animation{
|
|
self = [super init];
|
|
if(self){
|
|
_active=YES;
|
|
_duration = DEFAULT_MLO_ANIMATION_DURAION;
|
|
_fps = DEFAULT_ANIMATION_FPS;
|
|
_behavior=CANCELABLE;
|
|
_fractionType = fractionType;
|
|
_frameCount = -1.0f;
|
|
_startDate = nil;
|
|
_didPost =NO;
|
|
_cancelled=NO;
|
|
[self linearCurve];
|
|
self.animation = animation;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
-(void)animate{
|
|
|
|
if(!_startDate){
|
|
self.startDate = [NSDate date];
|
|
_frameCount = _duration *_fps;
|
|
|
|
if(_frameCount>0){
|
|
CGFloat frameDuration = 1.0f/_fps;
|
|
|
|
NSLog(@"MLOAnimation: duration=%f frameCount=%f fps=%f frameDuration=%f fractionType=%@",_duration,_frameCount,_fps,frameDuration,[self fractionTypeAsString]);
|
|
|
|
for (CGFloat i = 1; i <= _frameCount; i++) {
|
|
[self performSelector:@selector(doFrame:) withObject:[NSNumber numberWithFloat:i] afterDelay: i*frameDuration];
|
|
}
|
|
[self performSelector:@selector(doPost:) withObject:nil afterDelay:_duration + frameDuration];
|
|
}else{
|
|
NSLog(@"MLOAnimation cannot run (zero frames)");
|
|
}
|
|
}
|
|
}
|
|
|
|
-(void) doPost:(NSObject *) niller{
|
|
if(!_didPost){
|
|
_didPost = YES;
|
|
if(_endBlock){
|
|
_endBlock();
|
|
}
|
|
}
|
|
}
|
|
|
|
-(NSString *)fractionTypeAsString{
|
|
switch (_fractionType) {
|
|
case DELTA_ONLY:
|
|
return @"DELTA_ONLY";
|
|
case FULL_FRACTION:
|
|
return @"FULL_FRACTION";
|
|
}
|
|
}
|
|
|
|
-(void)doFrame:(NSNumber *) frame{
|
|
if(_active){
|
|
|
|
CGFloat fFrame = [frame floatValue];
|
|
|
|
CGFloat currentFraction = _curve(fFrame/_frameCount);
|
|
|
|
if(_fractionType == DELTA_ONLY){
|
|
currentFraction -= _curve( (fFrame-1.0f) /_frameCount);
|
|
}
|
|
|
|
_animation(_curve(currentFraction));
|
|
|
|
if(fFrame ==_frameCount){
|
|
|
|
_behavior =MANDATORY;
|
|
}
|
|
}
|
|
}
|
|
|
|
@end
|