MYAnimatingSplitView.m
author Jens Alfke <jens@mooseyard.com>
Sat Mar 28 09:39:31 2009 -0700 (2009-03-28)
changeset 21 88d7e2455a7f
parent 16 ce9c83f7ec14
permissions -rw-r--r--
(merge)
     1 //
     2 //  MYAnimatingSplitView.m
     3 //  Cloudy
     4 //
     5 //  Created by Jens Alfke on 7/10/08.
     6 //  Copyright 2008 Jens Alfke. All rights reserved.
     7 //
     8 
     9 #import "MYAnimatingSplitView.h"
    10 #import "DateUtils.h"
    11 
    12 
    13 #define kDefaultAnimationTime 0.3
    14 
    15 
    16 @interface MYAnimatingSplitView ()
    17 @property (readwrite) BOOL isLiveResizing;
    18 @end
    19 
    20 
    21 @implementation MYAnimatingSplitView
    22 
    23 
    24 @synthesize animationTime=_animationTime;
    25 
    26 
    27 - (void) my_animateDividerToPosition: (float)pos
    28 {
    29     const NSTimeInterval maxTime = _animationTime ?: kDefaultAnimationTime;
    30     
    31     NSTimeInterval startTime = TimeIntervalSinceBoot();
    32     float startPos = self.dividerPosition;
    33     const NSTimeInterval animationTime = maxTime * fabs(pos-startPos)/self.frame.size.height;
    34     float fract;
    35     do {
    36         fract = (float) MIN(1.0, (TimeIntervalSinceBoot()-startTime)/animationTime);
    37         float curPos = startPos + fract*(pos-startPos);
    38         [self setPosition: curPos ofDividerAtIndex: 0];
    39         [self.window displayIfNeeded];
    40         [self.window update];
    41     }while( fract < 1.0 );
    42 }
    43 
    44 
    45 - (void) getDividerPositionMin: (float*)outMin max: (float*)outMax
    46 {
    47     *outMin = [self.delegate splitView: self 
    48                     constrainMinCoordinate: [self minPossiblePositionOfDividerAtIndex: 0]
    49                     ofSubviewAt: 0];
    50     *outMax = [self.delegate splitView: self 
    51                     constrainMaxCoordinate: [self maxPossiblePositionOfDividerAtIndex: 0]
    52                     ofSubviewAt: 0];
    53 }
    54 
    55 - (float) dividerPosition
    56 {
    57     return NSMaxY([[self.subviews objectAtIndex: 0] frame]);
    58 }
    59 
    60 - (void) setDividerPosition: (float)pos
    61 {
    62     float minPos,maxPos;
    63     [self getDividerPositionMin: &minPos max: &maxPos];
    64     NSView *targetView = [[self subviews] objectAtIndex:0];
    65     NSRect startFrame = [targetView frame];
    66 
    67     // First uncollapse any collapsed subview:
    68     if( [self isSubviewCollapsed: targetView] )
    69         [self setPosition: minPos ofDividerAtIndex: 0];
    70     else if( startFrame.size.height > maxPos )
    71         [self setPosition: maxPos ofDividerAtIndex: 0];
    72     // Now animate:
    73     [self my_animateDividerToPosition: pos];
    74 }
    75 
    76 - (float) dividerFractionalPosition
    77 {
    78     float minPos, maxPos, pos=self.dividerPosition;
    79     [self getDividerPositionMin: &minPos max: &maxPos];
    80     float denom = maxPos-minPos;
    81     if( denom<=0 )
    82         return 0.0f;
    83     else
    84         return (pos-minPos)/denom;
    85 }
    86 
    87 - (void) setDividerFractionalPosition: (float)fract
    88 {
    89     float minPos, maxPos;
    90     [self getDividerPositionMin: &minPos max: &maxPos];
    91     self.dividerPosition = roundf( minPos + fract*(maxPos-minPos) );
    92 }
    93 
    94 
    95 - (void) collapseSubviewAtIndex: (int)index animate: (BOOL)animate
    96 {
    97     if( ! [self isSubviewCollapsed: [self.subviews objectAtIndex: index]] ) {
    98         float pos = index==0 ?[self minPossiblePositionOfDividerAtIndex: 0]
    99                              :[self maxPossiblePositionOfDividerAtIndex: 0];
   100         if( animate )
   101             [self my_animateDividerToPosition: pos];
   102         else
   103             [self setPosition: pos ofDividerAtIndex: 0];
   104     }
   105 }
   106 
   107 - (void) collapseSubviewAtIndex: (int)index
   108 {
   109     [self collapseSubviewAtIndex: index animate: YES];
   110 }
   111 
   112 
   113 
   114 - (BOOL) isLiveResizing
   115 {
   116     return _isLiveResizing;
   117 }
   118 
   119 - (void) setIsLiveResizing: (BOOL)inLiveResize
   120 {
   121     _isLiveResizing = inLiveResize;
   122     id delegate = self.delegate;
   123     if( [delegate respondsToSelector: @selector(splitView:inLiveResize:)] )
   124         [delegate splitView: self inLiveResize: inLiveResize];
   125 }
   126 
   127 
   128 - (void)viewWillStartLiveResize
   129 {
   130     [super viewWillStartLiveResize];
   131     self.isLiveResizing = YES;
   132 }
   133 
   134 - (void) viewDidEndLiveResize
   135 {
   136     [super viewDidEndLiveResize];
   137     self.isLiveResizing = NO;
   138 }
   139 
   140 @end