Files
cappuccino/Tests/Manual/CPAnimatablePropertyContainerTest/AppController.j
T
cacaodev 037bc4ea2b Test: demonstrate the new wantsPeriodicFrameUpdates animator property
In Tests/Manual/CPAnimatablePropertyContainerTest/
2016-11-07 22:26:30 +01:00

575 lines
16 KiB
Plaintext

/*
* AppController.j
* CPAnimatablePropertyContainerTest
*
* Created by You on December 3, 2012.
* Copyright 2012, Your Company All rights reserved.
*/
@import <Foundation/CPObject.j>
CPLogRegister(CPLogConsole);
var ANIMATIONS_NAMES = ["Fade In", "Fade Out", "Background Color", "Frame Origin", "Bounce", "Frame Size", "Frame"];
@implementation AppController : CPObject
{
@outlet CPWindow theWindow; //this "outlet" is connected automatically by the Cib
@outlet CPBox group1Box;
@outlet CPBox group2Box;
@outlet AnimationSandbox animationSandbox;
CPView leftView;
CPView rightView;
CPArray animations;
float duration1 @accessors;
float duration2 @accessors;
CPString message1 @accessors;
CPString message2 @accessors;
CPInteger selectedTimingFunction1 @accessors;
CPInteger selectedTimingFunction2 @accessors;
CPString timingFunction1 @accessors;
CPString timingFunction2 @accessors;
BOOL periodicFrameUpdates;
}
- (id)init
{
self = [super init];
animations = [CPArray array];
[ANIMATIONS_NAMES enumerateObjectsUsingBlock:function(anim, idx)
{
var dict = [CPDictionary dictionaryWithObjectsAndKeys:anim, @"name", NO, @"enabled1", NO, @"enabled2"];
[animations addObject:dict];
}];
duration1 = 1.0;
duration2 = 1.0;
message1 = @"Done for View 1";
message2 = @"Done for View 2";
timingFunction1 = @"0,1,1,0";
timingFunction2 = @"0,1,1,0";
selectedTimingFunction1 = 1;
selectedTimingFunction2 = 1;
periodicFrameUpdates = NO;
return self;
}
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
// This is called when the application is done loading.
}
- (void)awakeFromCib
{
// This is called when the cib is done loading.
// You can implement this method on any object instantiated from a Cib.
// It's a useful hook for setting up current UI values, and other things.
[[theWindow contentView] setBackgroundColor:[CPColor colorWithRed:1 green:238/255 blue:185/255 alpha:1]];
[animationSandbox setBackgroundColor:[CPColor whiteColor]];
[self revert:nil];
// In this case, we want the window from Cib to become our full browser window
[theWindow setFullPlatformWindow:YES];
}
- (IBAction)runAnimationsGroup1:(id)sender
{
[[CPAnimationContext currentContext] setDuration:duration1];
[[CPAnimationContext currentContext] setTimingFunction:[self timingFunctionForGroup:1 fromPopUp:selectedTimingFunction1]];
[[CPAnimationContext currentContext] setCompletionHandler:[self completionHandlerFromString:message1]];
[self runAnimationsForGroup:1];
}
- (IBAction)runAnimationsGroup2:(id)sender
{
[[CPAnimationContext currentContext] setDuration:duration2];
[[CPAnimationContext currentContext] setTimingFunction:[self timingFunctionForGroup:2 fromPopUp:selectedTimingFunction2]];
[[CPAnimationContext currentContext] setCompletionHandler:[self completionHandlerFromString:message2]];
[self runAnimationsForGroup:2];
}
- (IBAction)animate:(id)sender
{
[[CPAnimationContext currentContext] setDuration:duration1];
[[CPAnimationContext currentContext] setTimingFunction:[self timingFunctionForGroup:1 fromPopUp:selectedTimingFunction2]];
[[CPAnimationContext currentContext] setCompletionHandler:[self completionHandlerFromString:message1]];
var tag = [sender tag];
var width = tag ? 100 : 200;
[[sender animator] setFrameSize:CGSizeMake(width, CGRectGetHeight([sender frame]))];
[sender setTag:(1 - tag)];
}
- (IBAction)runBothGroups:(id)sender
{
[CPAnimationContext runAnimationGroup:function(context)
{
[context setDuration:duration1];
[context setTimingFunction:[self timingFunctionForGroup:1 fromPopUp:selectedTimingFunction1]];
[self runAnimationsForGroup:1];
} completionHandler:function()
{
CPLogConsole(message1);
}];
[CPAnimationContext runAnimationGroup:function(context)
{
[context setDuration:duration2];
[context setTimingFunction:[self timingFunctionForGroup:2 fromPopUp:selectedTimingFunction2]];
[self runAnimationsForGroup:2];
} completionHandler:function()
{
CPLogConsole(message2);
}];
}
/*
- (IBAction)runInGroups:(id)sender
{
[CPAnimationContext beginGrouping];
[[CPAnimationContext currentContext] setDuration:duration1];
[[CPAnimationContext currentContext] setTimingFunction:[self timingFunctionFromString:timingFunction1]];
[[CPAnimationContext currentContext] setCompletionHandler:[self completionHandlerFromString:message1]];
[self runAnimationsForGroup:1];
[CPAnimationContext endGrouping];
[CPAnimationContext beginGrouping];
[[CPAnimationContext currentContext] setDuration:duration2];
[[CPAnimationContext currentContext] setCompletionHandler:[self completionHandlerFromString:message2]];
[self runAnimationsForGroup:2];
[CPAnimationContext endGrouping];
}
- (IBAction)emptyGroupTest:(id)sender
{
[CPAnimationContext beginGrouping];
[[CPAnimationContext currentContext] setDuration:10];
[[CPAnimationContext currentContext] setCompletionHandler:function()
{
CPLogConsole("Context duration is 10s but no animations were set. We run the completionHandler (this message) immediately and return");
}];
[CPAnimationContext endGrouping];
}
*/
- (IBAction)removeFromSuperview:(id)sender
{
[[leftView animator] removeFromSuperview];
[[rightView animator] removeFromSuperview];
}
- (IBAction)revert:(id)sender
{
[self setupGroup1:nil];
[self setupGroup2:nil];
[animationSandbox setNeedsDisplay:YES];
}
/*
- (IBAction)addSubview:(id)sender
{
[[theWindow contentView] addSubview:];
}
*/
- (void)runAnimationsForGroup:(CPInteger)group
{
var aView = group == 1 ? leftView : rightView,
enabledKey = @"enabled" + group;
var enabledIndexes = [animations indexesOfObjectsPassingTest:function(obj, idx)
{
return [obj objectForKey:enabledKey];
}];
if ([enabledIndexes count] == 0)
return;
if ([enabledIndexes containsIndex:0])
{
[aView setAlphaValue:0];
[[aView animator] setAlphaValue:1];
}
else if ([enabledIndexes containsIndex:1])
{
[[aView animator] setAlphaValue:0];
}
if ([enabledIndexes containsIndex:2])
{
[[aView animator] setBackgroundColor:[CPColor magentaColor]];
}
if ([enabledIndexes containsIndex:6])
{
var frame = CGRectMakeCopy([aView frame]),
origin = frame.origin,
size = frame.size;
origin.x += 450;
origin.y += 200;
size.width += 100;
size.height += 100;
[[aView animator] setWantsPeriodicFrameUpdates:periodicFrameUpdates];
[[aView animator] setFrame:frame];
return;
}
if ([enabledIndexes containsIndex:4])
{
[[aView animations] setObject:[self bounceAnimation:aView] forKey:@"frameOrigin"];
var origin = CGPointMakeCopy([aView frameOrigin]);
[[aView animator] setWantsPeriodicFrameUpdates:periodicFrameUpdates];
[[aView animator] setFrameOrigin:origin];
}
else if ([enabledIndexes containsIndex:3])
{
[[aView animations] removeObjectForKey:@"frameOrigin"];
var origin = CGPointMakeCopy([aView frameOrigin]);
origin.x +=550;
origin.y +=300;
[[aView animator] setWantsPeriodicFrameUpdates:periodicFrameUpdates];
[[aView animator] setFrameOrigin:origin];
}
if ([enabledIndexes containsIndex:5])
{
var size = CGSizeMakeCopy([aView frameSize]);
size.width += 300;
size.height += 200;
[[aView animator] setFrameSize:size];
}
}
- (CAMediaTimingFunction)controlsPointsForGroup:(CPInteger)aGroup
{
var aString = (aGroup == 1) ? timingFunction1 : timingFunction2;
if (!aString || ![aString length])
return nil;
var controlsPoints = [aString componentsSeparatedByString:@","];
return [[controlsPoints[0] floatValue], [controlsPoints[1] floatValue], [controlsPoints[2] floatValue], [controlsPoints[3] floatValue]];
}
- (CAMediaTimingFunction)timingFunctionForGroup:(CPInteger)aGroup fromPopUp:(CPInteger)selectedTag
{
var controlsPoints;
switch (selectedTag)
{
case 1: controlsPoints = [0, 0, 1, 1];
break;
case 2: controlsPoints = [0.42, 0, 1, 1];
break;
case 3: controlsPoints = [0, 0, 0.58, 1];
break;
case 4: controlsPoints = [0.42, 0, 0.58, 1];
break;
case 0: controlsPoints = [self controlsPointsForGroup:aGroup];
break;
}
return [CAMediaTimingFunction functionWithControlPoints:controlsPoints[0] :controlsPoints[1] :controlsPoints[2] :controlsPoints[3]];
}
- (Function)completionHandlerFromString:(CPString)aMessage
{
if (!aMessage || ![aMessage length])
return nil;
var s = new Date();
return function()
{
var e = new Date() - s;
CPLogConsole(aMessage + " in " + e + " ms");
};
}
- (CAKeyframeAnimation)bounceAnimation:(CPView)aView
{
var anim = [CAKeyframeAnimation animation],
easein = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
easeout = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[anim setKeyTimes:[0, 0.2, 0.3, 0.5, 0.7, 0.8]];
var origin = CGPointMakeCopy([aView frameOrigin]);
[anim setValues:[origin, CGPointMake(origin.x, origin.y + 200), origin, CGPointMake(origin.x, origin.y + 100), origin, CGPointMake(origin.x, origin.y + 50)]];
[anim setTimingFunctions:[easeout, easein, easeout, easein, easeout]];
return anim;
}
- (CABasicAnimation)fadeOutAnimation
{
var animation = [CABasicAnimation animationWithKeyPath:@"alphaValue"];
[animation setDuration:0.2];
[animation setFromValue:1];
[animation setToValue:0];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
return animation;
}
- (IBAction)setupGroup1:(id)sender
{
var contentView = [group1Box contentView];
var hasSubviews = [[contentView viewWithTag:1000] state] * 2,
customLayout = [[contentView viewWithTag:1001] state] * 4,
customDraw = [[contentView viewWithTag:1002] state] * 8,
customDrawSubviews = [[contentView viewWithTag:1003] state],
autoLayout = [[contentView viewWithTag:1004] state],
options = hasSubviews | customLayout | customDraw;
[leftView removeFromSuperview];
leftView = [self viewWithOptions:options];
if (leftView)
{
[leftView setFrame:CGRectMake(0, 0, 200, 200)];
[leftView setTag:1];
[animationSandbox addSubview:leftView];
}
if (hasSubviews)
[self addSubviewsToView:leftView autoLayout:(autoLayout && !customLayout) customDrawSubviews:customDrawSubviews];
}
- (IBAction)setupGroup2:(id)sender
{
var contentView = [group2Box contentView];
var hasSubviews = [[contentView viewWithTag:1000] state] * 2,
customLayout = [[contentView viewWithTag:1001] state] * 4,
customDraw = [[contentView viewWithTag:1002] state] * 8,
options = hasSubviews | customLayout | customDraw;
[rightView removeFromSuperview];
rightView = [self viewWithOptions:options];
if (rightView)
{
[rightView setFrame:CGRectMake(250, 0, 200, 200)];
[rightView setTag:2];
[animationSandbox addSubview:rightView];
}
if (leftView)
{
[leftView setTag:1];
[animationSandbox addSubview:leftView];
}
if (hasSubviews)
[self addSubviewsToView:rightView autoLayout:!customLayout customDrawSubviews:NO];
}
- (void)viewWithOptions:(CPInteger)options
{
var view = nil,
hasSubviews = NO;
switch (options)
{
case 0: view = [[ColorView alloc] initWithFrame:CGRectMakeZero()];
break;
case 2: view = [[ColorView alloc] initWithFrame:CGRectMakeZero()];
hasSubviews = YES;
break;
case 4:
case 6: view = [[CustomLayoutView alloc] initWithFrame:CGRectMakeZero()];
[view setBackgroundColor:[CPColor randomColor]];
hasSubviews = YES;
break;
case 12:
case 14: view = [[CustomLayoutDrawView alloc] initWithFrame:CGRectMakeZero()];
hasSubviews = YES;
break;
case 8: view = [[DrawView alloc] initWithFrame:CGRectMakeZero()];
break;
case 10: view = [[DrawView alloc] initWithFrame:CGRectMakeZero()];
hasSubviews = YES;
break;
}
var anims = [CPDictionary dictionaryWithObject:[self fadeOutAnimation] forKey:@"CPAnimationTriggerOrderOut"];
[view setAnimations:anims];
return view;
}
- (void)addSubviewsToView:(CPView)aView autoLayout:(BOOL)autoLayout customDrawSubviews:(BOOL)customDrawSubviews
{
var subViewClass = customDrawSubviews ? [DrawView class] : [ColorView class];
for (var i = 0; i < 5; i++)
{
var view = [[subViewClass alloc] initWithFrame:CGRectMake(50, i * 40, 80, 26)];
if (autoLayout)
[view setAutoresizingMask:CPViewWidthSizable|CPViewMinYMargin];
[aView addSubview:view];
}
}
@end
@implementation ColorView : CPView
{
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
[self setBackgroundColor:[CPColor randomColor]];
return self;
}
- (void)setFrameOrigin:(CGPoint)anOrigin
{
[super setFrameOrigin:anOrigin];
[[self superview] setNeedsDisplay:YES];
}
@end
@implementation DrawView : CPView
{
CPColor color @accessors;
}
- (id)initWithFrame:(CGRect)aFrame
{
self = [super initWithFrame:aFrame];
color = [CPColor randomColor];
return self;
}
- (void)drawRect:(CGRect)aRect
{
var context = [[CPGraphicsContext currentContext] graphicsPort],
bounds = [self bounds];
CGContextSetLineWidth(context, 2);
CGContextSetStrokeColor(context, [CPColor blackColor]);
CGContextSetFillColor(context, color);
CGContextBeginPath(context);
CGContextFillRect(context, bounds);
var height = CGRectGetHeight(bounds),
width = CGRectGetWidth(bounds);
CGContextStrokeLineSegments(context, [CGPointMake(10,0), CGPointMake(10, height),
CGPointMake(0, 10), CGPointMake(CGRectGetWidth(aRect), 10),
CGPointMake(width - 10, 0), CGPointMake(width - 10, height),
CGPointMake(0, height - 10), CGPointMake(width, height - 10)], 8);
}
@end
@implementation CustomLayoutView : CPView
{
}
- (void)layoutSubviews
{
var subviews = [self subviews],
count = [subviews count] - 1;
var dx = (CGRectGetWidth([self frame]) - 100) / count,
dy = (CGRectGetHeight([self frame]) - 26) / count
[subviews enumerateObjectsUsingBlock:function(view, idx, stop)
{
[view setFrameOrigin:CGPointMake(dx * idx, dy * idx)];
}];
}
@end
@implementation CustomLayoutDrawView : DrawView
{
}
- (void)layoutSubviews
{
var subviews = [self subviews],
count = [subviews count] - 1;
var dx = (CGRectGetWidth([self frame]) - 100) / count,
dy = (CGRectGetHeight([self frame]) - 26) / count
[subviews enumerateObjectsUsingBlock:function(view, idx, stop)
{
[view setFrameOrigin:CGPointMake(dx * idx, dy * idx)];
}];
}
@end
@implementation AnimationSandbox : CPView
{
}
- (void)drawRect:(CGRect)aRect
{
if ([[self subviews] count] < 2)
return;
var context = [[CPGraphicsContext currentContext] graphicsPort],
leftViewCenter = [[self viewWithTag:1] center],
rightViewCenter = [[self viewWithTag:2] center];
CGContextBeginPath(context);
CGContextMoveToPoint(context, leftViewCenter.x, leftViewCenter.y);
CGContextAddLineToPoint(context, rightViewCenter.x, rightViewCenter.y);
CGContextSetLineWidth(context, 2);
CGContextStrokePath(context);
}
@end