27- (id)initWithFrame:(NSRect)frame {
28 self = [
super initWithFrame:frame];
61- (void)setCoupled:(BOOL)flag {
75 return [[
self couplingSplitView] isOpaque];
79- (void)setHidden:(BOOL)flag {
80 if ([
self isHidden]!=flag) {
82 [
self RB___setHidden:flag];
100 id result = [
self superview];
109 id result = [
self superview];
120 while ((sv = [sv superview])&&[sv isKindOfClass:[
RBSplitView class]]) {
128 return [[
self splitView] isHorizontal];
133- (void)setTag:(NSInteger)theTag {
141- (void)setIdentifier:(NSString*)aString {
142 [identifier autorelease];
153 return [identifier length]>0?[NSString stringWithFormat:@"%@(%@)",[
super description],identifier]:[
super description];
160 return sv?[[sv subviews] indexOfObjectIdenticalTo:self]:0;
163- (void)setPosition:(NSUInteger)newPosition {
167 [
self removeFromSuperviewWithoutNeedingDisplay];
168 NSArray* subviews = [sv subviews];
169 if (newPosition>=[subviews
count]) {
180 return [
self RB___visibleDimension]<=0.0;
185 return [
self RB___visibleDimension]>([
self canCollapse]?0.0:minDimension);
195 animationData* anim = [
self RB___animationData:NO resize:NO];
207 if ([sv RB___numberOfSubviews]<2) {
212 result = [delegate splitView:sv canCollapse:self];
219- (void)setCanCollapse:(BOOL)flag {
229 return [
self RB___expandAndSetToMinimum:NO];
238 return [
self RB___collapse];
244 return [
self collapseWithAnimation:YES withResize:YES];
250 return [
self expandWithAnimation:YES withResize:YES];
259 if (animate&&[
self RB___animationData:YES resize:resize]) {
260 [
self RB___clearResponder];
261 [
self RB___stepAnimation];
264 [
self RB___collapse];
273 if (animate&&[
self RB___animationData:YES resize:resize]) {
274 [
self RB___stepAnimation];
277 [
self RB___expandAndSetToMinimum:NO];
295- (void)setMinDimension:(CGFloat)newMinDimension andMaxDimension:(CGFloat)newMaxDimension {
297 if (newMaxDimension<1.0) {
301 CGFloat dim = [
self dimension];
303 [[
self splitView] setMustAdjust];
310 CGFloat dim = [
self RB___visibleDimension];
312 dim = [[
self splitView] RB___dimensionWithoutDividers]*
fraction;
324- (void)setDimension:(CGFloat)value {
331 NSSize
size = [
self frame].size;
336 [
self setFrameSize:size];
347- (void)drawRect:(NSRect)rect {
352 NSRectFillUsingOperation(rect,NSCompositeSourceOver);
355 if ([del respondsToSelector:
@selector(
splitView:willDrawSubview:inRect:)]) {
356 [del splitView:sv willDrawSubview:self inRect:rect];
365 if ([sv mustAdjust]) {
379- (void)setAutoresizesSubviews:(BOOL)flag {
383- (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
387 NSRect frame = [
self frame];
388 CGFloat dim =
DIM(frame.size);
389 CGFloat other =
OTHER(frame.size);
391 animationData* anim = [
self RB___animationData:NO resize:NO];
400 [
super resizeSubviewsWithOldSize:oldBoundsSize];
410- (CGFloat)changeDimensionBy:(CGFloat)increment mayCollapse:(BOOL)mayCollapse move:(BOOL)move {
412 if (!sv||(fabs(increment)<1.0)) {
416 NSRect frame = [
self frame];
417 CGFloat olddim =
DIM(frame.size);
418 CGFloat newdim =
MAX(0.0,olddim+increment);
423 return [
self RB___collapse];
427 }
else if (newdim>olddim) {
431 newdim =
MAX(newdim,[
self RB___expandAndSetToMinimum:YES]);
440 if ((
int)newdim!=(
int)olddim) {
442 increment = newdim-olddim;
443 DIM(frame.size) = newdim;
445 DIM(frame.origin) -= increment;
449 [
super setFrame:frame];
453 return newdim-olddim;
458 return [[
self subviews] count];
463- (NSView*)hitTest:(NSPoint)aPoint {
464 if ([
self mouse:aPoint inRect:[
self frame]]) {
467 if ([delegate respondsToSelector:
@selector(
splitView:dividerForPoint:inSubview:)]) {
468 actDivider = [delegate splitView:sv dividerForPoint:aPoint inSubview:self];
469 if ((
actDivider+1)<[sv RB___numberOfSubviews]) {
474 NSView* result = [
super hitTest:aPoint];
475 canDragWindow = ![[result opaqueAncestor] isDescendantOf:[[result window] contentView]];
483- (void)mouseDown:(NSEvent*)theEvent {
484 NSWindow* window = [
self window];
485 NSPoint where = [theEvent locationInWindow];
491 NSPoint point = [sv convertPoint:where fromView:nil];
493 NSPoint base = NSZeroPoint;
499 while ((theEvent = [NSApp nextEventMatchingMask:NSLeftMouseDownMask|NSLeftMouseDraggedMask|NSLeftMouseUpMask untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:YES])&&([theEvent type]!=NSLeftMouseUp)) {
501 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
502 NSDisableScreenUpdates();
505 if ([sv mustAdjust]) {
512 DIM(point) += newc-divc;
514 NSEnableScreenUpdates();
527 where = [window convertBaseToScreen:where];
528 NSPoint
origin = [window frame].origin;
530 while ((theEvent = [NSApp nextEventMatchingMask:NSLeftMouseDownMask|NSLeftMouseDraggedMask|NSLeftMouseUpMask untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:YES])&&([theEvent type]!=NSLeftMouseUp)) {
532 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
533 NSPoint now = [window convertBaseToScreen:[theEvent locationInWindow]];
537 [window setFrameOrigin:origin];
545- (void)encodeWithCoder:(NSCoder*)coder {
547 BOOL coll = [
self isCollapsed];
551 NSRect newf = frame = [
self frame];
553 [
super setFrameOrigin:newf.origin];
555 [
super setFrameSize:newf.size];
557 [
super encodeWithCoder:coder];
559 [
super setFrame:frame];
561 if ([coder allowsKeyedCoding]) {
562 [coder encodeObject:identifier forKey:@"identifier"];
563 [coder encodeInteger:tag forKey:@"tag"];
564 [coder encodeDouble:minDimension forKey:@"minDimension"];
565 [coder encodeDouble:maxDimension forKey:@"maxDimension"];
566 [coder encodeDouble:fraction forKey:@"fraction"];
567 [coder encodeBool:canCollapse forKey:@"canCollapse"];
569 [coder encodeObject:identifier];
570 [coder encodeValueOfObjCType:@encode(typeof(tag)) at:&tag];
571 [coder encodeValueOfObjCType:@encode(typeof(minDimension)) at:&minDimension];
572 [coder encodeValueOfObjCType:@encode(typeof(maxDimension)) at:&maxDimension];
573 [coder encodeValueOfObjCType:@encode(typeof(fraction)) at:&fraction];
574 [coder encodeValueOfObjCType:@encode(typeof(canCollapse)) at:&canCollapse];
578- (id)initWithCoder:(NSCoder*)coder {
579 if ((
self = [super initWithCoder:coder])) {
592 BOOL ishor = [
self splitViewIsHorizontal];
595 [
self setFrameOrigin:previous.origin];
596 [
self setFrameSize:previous.size];
599 if ([coder allowsKeyedCoding]) {
600 [
self setIdentifier:[coder decodeObjectForKey:@"identifier"]];
601 tag = [coder decodeIntegerForKey:@"tag"];
602 minDimension = [coder decodeDoubleForKey:@"minDimension"];
603 maxDimension = [coder decodeDoubleForKey:@"maxDimension"];
604 fraction = [coder decodeDoubleForKey:@"fraction"];
605 canCollapse = [coder decodeBoolForKey:@"canCollapse"];
607 [
self setIdentifier:[coder decodeObject]];
608 [coder decodeValueOfObjCType:@encode(typeof(tag)) at:&tag];
609 [coder decodeValueOfObjCType:@encode(typeof(minDimension)) at:&minDimension];
610 [coder decodeValueOfObjCType:@encode(typeof(maxDimension)) at:&maxDimension];
611 [coder decodeValueOfObjCType:@encode(typeof(fraction)) at:&fraction];
612 [coder decodeValueOfObjCType:@encode(typeof(canCollapse)) at:&canCollapse];
620@implementation RBSplitSubview (RB___SubviewAdditions)
623- (void)RB___setHidden:(BOOL)flag {
624 [
super setHidden:flag];
631- (
animationData*)RB___animationData:(BOOL)start resize:(BOOL)resize {
640 CGFloat dim = [
self dimension];
642 NSTimeInterval total = dim*(0.2/150.0);
644 if ([delegate respondsToSelector:
@selector(splitView:willAnimateSubview:withDimension:)]) {
645 total = [delegate splitView:sv willAnimateSubview:self withDimension:dim];
674 NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
675 animationData* anim = [
self RB___animationData:NO resize:NO];
679 NSRect frame = [
self frame];
696 DIM(frame.size) = dim;
697 [
self RB___setFrame:frame withFraction:0.0 notify:NO];
700 anim->
elapsedTime += [NSDate timeIntervalSinceReferenceDate]-now;
703 [
self performSelector:@selector(RB___stepAnimation) withObject:nil afterDelay:delay inModes:[NSArray arrayWithObjects:NSDefaultRunLoopMode,NSModalPanelRunLoopMode,
704 NSEventTrackingRunLoopMode,nil]];
710 DIM(frame.size) = 0.0;
713 CGFloat savemin,savemax;
714 CGFloat dim = [
self RB___setMinAndMaxTo:anim->dimension savingMin:&savemin andMax:&savemax];
715 DIM(frame.size) = dim;
716 [
self RB___finishExpand:frame withFraction:0.0];
717 minDimension = savemin;
718 maxDimension = savemax;
727 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(RB___stepAnimation) object:nil];
730 [[
self splitView] RB___setDragging:NO];
739 BOOL ishor = [
self splitViewIsHorizontal];
740 NSRect frame = [
self frame];
741 return MAX(0.0,
DIM(frame.size));
748 cache->
rect = [
self frame];
749 cache->
size = [
self RB___visibleDimension];
754- (void)RB___updateFromCache:(
subviewCache*)cache withTotalDimension:(CGFloat)value {
755 CGFloat dim = [
self RB___visibleDimension];
756 if (cache->
size>=1.0) {
760 [
self RB___setFrame:cache->rect withFraction:cache->fraction notify:YES];
763 [
self RB___finishExpand:cache->rect withFraction:cache->fraction];
769 [
self RB___clearResponder];
770 [
self RB___finishCollapse:cache->rect withFraction:dim/value];
773 [
self RB___setFrame:cache->rect withFraction:cache->fraction notify:YES];
780- (CGFloat)RB___setMinAndMaxTo:(CGFloat)value savingMin:(CGFloat*)oldmin andMax:(CGFloat*)oldmax {
781 *oldmin = [
self minDimension];
782 *oldmax = [
self maxDimension];
789 minDimension = maxDimension = value;
797 NSWindow* window = [
self window];
799 NSView* responder = (NSView*)[window firstResponder];
800 if (responder&&[responder respondsToSelector:
@selector(isDescendantOf:)]) {
801 if ([responder isDescendantOf:
self]) {
802 if ([window makeFirstResponder:
nil]) {
815 CGFloat result = 0.0;
816 if (![
self isCollapsed]) {
818 if (sv&&[
self canCollapse]) {
819 [
self RB___clearResponder];
820 NSRect frame = [
self frame];
822 result =
DIM(frame.size);
824 DIM(frame.size) = 0.0;
833- (void)RB___finishCollapse:(NSRect)rect withFraction:(
double)value {
835 BOOL finish = [
self RB___stopAnimation];
836 [
self RB___setFrame:rect withFraction:value notify:YES];
842 if ([delegate respondsToSelector:
@selector(splitView:didCollapse:)]) {
843 [delegate splitView:sv didCollapse:self];
849- (CGFloat)RB___expandAndSetToMinimum:(BOOL)setToMinimum {
850 CGFloat result = 0.0;
852 if (sv&&[
self isCollapsed]) {
853 NSRect frame = [
super frame];
854 double frac = fraction;
857 result =
DIM(frame.size) = minDimension;
861 CGFloat newdim = floor((frac>=1.0)?result:result/(1.0-frac));
862 DIM(frame.size) = newdim;
863 result = floor(result);
865 [
self RB___finishExpand:frame withFraction:0.0];
872- (void)RB___finishExpand:(NSRect)rect withFraction:(
double)value {
874 BOOL finish = [
self RB___stopAnimation];
875 [
self RB___setFrame:rect withFraction:value notify:YES];
881 if ([delegate respondsToSelector:
@selector(splitView:didExpand:)]) {
882 [delegate splitView:sv didExpand:self];
888- (void)RB___setFrame:(NSRect)rect withFraction:(
double)value notify:(BOOL)notify {
894 if ([delegate respondsToSelector:
@selector(splitView:changedFrameOfSubview:from:to:)]) {
896 if (NSEqualRects(previous,rect)) {
904 [
self setFrame:rect];
906 [delegate splitView:sv changedFrameOfSubview:self from:previous to:rect];
907 previous = delegate?rect:NSZeroRect;
910- (void)RB___setFrameSize:(NSSize)size withFraction:(
double)value {
911 [[
self splitView] setMustAdjust];
912 [
self setFrameSize:size];
static animationData * currentAnimation
void RB___stepAnimation()
BOOL RB___stopAnimation()
CGFloat RB___visibleDimension()
BOOL RB___clearResponder()
BOOL splitViewIsHorizontal()
RBSplitView * couplingSplitView()
BOOL autoresizesSubviews()
RBSplitView * coupledSplitView()
RBSSubviewStatus status()
BOOL expandWithAnimation()
BOOL collapseWithAnimation()
RBSplitView * asSplitView()
BOOL acceptsFirstResponder()
RBSplitView * outermostSplitView()
NSUInteger numberOfSubviews()
RBSplitView * splitView()
void RB___trackMouseEvent:from:withBase:inDivider:(NSEvent *theEvent,[from] NSPoint where,[withBase] NSPoint base,[inDivider] NSUInteger indx)
CGFloat RB___dimensionWithoutDividers()
CGFloat RB___dividerOrigin:(NSUInteger indx)
void adjustSubviewsExcepting:(RBSplitSubview *excepting)
void RB___setDragging:(BOOL flag)
NSCursor * cursor:(RBSVCursorType type)
void addSubview:positioned:relativeTo:(NSView *aView, [positioned] NSWindowOrderingMode place, [relativeTo] NSView *otherView)
void RB___setMustClearFractions()
NSTimeInterval elapsedTime
NSTimeInterval finishTime