API  0.9.6
 All Classes Files Functions Variables Macros Groups Pages
CPViewAnimation.j
Go to the documentation of this file.
1 /*
2  * CPViewAnimation.j
3  * AppKit
4  *
5  * Created by Klaas Pieter Annema on September 3, 2009.
6  * Copyright 2009, Sofa BV
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 
25 CPViewAnimationTargetKey = @"CPViewAnimationTargetKey";
26 CPViewAnimationStartFrameKey = @"CPViewAnimationStartFrameKey";
27 CPViewAnimationEndFrameKey = @"CPViewAnimationEndFrameKey";
28 CPViewAnimationEffectKey = @"CPViewAnimationEffectKey";
29 
30 CPViewAnimationFadeInEffect = @"CPViewAnimationFadeInEffect";
31 CPViewAnimationFadeOutEffect = @"CPViewAnimationFadeOutEffect";
32 
40 @implementation CPViewAnimation : CPAnimation
41 {
42  CPArray _viewAnimations;
43 }
44 
68 - (id)initWithViewAnimations:(CPArray)viewAnimations
69 {
70  if (self = [super initWithDuration:0.5 animationCurve:CPAnimationLinear])
71  {
72  [self setViewAnimations:viewAnimations];
73  }
74 
75  return self;
76 }
77 
78 - (void)startAnimation
79 {
80  var animationIndex = [_viewAnimations count];
81  while (animationIndex--)
82  {
83  var dictionary = [_viewAnimations objectAtIndex:animationIndex],
84  view = [self _targetView:dictionary],
85  startFrame = [self _startFrame:dictionary];
86 
87  [view setFrame:startFrame];
88 
89  var effect = [self _effect:dictionary];
90  if (effect === CPViewAnimationFadeInEffect)
91  {
92  [view setAlphaValue:0.0];
93  [self _targetView:view setHidden:NO];
94  }
95  else if (effect === CPViewAnimationFadeOutEffect)
96  [view setAlphaValue:1.0];
97  }
98 
99  [super startAnimation];
100 }
101 
102 - (void)setCurrentProgress:(CPAnimationProgress)progress
103 {
104  [super setCurrentProgress:progress];
105 
106  var animationIndex = [_viewAnimations count];
107  while (animationIndex--)
108  {
109  var dictionary = [_viewAnimations objectAtIndex:animationIndex],
110  view = [self _targetView:dictionary],
111  startFrame = [self _startFrame:dictionary],
112  endFrame = [self _endFrame:dictionary],
113  differenceFrame = _CGRectMakeZero(),
114  value = [super currentValue];
115 
116  differenceFrame.origin.x = endFrame.origin.x - startFrame.origin.x;
117  differenceFrame.origin.y = endFrame.origin.y - startFrame.origin.y;
118  differenceFrame.size.width = endFrame.size.width - startFrame.size.width;
119  differenceFrame.size.height = endFrame.size.height - startFrame.size.height;
120 
121  var intermediateFrame = _CGRectMakeZero();
122  intermediateFrame.origin.x = startFrame.origin.x + differenceFrame.origin.x * value;
123  intermediateFrame.origin.y = startFrame.origin.y + differenceFrame.origin.y * value;
124  intermediateFrame.size.width = startFrame.size.width + differenceFrame.size.width * value;
125  intermediateFrame.size.height = startFrame.size.height + differenceFrame.size.height * value;
126 
127  [view setFrame:intermediateFrame];
128 
129  // Update the view's alpha value
130  var effect = [self _effect:dictionary];
131  if (effect === CPViewAnimationFadeInEffect)
132  [view setAlphaValue:1.0 * value];
133  else if (effect === CPViewAnimationFadeOutEffect)
134  [view setAlphaValue:1.0 + ( 0.0 - 1.0 ) * value];
135 
136  if (progress === 1.0)
137  [self _targetView:view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
138  }
139 }
140 
141 - (void)stopAnimation
142 {
143  var animationIndex = [_viewAnimations count];
144  while (animationIndex--)
145  {
146  var dictionary = [_viewAnimations objectAtIndex:animationIndex],
147  view = [self _targetView:dictionary],
148  endFrame = [self _endFrame:dictionary];
149 
150  [view setFrame:endFrame];
151 
152  var effect = [self _effect:dictionary];
153  if (effect === CPViewAnimationFadeInEffect)
154  [view setAlphaValue:1.0];
155  else if (effect === CPViewAnimationFadeOutEffect)
156  [view setAlphaValue:0.0];
157 
158  [self _targetView:view setHidden:_CGRectIsNull(endFrame) || [view alphaValue] === 0.0];
159  }
160 
161  [super stopAnimation];
162 }
163 
164 - (void)_targetView:(id)theView setHidden:(BOOL)isHidden
165 {
166  if ([theView isKindOfClass:[CPWindow class]])
167  {
168  if (isHidden)
169  [theView orderOut:self];
170  else
171  [theView orderFront:self];
172  }
173  else
174  [theView setHidden:isHidden];
175 }
176 
177 - (id)_targetView:(CPDictionary)dictionary
178 {
179  var targetView = [dictionary valueForKey:CPViewAnimationTargetKey];
180  if (!targetView)
181  [CPException raise:CPInternalInconsistencyException reason:[CPString stringWithFormat:@"view animation: %@ does not have a target view", [dictionary description]]];
182 
183  return targetView;
184 }
185 
186 - (CGRect)_startFrame:(CPDictionary)dictionary
187 {
188  var startFrame = [dictionary valueForKey:CPViewAnimationStartFrameKey];
189  if (!startFrame)
190  return [[self _targetView:dictionary] frame];
191 
192  return startFrame;
193 }
194 
195 - (CGRect)_endFrame:(CPDictionary)dictionary
196 {
197  var endFrame = [dictionary valueForKey:CPViewAnimationEndFrameKey];
198  if (!endFrame)
199  return [[self _targetView:dictionary] frame];
200 
201  return endFrame;
202 }
203 
204 - (CPString)_effect:(CPDictionary)dictionary
205 {
206  return [dictionary valueForKey:CPViewAnimationEffectKey];
207 }
208 
209 - (CPArray)viewAnimations
210 {
211  return _viewAnimations;
212 }
213 
219 - (void)setViewAnimations:(CPArray)viewAnimations
220 {
221  if (viewAnimations != _viewAnimations)
222  {
223  [self stopAnimation];
224  _viewAnimations = [viewAnimations copy];
225  }
226 }
227 
228 @end