jens@16: // jens@16: // MYAnimatingSplitView.m jens@16: // Cloudy jens@16: // jens@16: // Created by Jens Alfke on 7/10/08. jens@16: // Copyright 2008 Jens Alfke. All rights reserved. jens@16: // jens@16: jens@16: #import "MYAnimatingSplitView.h" jens@16: #import "DateUtils.h" jens@16: jens@16: jens@16: #define kDefaultAnimationTime 0.3 jens@16: jens@16: jens@16: @interface MYAnimatingSplitView () jens@16: @property (readwrite) BOOL isLiveResizing; jens@16: @end jens@16: jens@16: jens@16: @implementation MYAnimatingSplitView jens@16: jens@16: jens@16: @synthesize animationTime=_animationTime; jens@16: jens@16: jens@16: - (void) my_animateDividerToPosition: (float)pos jens@16: { jens@16: const NSTimeInterval maxTime = _animationTime ?: kDefaultAnimationTime; jens@16: jens@16: NSTimeInterval startTime = TimeIntervalSinceBoot(); jens@16: float startPos = self.dividerPosition; jens@16: const NSTimeInterval animationTime = maxTime * fabs(pos-startPos)/self.frame.size.height; jens@16: float fract; jens@16: do { jens@16: fract = (float) MIN(1.0, (TimeIntervalSinceBoot()-startTime)/animationTime); jens@16: float curPos = startPos + fract*(pos-startPos); jens@16: [self setPosition: curPos ofDividerAtIndex: 0]; jens@16: [self.window displayIfNeeded]; jens@16: [self.window update]; jens@16: }while( fract < 1.0 ); jens@16: } jens@16: jens@16: jens@16: - (void) getDividerPositionMin: (float*)outMin max: (float*)outMax jens@16: { jens@16: *outMin = [self.delegate splitView: self jens@16: constrainMinCoordinate: [self minPossiblePositionOfDividerAtIndex: 0] jens@16: ofSubviewAt: 0]; jens@16: *outMax = [self.delegate splitView: self jens@16: constrainMaxCoordinate: [self maxPossiblePositionOfDividerAtIndex: 0] jens@16: ofSubviewAt: 0]; jens@16: } jens@16: jens@16: - (float) dividerPosition jens@16: { jens@16: return NSMaxY([[self.subviews objectAtIndex: 0] frame]); jens@16: } jens@16: jens@16: - (void) setDividerPosition: (float)pos jens@16: { jens@16: float minPos,maxPos; jens@16: [self getDividerPositionMin: &minPos max: &maxPos]; jens@16: NSView *targetView = [[self subviews] objectAtIndex:0]; jens@16: NSRect startFrame = [targetView frame]; jens@16: jens@16: // First uncollapse any collapsed subview: jens@16: if( [self isSubviewCollapsed: targetView] ) jens@16: [self setPosition: minPos ofDividerAtIndex: 0]; jens@16: else if( startFrame.size.height > maxPos ) jens@16: [self setPosition: maxPos ofDividerAtIndex: 0]; jens@16: // Now animate: jens@16: [self my_animateDividerToPosition: pos]; jens@16: } jens@16: jens@16: - (float) dividerFractionalPosition jens@16: { jens@16: float minPos, maxPos, pos=self.dividerPosition; jens@16: [self getDividerPositionMin: &minPos max: &maxPos]; jens@16: float denom = maxPos-minPos; jens@16: if( denom<=0 ) jens@17: return 0.0f; jens@16: else jens@16: return (pos-minPos)/denom; jens@16: } jens@16: jens@16: - (void) setDividerFractionalPosition: (float)fract jens@16: { jens@16: float minPos, maxPos; jens@16: [self getDividerPositionMin: &minPos max: &maxPos]; jens@16: self.dividerPosition = roundf( minPos + fract*(maxPos-minPos) ); jens@16: } jens@16: jens@16: jens@16: - (void) collapseSubviewAtIndex: (int)index animate: (BOOL)animate jens@16: { jens@16: if( ! [self isSubviewCollapsed: [self.subviews objectAtIndex: index]] ) { jens@16: float pos = index==0 ?[self minPossiblePositionOfDividerAtIndex: 0] jens@16: :[self maxPossiblePositionOfDividerAtIndex: 0]; jens@16: if( animate ) jens@16: [self my_animateDividerToPosition: pos]; jens@16: else jens@16: [self setPosition: pos ofDividerAtIndex: 0]; jens@16: } jens@16: } jens@16: jens@16: - (void) collapseSubviewAtIndex: (int)index jens@16: { jens@16: [self collapseSubviewAtIndex: index animate: YES]; jens@16: } jens@16: jens@16: jens@16: jens@16: - (BOOL) isLiveResizing jens@16: { jens@16: return _isLiveResizing; jens@16: } jens@16: jens@16: - (void) setIsLiveResizing: (BOOL)inLiveResize jens@16: { jens@16: _isLiveResizing = inLiveResize; jens@16: id delegate = self.delegate; jens@16: if( [delegate respondsToSelector: @selector(splitView:inLiveResize:)] ) jens@16: [delegate splitView: self inLiveResize: inLiveResize]; jens@16: } jens@16: jens@16: jens@16: - (void)viewWillStartLiveResize jens@16: { jens@16: [super viewWillStartLiveResize]; jens@16: self.isLiveResizing = YES; jens@16: } jens@16: jens@16: - (void) viewDidEndLiveResize jens@16: { jens@16: [super viewDidEndLiveResize]; jens@16: self.isLiveResizing = NO; jens@16: } jens@16: jens@16: @end