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