Fairly large ITTSW checkin.
authorMatthew Judy <mjudy@ithinksw.com>
Sun, 13 Apr 2003 15:19:26 +0000 (15:19 +0000)
committerMatthew Judy <mjudy@ithinksw.com>
Sun, 13 Apr 2003 15:19:26 +0000 (15:19 +0000)
- Created ITCutWindowEffect for simple appear and vanish without a
transition.  Better than using nil in the ITTSW.

- Moved the concept of effect progress out of the effects and into the
window itself, as a method in the ITWindowMobility protocol (formerly
known as ITWindowPositioning).

- Moved the logic to start the vanish timer into ITTSW's setVisibility
callback method.  If an effect sets the window's visibility to the
"Visible" state (having completely appeared, or completely canceled
vanishing), the timer will begin.

- Cleaned up a lot of code, and improved performance a bit.  Looks even
better than before on my old dual 450... who knows, it might be good on a
G3 :)

Stuff that's left in the Kit side of MT's statuswindows:

- Implement vanish timer.

- Finalize ITSlide*allyWindowEffect

- ( Warning... long. )
  Cancelling a window appearing should always use a reverse of the entry
effect.  But sometimes, a different effect may be desired for cancelling
a vanishing window than the reverse of the exit effect.  For example,
a window "Cuts" in, and begins to "Dissolve" out.  As of now, cancelling
the dissolve out will cause a very fast dissolve back in, however, to
match Apple's style, a simple "cut" back in would be desired.

  It's not as simple as always using an inverse of the entry effect to
cancel vanish.  Some effects are too radically different (consider trying to
cancel a "Pivot" exit with the inverse of a "SlideHorizontally".  It just
wouldn't work.

  Personally, i think it's actually better to keep the heuristic as it
is, and in the case of "Cut" in / "Dissolve" out, fuck the way Apple does
it... Ours looks better.  However, a third effect object could be
instantiated to handle the cancel vanish effect, which would be used for
that purpose if present.  This is a big maybe, and is definitely not a
showstopper for MT FCS.

ITCutWindowEffect.h [new file with mode: 0755]
ITCutWindowEffect.m [new file with mode: 0755]
ITDissolveWindowEffect.m
ITPivotWindowEffect.m
ITTransientStatusWindow.h
ITTransientStatusWindow.m
ITWindowEffect.h
ITWindowEffect.m
Showcase/Controller.m

diff --git a/ITCutWindowEffect.h b/ITCutWindowEffect.h
new file mode 100755 (executable)
index 0000000..4826001
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ *     ITKit
+ *  ITCutWindowEffect
+ *    Effect subclass which performs a simple cut in or out, with no transition.
+ *
+ *  Original Author : Matt Judy <mjudy@ithinksw.com>
+ *   Responsibility : Matt Judy <mjudy@ithinksw.com>
+ *
+ *  Copyright (c) 2002 - 2003 iThink Software.
+ *  All Rights Reserved
+ *
+ */
+
+
+#import <Cocoa/Cocoa.h>
+#import "ITWindowEffect.h"
+
+
+@interface ITCutWindowEffect : ITWindowEffect <ITWindowEffect> {
+
+}
+
+@end
diff --git a/ITCutWindowEffect.m b/ITCutWindowEffect.m
new file mode 100755 (executable)
index 0000000..a42fcc8
--- /dev/null
@@ -0,0 +1,42 @@
+#import "ITCutWindowEffect.h"
+#import "ITTransientStatusWindow.h"
+
+
+@implementation ITCutWindowEffect
+
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark APPEAR METHODS
+/*************************************************************************/
+
+- (void)performAppear
+{
+    [_window orderFront:self];
+    [self setWindowVisibility:ITTransientStatusWindowVisibleState];
+}
+
+- (void)cancelAppear
+{
+    [self performVanish];
+}
+
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark VANISH METHODS
+/*************************************************************************/
+
+- (void)performVanish
+{
+    [_window orderOut:self];
+    [self setWindowVisibility:ITTransientStatusWindowHiddenState];
+}
+
+- (void)cancelVanish
+{
+    [self performAppear];
+}
+
+
+@end
index 31aed00..fc2bd38 100755 (executable)
 #import "ITDissolveWindowEffect.h"
+#import "ITTransientStatusWindow.h"
+
+
+@interface ITDissolveWindowEffect (Private)
+- (void)performAppearFromProgress:(float)progress effectTime:(float)time;
+- (void)appearStep;
+- (void)appearFinish;
+- (void)performVanishFromProgress:(float)progress effectTime:(float)time;
+- (void)vanishStep;
+- (void)vanishFinish;
+@end
 
 
 @implementation ITDissolveWindowEffect
 
 
+/*************************************************************************/
+#pragma mark -
+#pragma mark APPEAR METHODS
+/*************************************************************************/
+
 - (void)performAppear
 {
-    NSLog(@"ITDissolveWindowEffect does not implement performAppear.");
+    [self setWindowVisibility:ITTransientStatusWindowAppearingState];
+    [self performAppearFromProgress:0.0 effectTime:_effectTime];
 }
 
-- (void)performVanish
+- (void)performAppearFromProgress:(float)progress effectTime:(float)time
+{
+    [_window setEffectProgress:progress];
+    _effectSpeed = (1.0 / (EFFECT_FPS * time));
+
+    if ( progress == 0.0 ) {
+        [_window setAlphaValue:0.0];
+    }
+
+    [_window orderFront:self];
+    _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
+                                                    target:self
+                                                  selector:@selector(appearStep)
+                                                  userInfo:nil
+                                                   repeats:YES];
+}
+
+- (void)appearStep
+{
+    float interFade = 0.0;
+    [_window setEffectProgress:([_window effectProgress] + _effectSpeed)];
+    [_window setEffectProgress:( ([_window effectProgress] < 1.0) ? [_window effectProgress] : 1.0)];
+    interFade = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
+    [_window setAlphaValue:interFade];
+
+    if ( [_window effectProgress] >= 1.0 ) {
+        [self appearFinish];
+    }
+}
+
+- (void)appearFinish
 {
-    NSLog(@"ITDissolveWindowEffect does not implement performVanish.");
+    [_effectTimer invalidate];
+    _effectTimer = nil;
+    [self setWindowVisibility:ITTransientStatusWindowVisibleState];
 }
 
 - (void)cancelAppear
 {
-    NSLog(@"ITWindowEffect does not implement cancelAppear.");
+    [self setWindowVisibility:ITTransientStatusWindowVanishingState];
+
+    [_effectTimer invalidate];
+    _effectTimer = nil;
+
+    [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
+}
+
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark VANISH METHODS
+/*************************************************************************/
+
+- (void)performVanish
+{
+    [self setWindowVisibility:ITTransientStatusWindowVanishingState];
+    [self performVanishFromProgress:1.0 effectTime:_effectTime];
+}
+
+- (void)performVanishFromProgress:(float)progress effectTime:(float)time
+{
+    [_window setEffectProgress:progress];
+    _effectSpeed = (1.0 / (EFFECT_FPS * time));
+    if ( progress == 1.0 ) {
+        [_window setAlphaValue:1.0];
+    }
+
+    [_window orderFront:self];
+    _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
+                                                    target:self
+                                                  selector:@selector(vanishStep)
+                                                  userInfo:nil
+                                                   repeats:YES];
+}
+
+- (void)vanishStep
+{
+    float interFade = 1.0;
+    [_window setEffectProgress:([_window effectProgress] - _effectSpeed)];
+    [_window setEffectProgress:( ([_window effectProgress] > 0.0) ? [_window effectProgress] : 0.0)];
+    interFade = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
+    [_window setAlphaValue:interFade];
+
+    if ( [_window effectProgress] <= 0.0 ) {
+        [self vanishFinish];
+    }
+}
+
+- (void)vanishFinish
+{
+    [_effectTimer invalidate];
+    _effectTimer = nil;
+    [_window orderOut:self];
+    [_window setAlphaValue:1.0];
+    [self setWindowVisibility:ITTransientStatusWindowHiddenState];
 }
 
 - (void)cancelVanish
 {
-    NSLog(@"ITDissolveWindowEffect does not implement cancelVanish.");
+    [self setWindowVisibility:ITTransientStatusWindowVanishingState];
+
+    [_effectTimer invalidate];
+    _effectTimer = nil;
+
+    [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
 }
 
 
index 2c87f68..95c1040 100755 (executable)
@@ -6,14 +6,22 @@
 @interface ITPivotWindowEffect (Private)
 - (void)setPivot:(float)angle;
 - (void)performAppearFromProgress:(float)progress effectTime:(float)time;
-- (void)performVanishFromProgress:(float)progress effectTime:(float)time;
+- (void)appearStep;
 - (void)appearFinish;
+- (void)performVanishFromProgress:(float)progress effectTime:(float)time;
+- (void)vanishStep;
 - (void)vanishFinish;
 @end
 
 
 @implementation ITPivotWindowEffect
 
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark APPEAR METHODS
+/*************************************************************************/
+
 - (void)performAppear
 {
     [self setWindowVisibility:ITTransientStatusWindowAppearingState];
@@ -22,7 +30,7 @@
 
 - (void)performAppearFromProgress:(float)progress effectTime:(float)time
 {
-    _effectProgress = progress;
+    [_window setEffectProgress:progress];
     _effectSpeed = (1.0 / (EFFECT_FPS * time));
     
     if ( progress == 0.0 ) {
                                                    repeats:YES];
 }
 
-- (void)performVanish
+- (void)appearStep
 {
-    [self setWindowVisibility:ITTransientStatusWindowVanishingState];
-    [self performVanishFromProgress:1.0 effectTime:_effectTime];
-}
+    float interPivot = 0.0;
+    [_window setEffectProgress:([_window effectProgress] + _effectSpeed)];
+    [_window setEffectProgress:( ([_window effectProgress] < 1.0) ? [_window effectProgress] : 1.0)];
+    interPivot = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
+    [self setPivot:((interPivot * 45) + 315)];
+    [_window setAlphaValue:interPivot];
 
-- (void)performVanishFromProgress:(float)progress effectTime:(float)time
-{
-    _effectProgress = progress;
-    _effectSpeed = (1.0 / (EFFECT_FPS * time));
-    if ( progress == 1.0 ) {
-        [self setPivot:0.0];
-        [_window setAlphaValue:1.0];
+    if ( [_window effectProgress] >= 1.0 ) {
+        [self appearFinish];
     }
-
-    [_window orderFront:self];
-    _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
-                                                    target:self
-                                                  selector:@selector(vanishStep)
-                                                  userInfo:nil
-                                                   repeats:YES];
 }
 
-- (void)cancelAppear
+- (void)appearFinish
 {
-    [self setWindowVisibility:ITTransientStatusWindowVanishingState];
-    
     [_effectTimer invalidate];
     _effectTimer = nil;
-    
-    [self performVanishFromProgress:_effectProgress effectTime:(_effectTime / 3.5)];
+    [self setWindowVisibility:ITTransientStatusWindowVisibleState];
 }
 
-- (void)cancelVanish
+- (void)cancelAppear
 {
-    [self setWindowVisibility:ITTransientStatusWindowAppearingState];
+    [self setWindowVisibility:ITTransientStatusWindowVanishingState];
 
     [_effectTimer invalidate];
     _effectTimer = nil;
 
-    [self performAppearFromProgress:_effectProgress effectTime:(_effectTime / 3.5)];
+    [self performVanishFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
 }
 
-- (void)appearStep
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark VANISH METHODS
+/*************************************************************************/
+
+- (void)performVanish
 {
-    float interPivot = 0.0;
-    _effectProgress += _effectSpeed;
-    _effectProgress = (_effectProgress < 1.0 ? _effectProgress : 1.0);
-    interPivot = (( sin((_effectProgress * pi) - (pi / 2)) + 1 ) / 2);
-    [self setPivot:((interPivot * 45) + 315)];
-    [_window setAlphaValue:interPivot];
+    [self setWindowVisibility:ITTransientStatusWindowVanishingState];
+    [self performVanishFromProgress:1.0 effectTime:_effectTime];
+}
 
-    if ( _effectProgress >= 1.0 ) {
-        [self appearFinish];
+- (void)performVanishFromProgress:(float)progress effectTime:(float)time
+{
+    [_window setEffectProgress:progress];
+    _effectSpeed = (1.0 / (EFFECT_FPS * time));
+    if ( progress == 1.0 ) {
+        [self setPivot:0.0];
+        [_window setAlphaValue:1.0];
     }
+
+    [_window orderFront:self];
+    _effectTimer = [NSTimer scheduledTimerWithTimeInterval:(1.0 / EFFECT_FPS)
+                                                    target:self
+                                                  selector:@selector(vanishStep)
+                                                  userInfo:nil
+                                                   repeats:YES];
 }
 
 - (void)vanishStep
 {
     float interPivot = 1.0;
-    _effectProgress -= _effectSpeed;
-    _effectProgress = (_effectProgress > 0.0 ? _effectProgress : 0.0);
-    interPivot = (( sin((_effectProgress * pi) - (pi / 2)) + 1 ) / 2);
+    [_window setEffectProgress:([_window effectProgress] - _effectSpeed)];
+    [_window setEffectProgress:( ([_window effectProgress] > 0.0) ? [_window effectProgress] : 0.0)];
+    interPivot = (( sin(([_window effectProgress] * pi) - (pi / 2)) + 1 ) / 2);
     [self setPivot:((interPivot * 45) + 315)];
     [_window setAlphaValue:interPivot];
 
-    if ( _effectProgress <= 0.0 ) {
+    if ( [_window effectProgress] <= 0.0 ) {
         [self vanishFinish];
     }
 }
 
-- (void)appearFinish
+- (void)vanishFinish
 {
     [_effectTimer invalidate];
     _effectTimer = nil;
-    [self setWindowVisibility:ITTransientStatusWindowVisibleState];
+    [_window orderOut:self];
+    [_window setAlphaValue:1.0];
+    [self setWindowVisibility:ITTransientStatusWindowHiddenState];
 }
 
-- (void)vanishFinish
+- (void)cancelVanish
 {
+    [self setWindowVisibility:ITTransientStatusWindowAppearingState];
+
     [_effectTimer invalidate];
     _effectTimer = nil;
-    [self setWindowVisibility:ITTransientStatusWindowHiddenState];
+
+    [self performAppearFromProgress:[_window effectProgress] effectTime:(_effectTime / 3.5)];
 }
 
+
+/*************************************************************************/
+#pragma mark -
+#pragma mark PRIVATE METHOD IMPLEMENTATIONS
+/*************************************************************************/
+
 - (void)setPivot:(float)angle
 {
     float degAngle = (angle * (pi / 180));
index 90d74c6..dcbe360 100755 (executable)
@@ -43,7 +43,7 @@ typedef enum {
 } ITTransientStatusWindowBackgroundType;
 
 
-@interface ITTransientStatusWindow : NSWindow <ITWindowPositioning , ITWindowVisibility> {
+@interface ITTransientStatusWindow : NSWindow <ITWindowPositioning , ITWindowMotility> {
 
     ITWindowVisibilityState                _visibilityState;
     ITTransientStatusWindowExitMode        _exitMode;
@@ -51,6 +51,7 @@ typedef enum {
     ITTransientStatusWindowBackgroundType  _backgroundType;
     ITWindowEffect                        *_entryEffect;
     ITWindowEffect                        *_exitEffect;
+    double                                 _effectProgress;
     ITVerticalWindowPosition               _verticalPosition;
     ITHorizontalWindowPosition             _horizontalPosition;
     float                                  _screenPadding;
@@ -90,6 +91,9 @@ typedef enum {
 - (ITHorizontalWindowPosition)horizontalPosition;
 - (void)setHorizontalPosition:(ITHorizontalWindowPosition)newPosition;
 
+- (float)effectProgress;
+- (void)setEffectProgress:(float)newProgress;
+
 - (ITWindowEffect *)entryEffect;
 - (void)setEntryEffect:(ITWindowEffect *)newEffect;
 
index b06fb3a..6cb33a3 100755 (executable)
@@ -156,13 +156,7 @@ static ITTransientStatusWindow *staticWindow = nil;
 {
     if ( _visibilityState == ITTransientStatusWindowHiddenState ) {
          // Window is hidden.  Appear as normal, and start the timer.
-        if ( _entryEffect == nil ) {
-            [self orderFront:self];
-            _visibilityState = ITTransientStatusWindowVisibleState;
-        } else {
-            [_entryEffect performAppear];
-        }
-        [self startVanishTimer];
+        [_entryEffect performAppear];
     } else if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
          // Window is completely visible.  Simply reset the timer.
         [self startVanishTimer];
@@ -170,13 +164,7 @@ static ITTransientStatusWindow *staticWindow = nil;
          // Window is on its way in.  Do nothing.
     } else if ( _visibilityState == ITTransientStatusWindowVanishingState ) {
         // Window is on its way out.  Cancel the vanish.
-        if ( _exitEffect == nil ) {
-            [self orderFront:self];
-            _visibilityState = ITTransientStatusWindowVisibleState;
-        } else {
-            [_exitEffect cancelVanish];
-        }
-        [self startVanishTimer];
+        [_exitEffect cancelVanish];
     }
 }
 
@@ -184,13 +172,7 @@ static ITTransientStatusWindow *staticWindow = nil;
 {
     if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
         // Window is totally visible.  Perform exit effect.
-        if ( _exitEffect == nil ) {
-            [self orderOut:self];
-            _visibilityState = ITTransientStatusWindowHiddenState;
-        } else {
-            [_exitEffect performVanish];
-        }
-        [self startVanishTimer];
+        [_exitEffect performVanish];
     } else if ( _visibilityState == ITTransientStatusWindowHiddenState ) {
         // Window is hidden.  Do nothing.
     } else if ( _visibilityState == ITTransientStatusWindowAppearingState ) {
@@ -209,6 +191,10 @@ static ITTransientStatusWindow *staticWindow = nil;
 - (void)setVisibilityState:(ITWindowVisibilityState)newState
 {
     _visibilityState = newState;
+    
+    if ( _visibilityState == ITTransientStatusWindowVisibleState ) {
+        [self startVanishTimer];
+    }
 }
 
 - (ITTransientStatusWindowExitMode)exitMode
@@ -264,6 +250,16 @@ static ITTransientStatusWindow *staticWindow = nil;
     _horizontalPosition = newPosition;
 }
 
+- (float)effectProgress
+{
+    return _effectProgress;
+}
+
+- (void)setEffectProgress:(float)newProgress
+{
+    _effectProgress = newProgress;
+}
+
 - (float)screenPadding
 {
     return _screenPadding;
@@ -332,7 +328,8 @@ static ITTransientStatusWindow *staticWindow = nil;
 
 - (void)startVanishTimer
 {
-
+    // start timer, if appropriate
+    // if timer already exists, restart it.
 }
 
 @end
index 2cc6c45..71852e2 100755 (executable)
@@ -15,6 +15,7 @@
 #import <Cocoa/Cocoa.h>
 #import "ITWindowPositioning.h"
 
+@class ITTransientStatusWindow;
 
 #define EFFECT_FPS 30.0
 #define DEFAULT_EFFECT_TIME 0.75
@@ -36,18 +37,19 @@ typedef enum {
 @end
 
 
-@protocol ITWindowVisibility
+@protocol ITWindowMotility
 - (ITWindowVisibilityState)visibilityState;
 - (void)setVisibilityState:(ITWindowVisibilityState)newState;
+- (float)effectProgress;
+- (void)setEffectProgress:(float)newProgress;
 @end
 
 
 @interface ITWindowEffect : NSObject <ITWindowEffect>
 {
-    NSWindow                   *_window;
+    ITTransientStatusWindow    *_window;
     float                       _effectTime;
     float                       _effectSpeed;
-    double                      _effectProgress;
     ITVerticalWindowPosition    _verticalPosition;
     ITHorizontalWindowPosition  _horizontalPosition;
     NSTimer                    *_effectTimer;
index d485df5..752742b 100755 (executable)
@@ -11,7 +11,6 @@
     
         _window         = [window retain];
         _effectTime     = DEFAULT_EFFECT_TIME;
-        _effectProgress = 0.00;
         _effectTimer    = nil;
 
         if ( [window conformsToProtocol:@protocol(ITWindowPositioning)] ) {
@@ -40,7 +39,7 @@
 
 - (void)setWindowVisibility:(ITWindowVisibilityState)visibilityState
 {
-    if ( [_window conformsToProtocol:@protocol(ITWindowVisibility)] ) {
+    if ( [_window conformsToProtocol:@protocol(ITWindowMotility)] ) {
        // Cast so the compiler won't gripe
         [(ITTransientStatusWindow *)_window setVisibilityState:visibilityState];
     } else {
index 16b5c0b..f2680bd 100755 (executable)
@@ -2,6 +2,8 @@
 #import "ITTransientStatusWindow.h"
 #import "ITTextField.h"
 #import "ITPivotWindowEffect.h"
+#import "ITDissolveWindowEffect.h"
+#import "ITCutWindowEffect.h"
 
 #define SW_PAD    24.0
 #define SW_SPACE  24.0
 
     [[statusWindow contentView] setNeedsDisplay:YES];
 
-    [statusWindow setEntryEffect:[[ITPivotWindowEffect alloc] initWithWindow:statusWindow]];
-    [statusWindow setExitEffect:[[ITPivotWindowEffect alloc] initWithWindow:statusWindow]];
+//    [statusWindow setEntryEffect:[[ITPivotWindowEffect alloc] initWithWindow:statusWindow]];
+//    [statusWindow setExitEffect:[[ITPivotWindowEffect alloc] initWithWindow:statusWindow]];
+    [statusWindow setEntryEffect:[[ITCutWindowEffect alloc]      initWithWindow:statusWindow]];
+    [statusWindow setExitEffect: [[ITDissolveWindowEffect alloc] initWithWindow:statusWindow]];
 }
 
 - (IBAction)toggleStatusWindow:(id)sender