14static const unsigned char RBSplitView_Copyright[]
__attribute__ ((used)) =
15 "RBSplitView 1.2 Copyright(c)2004-2009 by Rainer Brockerhoff <rainer@brockerhoff.net>.";
21static inline CGFloat
fMIN(CGFloat a,CGFloat b) {
25static inline CGFloat
fMAX(CGFloat a,CGFloat b) {
35 NSCursor* result =
cursors[type];
41 return [NSCursor resizeUpDownCursor];
43 return [NSCursor resizeLeftRightCursor];
45 return [NSCursor openHandCursor];
47 return [NSCursor closedHandCursor];
52 return [NSCursor currentCursor];
57 [cursors[type] release];
58 cursors[type] = [cursor retain];
63+ (void)removeStateUsingName:(NSString*)name {
65 NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
66 [defaults removeObjectForKey:[[
self class] defaultsKeyForName:name isHorizontal:NO]];
67 [defaults removeObjectForKey:[[
self class] defaultsKeyForName:name isHorizontal:YES]];
72+ (NSString*)defaultsKeyForName:(NSString*)name isHorizontal:(BOOL)orientation {
73 return [NSString stringWithFormat:@"RBSplitView %@ %@",orientation?@"H":@"V",name];
87- (void)setAutosaveName:(NSString*)aString recursively:(BOOL)flag {
89 if ((clear = ![aString length])) {
93 [autosaveName autorelease];
96 NSArray* subviews = [
self subviews];
97 NSUInteger subcount = [subviews count];
99 for (i=0;i<subcount;i++) {
100 RBSplitView* sv = [[subviews objectAtIndex:i] asSplitView];
102 NSString* subst = clear?
@"":[aString stringByAppendingFormat:@"[%ld]",i];
112- (BOOL)saveState:(BOOL)recurse {
115 [[NSUserDefaults standardUserDefaults] setObject:[
self stringWithSavedState] forKey:[[
self class] defaultsKeyForName:autosaveName isHorizontal:[
self isHorizontal]]];
118 [[sub asSplitView] saveState:YES];
129- (BOOL)restoreState:(BOOL)recurse {
132 result = [
self setStateFromString:[[NSUserDefaults standardUserDefaults] stringForKey:[[
self class] defaultsKeyForName:autosaveName isHorizontal:[
self isHorizontal]]]];
133 if (result&&recurse) {
135 [[sub asSplitView] restoreState:YES];
147 NSMutableArray* array = [NSMutableArray array];
148 [array addObject:[
self stringWithSavedState]];
154 [array addObject:[NSNull null]];
164- (BOOL)setStatesFromArray:(NSArray*)array {
165 NSArray* subviews = [
self subviews];
166 NSUInteger
count = [array count];
168 NSString* me = [array objectAtIndex:0];
169 if ([me isKindOfClass:[NSString
class]]) {
170 if ([
self setStateFromString:me]) {
172 for (i=1;i<
count;i++) {
173 NSArray* item = [array objectAtIndex:i];
174 RBSplitView* suv = [[subviews objectAtIndex:i-1] asSplitView];
175 if ([item isKindOfClass:[NSArray
class]]==(suv!=
nil)) {
176 if (suv&&![suv setStatesFromArray:item]) {
194 NSArray* subviews = [
self subviews];
195 NSMutableString* result = [NSMutableString stringWithFormat:@"%ld",[subviews count]];
197 double size = [sub dimension];
203 [result appendFormat:[sub isHidden]?@" %gH":@" %g",size];
210- (BOOL)setStateFromString:(NSString*)aString {
211 if ([aString length]) {
212 NSArray* parts = [aString componentsSeparatedByString:@" "];
213 NSArray* subviews = [
self subviews];
214 NSInteger subcount = [subviews count];
215 NSInteger k = [parts count];
216 if ((k-->1)&&([[parts objectAtIndex:0] intValue]==subcount)&&(k==subcount)) {
218 NSRect frame = [
self frame];
219 BOOL ishor = [
self isHorizontal];
220 for (i=0;i<subcount;i++) {
221 NSString* part = [parts objectAtIndex:i+1];
222 double size = [part doubleValue];
223 BOOL hidden = [part hasSuffix:@"H"];
224 BOOL negative =
size<=0.0;
239 [
self setMustAdjust];
248- (id)initWithFrame:(NSRect)frame {
249 self = [
super initWithFrame:frame];
256 [
self setVertical:YES];
257 [
self setDivider:nil];
258 [
self setAutosaveName:nil recursively:NO];
259 [
self setBackground:nil];
265- (id)initWithFrame:(NSRect)frame andSubviews:(NSUInteger)count {
266 self = [
self initWithFrame:frame];
269 [
self addSubview:[[[
RBSplitSubview alloc] initWithFrame:frame] autorelease]];
271 [
self setMustAdjust];
281 [autosaveName release];
283 [background release];
290- (void)setCoupled:(BOOL)flag {
295 [
self setDivider:[[
self splitView] divider]];
297 [
self setMustAdjust];
317 return [
self isCoupled]?
self:
nil;
335 [
self setNeedsDisplay:YES];
355- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent {
356 return ([theEvent modifierFlags]&NSCommandKeyMask)==0;
359- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent*)theEvent {
360 return ([theEvent modifierFlags]&NSCommandKeyMask)!=0;
374- (void)setBackground:(NSColor*)color {
376 [background autorelease];
378 [
self setNeedsDisplay:YES];
390 return [NSString stringWithFormat:@"%@ {%@}",[
super description],[
self stringWithSavedState]];
403- (void)setHorizontal:(BOOL)flag {
407 [
self setDividerThickness:DIM(size)];
408 [
self setMustAdjust];
413 return ![
self isHorizontal];
416- (void)setVertical:(BOOL)flag {
417 [
self setHorizontal:!flag];
423 if ([anIdentifier isEqualToString:[sub
identifier]]) {
432 NSArray* subviews = [
super subviews];
433 NSUInteger subcount = [subviews count];
435 return [subviews objectAtIndex:position];
445- (void)setDelegate:(
id)anObject {
458- (void)setDivider:(NSImage*)image {
460 [divider autorelease];
467 [divider setFlipped:YES];
470 [
self setDividerThickness:0.0];
471 [
self setMustAdjust];
481 NSImage* divdr = [
self divider];
483 NSSize
size = [divdr size];
484 BOOL ishor = [
self isHorizontal];
490- (void)setDividerThickness:(CGFloat)thickness {
491 CGFloat t =
fMAX(0.0,floor(thickness));
494 [
self setMustAdjust];
500- (void)addSubview:(NSView*)aView {
502 [
super addSubview:aView];
504 [aView setFrameOrigin:NSZeroPoint];
506 [aView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
507 [sub addSubview:aView];
508 [
super addSubview:sub];
510 [
self setMustAdjust];
513- (void)addSubview:(NSView*)aView positioned:(NSWindowOrderingMode)place relativeTo:(NSView*)otherView {
515 [
super addSubview:aView positioned:place relativeTo:otherView];
517 [aView setFrameOrigin:NSZeroPoint];
519 [aView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
520 [sub addSubview:aView];
521 [
super addSubview:sub positioned:place relativeTo:otherView];
522 [aView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
524 [
self setMustAdjust];
527- (void)addSubview:(NSView*)aView atPosition:(NSUInteger)position {
530 [
self addSubview:aView positioned:NSWindowBelow relativeTo:suv];
532 [
self addSubview:aView];
538 [
super viewDidMoveToSuperview];
539 NSScrollView* scrollv = [
self enclosingScrollView];
544- (void)willRemoveSubview:(NSView*)subview {
548 [
super willRemoveSubview:subview];
549 [
self setMustAdjust];
559- (void)setFrameSize:(NSSize)size {
561 NSSize oldsize = [
self frame].size;
562 [
super setFrameSize:size];
563 [
self setMustAdjust];
565 BOOL ishor = [
self isHorizontal];
566 CGFloat olddim =
DIM(oldsize);
569 if (((NSInteger)newdim!=(NSInteger)olddim)) {
570 [delegate splitView:self wasResizedFrom:olddim to:newdim];
575 [
self adjustSubviews];
582- (void)mouseDown:(NSEvent*)theEvent {
586 NSArray* subviews = [
self RB___subviews];
587 NSUInteger subcount = [subviews count];
593 [
super mouseDown:theEvent];
596 NSPoint where = [
self convertPoint:[theEvent locationInWindow] fromView:nil];
597 BOOL ishor = [
self isHorizontal];
601 for (i=0;i<subcount;i++) {
603 if ([
self mouse:where inRect:*divdr]) {
607 RBSplitView* trailing = [subviews objectAtIndex:i+1];
608 if ([
delegate respondsToSelector:
@selector(
splitView:shouldHandleEvent:inDivider:betweenView:andView:)]) {
609 if (![
delegate splitView:
self shouldHandleEvent:theEvent inDivider:i betweenView:leading andView:trailing]) {
614 if ([theEvent clickCount]>1) {
618 [
self RB___tryToExpandTrailing:trailing leading:leading delta:-[trailing
dimension]];
622 [
self RB___tryToExpandLeading:leading divider:i trailing:trailing delta:[leading
dimension]];
630 if ([
delegate respondsToSelector:
@selector(
splitView:collapseLeading:orTrailing:)]) {
631 RBSplitSubview* sub = [delegate splitView:self collapseLeading:leading orTrailing:trailing];
634 tcan = sub==trailing;
642 [
self RB___tryToShortenLeading:leading divider:i trailing:trailing delta:-ldim always:NO];
646 [
self RB___tryToShortenTrailing:trailing divider:i leading:leading delta:[trailing
dimension] always:NO];
652 [
self RB___setMustClearFractions];
654 [sv?sv:self adjustSubviews];
659 CGFloat divt = [
self dividerThickness];
662 NSInteger ldivdr = NSNotFound;
663 CGFloat loffset = 0.0;
664 NSPoint lwhere = where;
665 NSRect lrect = NSZeroRect;
668 if (ldivdr!=NSNotFound) {
674 NSInteger tdivdr = NSNotFound;
675 CGFloat toffset = 0.0;
676 NSPoint twhere = where;
677 NSRect trect = NSZeroRect;
680 if (tdivdr!=NSNotFound) {
687 [
self RB___setDragging:YES];
688 while ((theEvent = [NSApp nextEventMatchingMask:NSLeftMouseDownMask|NSLeftMouseDraggedMask|NSLeftMouseUpMask untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:YES])&&([theEvent type]!=NSLeftMouseUp)) {
690 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
691 NSDisableScreenUpdates();
693 [
self RB___trackMouseEvent:theEvent from:where withBase:NSZeroPoint inDivider:i];
694 if (ldivdr!=NSNotFound) {
698 if (tdivdr!=NSNotFound) {
706 [sv?sv:self adjustSubviews];
711 if ((ldivdr!=NSNotFound)&&![leading
isCollapsed]) {
716 if ((tdivdr!=NSNotFound)&&![trailing
isCollapsed]) {
722 NSEnableScreenUpdates();
725 [
self RB___setDragging:NO];
736 [
self adjustSubviews];
739 return [
super needsDisplay];
745 [
super awakeFromNib];
748 [
self restoreState:YES];
755 [
self adjustSubviews];
761- (void)drawRect:(NSRect)rect {
762 [
super drawRect:rect];
766 NSArray* subviews = [
self RB___subviews];
767 NSUInteger subcount = [subviews count];
775 NSImage* divdr = [
self divider];
776 CGFloat divt = [
self dividerThickness];
778 for (i=0;i<subcount;i++) {
780 if ([
self needsToDrawRect:
dividers[i]]) {
782 RBSplitView* trailing = [subviews objectAtIndex:i+1];
788 [
self drawDivider:nodiv?nil:divdr inRect:dividers[i] betweenView:leading andView:trailing];
812 if (leading||trailing) {
813 NSColor* bg = [
self background];
816 NSRectFillUsingOperation(rect,NSCompositeSourceOver);
820 NSRect imrect = NSZeroRect;
821 NSRect dorect = NSZeroRect;
823 imrect.size = dorect.size = [anImage size];
824 dorect.origin = NSMakePoint(floor(rect.origin.x+(rect.size.width-dorect.size.width)/2),
825 floor(rect.origin.y+(rect.size.height-dorect.size.height)/2));
828 if ([
delegate respondsToSelector:
@selector(
splitView:willDrawDividerInRect:betweenView:andView:withProposedRect:)]) {
829 dorect = [delegate splitView:self willDrawDividerInRect:rect betweenView:leading andView:trailing withProposedRect:dorect];
832 if (!NSIsEmptyRect(dorect)) {
833 [anImage drawInRect:dorect fromRect:imrect operation:NSCompositeSourceOver fraction:1.0];
840 [
self RB___adjustSubviewsExcepting:[excepting
isCollapsed]?nil:excepting];
845 [
self RB___adjustSubviewsExcepting:nil];
854 id del = [delegate respondsToSelector:@selector(splitView:cursorRect:forDivider:)]?
delegate:
nil;
855 NSArray* subviews = [
self RB___subviews];
856 NSInteger divcount = [subviews count]-1;
857 if ((divcount<1)||![
self divider]) {
858 [del splitView:self cursorRect:NSZeroRect forDivider:0];
862 NSCursor* cursor = [
RBSplitView cursor:[
self isVertical]?RBSVVerticalCursor:RBSVHorizontalCursor];
863 CGFloat divt = [
self dividerThickness];
864 for (i=0;i<divcount;i++) {
865 RBSplitView* sub = [[subviews objectAtIndex:i] coupledSplitView];
870 sub = [[subviews objectAtIndex:i+1] coupledSplitView];
878 divrect = [del splitView:self cursorRect:divrect forDivider:i];
880 if (!NSIsEmptyRect(divrect)) {
881 [
self addCursorRect:divrect cursor:cursor];
890- (void)encodeWithCoder:(NSCoder *)coder {
891 [
super encodeWithCoder:coder];
892 if ([coder allowsKeyedCoding]) {
893 [coder encodeConditionalObject:delegate forKey:@"delegate"];
894 [coder encodeObject:autosaveName forKey:@"autosaveName"];
895 [coder encodeObject:[divider TIFFRepresentation] forKey:@"divider"];
896 [coder encodeObject:background forKey:@"background"];
897 [coder encodeDouble:dividerThickness forKey:@"dividerThickness"];
898 [coder encodeBool:isHorizontal forKey:@"isHorizontal"];
899 [coder encodeBool:isCoupled forKey:@"isCoupled"];
901 [coder encodeConditionalObject:delegate];
902 [coder encodeObject:autosaveName];
903 [coder encodeObject:[divider TIFFRepresentation]];
904 [coder encodeObject:background];
905 [coder encodeValueOfObjCType:@encode(typeof(dividerThickness)) at:÷rThickness];
906 [coder encodeValueOfObjCType:@encode(typeof(isHorizontal)) at:&isHorizontal];
907 [coder encodeValueOfObjCType:@encode(typeof(isCoupled)) at:&isCoupled];
911- (id)initWithCoder:(NSCoder *)coder {
912 if ((
self = [super initWithCoder:coder])) {
919 if ([coder allowsKeyedCoding]) {
920 isCoupled = [coder decodeBoolForKey:@"isCoupled"];
921 [
self setDelegate:[coder decodeObjectForKey:@"delegate"]];
922 [
self setAutosaveName:[coder decodeObjectForKey:@"autosaveName"] recursively:NO];
923 data = [coder decodeObjectForKey:@"divider"];
924 [
self setBackground:[coder decodeObjectForKey:@"background"]];
925 divt = [coder decodeDoubleForKey:@"dividerThickness"];
926 isHorizontal = [coder decodeBoolForKey:@"isHorizontal"];
928 [
self setDelegate:[coder decodeObject]];
929 [
self setAutosaveName:[coder decodeObject] recursively:NO];
930 data = [coder decodeObject];
931 [
self setBackground:[coder decodeObject]];
932 [coder decodeValueOfObjCType:@encode(typeof(divt)) at:&divt];
933 [coder decodeValueOfObjCType:@encode(typeof(isHorizontal)) at:&isHorizontal];
934 [coder decodeValueOfObjCType:@encode(typeof(isCoupled)) at:&isCoupled];
938 NSBitmapImageRep* rep = [NSBitmapImageRep imageRepWithData:data];
939 NSImage* image = [[[NSImage alloc] initWithSize:[rep size]] autorelease];
940 [image setFlipped:YES];
941 [image addRepresentation:rep];
942 [
self setDivider:image];
944 [
self setDivider:nil];
946 [
self setDividerThickness:divt];
947 [
self setMustAdjust];
948 [
self performSelector:@selector(viewDidMoveToSuperview) withObject:nil afterDelay:0.0];
949 [
self performSelector:@selector(RB___adjustOutermostIfNeeded) withObject:nil afterDelay:0.0];
960@implementation RBSplitView (RB___ViewAdditions)
963- (void)RB___setDragging:(BOOL)flag {
964 BOOL save = isDragging&&!flag;
973 NSUInteger result = 0;
975 if (![sub isHidden]) {
983- (CGFloat)RB___dividerOrigin:(NSUInteger)indx {
984 CGFloat result = 0.0;
986 BOOL ishor = [
self isHorizontal];
994 NSMutableArray* result = [NSMutableArray arrayWithArray:[
self subviews]];
996 for (i=[result
count]-1;i>=0;i--) {
998 if ([view isHidden]) {
999 [result removeObjectAtIndex:i];
1007 return dividerThickness;
1012 BOOL ishor = [
self isHorizontal];
1013 NSSize
size = [
self frame].size;
1020- (NSRect)RB___dividerRect:(NSUInteger)indx relativeToView:(
RBSplitView*)view {
1022 NSRect result = dividers[indx];
1023 if (view&&(view!=
self)) {
1024 result = [
self convertRect:result toView:view];
1034- (NSUInteger)RB___dividerHitBy:(NSPoint)point relativeToView:(
RBSplitView*)view thickness:(CGFloat)delta {
1038 NSInteger divcount = [
self RB___numberOfSubviews]-1;
1043 BOOL ishor = [
self isHorizontal];
1044 point = [
self convertPoint:point fromView:view];
1045 for (i=0;i<divcount;i++) {
1046 NSRect divdr = dividers[i];
1047 OTHER(divdr.origin) -= delta;
1048 OTHER(divdr.size) += 2*delta;
1049 if ([
self mouse:point inRect:divdr]) {
1058 mustClearFractions = YES;
1063- (BOOL)RB___shouldResizeWindowForDivider:(NSUInteger)indx betweenView:(
RBSplitSubview*)leading andView:(
RBSplitSubview*)trailing willGrow:(BOOL)grow {
1064 if (!isInScrollView&&[delegate respondsToSelector:
@selector(splitView:shouldResizeWindowForDivider:betweenView:andView:willGrow:)]) {
1065 return [delegate splitView:self shouldResizeWindowForDivider:indx betweenView:leading andView:trailing willGrow:grow];
1071- (void)RB___tryToExpandLeading:(
RBSplitSubview*)leading divider:(NSUInteger)indx trailing:(
RBSplitSubview*)trailing delta:(CGFloat)delta {
1072 NSWindow* window =
nil;
1073 NSView* document =
nil;
1075 NSRect frame = NSZeroRect;
1079 BOOL dowin = ([
self RB___shouldResizeWindowForDivider:indx betweenView:leading andView:trailing willGrow:YES]);
1082 ishor = [
self isHorizontal];
1083 document = [[
self enclosingScrollView] documentView];
1085 frame = [document frame];
1087 window = [
self window];
1088 frame = [window frame];
1089 maxsize = [window maxSize];
1090 screen = [[NSScreen mainScreen] visibleFrame];
1096 CGFloat dimension = 0.0;
1098 CGFloat maxd =
fMAX(0.0,(ishor?frame.origin.y-screen.origin.y:(screen.origin.x+screen.size.width)-(frame.origin.x+frame.size.width)));
1099 dimension =
fMIN(
DIM(maxsize)-
DIM(frame.size),maxd);
1103 if (limit>dimension) {
1106 if (!dowin&&trailing) {
1107 limit += [trailing minDimension];
1108 if (limit>dimension) {
1111 if (([trailing canCollapse])&&(delta>(0.5+
HYSTERESIS)*dimension)&&([leading maxDimension]<=dimension)) {
1112 delta = -[trailing RB___collapse];
1119 delta = -[leading changeDimensionBy:delta mayCollapse:NO move:NO];
1122 DIM(frame.size) -= delta;
1124 DIM(frame.origin) += delta;
1127 [document setFrame:frame];
1128 [document setNeedsDisplay:YES];
1130 [window setFrame:frame display:YES];
1132 [
self setMustAdjust];
1142- (void)RB___tryToShortenLeading:(
RBSplitSubview*)leading divider:(NSUInteger)indx trailing:(
RBSplitSubview*)trailing delta:(CGFloat)delta always:(BOOL)always {
1143 NSWindow* window =
nil;
1144 NSView* document =
nil;
1145 NSSize minsize = NSZeroSize;
1146 NSRect frame = NSZeroRect;
1149 BOOL dowin = ([
self RB___shouldResizeWindowForDivider:indx betweenView:leading andView:trailing willGrow:NO]);
1152 ishor = [
self isHorizontal];
1153 document = [[
self enclosingScrollView] documentView];
1155 frame = [document frame];
1157 window = [
self window];
1158 frame = [window frame];
1159 minsize = [window minSize];
1163 CGFloat limit = 0.0;
1165 limit =
DIM(frame.size)-
DIM(minsize);
1167 limit = trailing?([trailing
maxDimension]-[trailing dimension]):WAYOUT;
1179 delta = -[leading changeDimensionBy:delta mayCollapse:okl move:NO];
1182 DIM(frame.size) -= delta;
1184 DIM(frame.origin) += delta;
1187 [document setFrame:frame];
1188 [document setNeedsDisplay:YES];
1190 [window setFrame:frame display:YES];
1192 [
self setMustAdjust];
1203- (void)RB___tryToShortenTrailing:(
RBSplitSubview*)trailing divider:(NSUInteger)indx leading:(
RBSplitSubview*)leading delta:(CGFloat)delta always:(BOOL)always {
1204 NSWindow* window =
nil;
1205 NSView* document =
nil;
1207 NSRect frame = NSZeroRect;
1211 BOOL dowin = ([
self RB___shouldResizeWindowForDivider:indx betweenView:leading andView:trailing willGrow:YES]);
1214 ishor = [
self isHorizontal];
1215 document = [[
self enclosingScrollView] documentView];
1217 frame = [document frame];
1219 window = [
self window];
1220 frame = [window frame];
1221 maxsize = [window maxSize];
1222 screen = [[NSScreen mainScreen] visibleFrame];
1226 CGFloat limit = 0.0;
1228 CGFloat maxd =
fMAX(0.0,(ishor?frame.origin.y-screen.origin.y:(screen.origin.x+screen.size.width)-(frame.origin.x+frame.size.width)));
1229 limit =
fMIN(
DIM(maxsize)-
DIM(frame.size),maxd);
1245 DIM(frame.size) += delta;
1247 DIM(frame.origin) -= delta;
1250 [document setFrame:frame];
1251 [document setNeedsDisplay:YES];
1253 [window setFrame:frame display:YES];
1255 [
self setMustAdjust];
1259 delta = -[trailing changeDimensionBy:-delta mayCollapse:okl move:YES];
1272 CGFloat dimension = [leading
dimension];
1273 if (limit>dimension) {
1276 limit += [leading minDimension];
1277 if (limit>dimension) {
1278 if ([leading canCollapse]&&(-delta>(0.5+
HYSTERESIS)*dimension)&&((trailing?[trailing maxDimension]:0.0)<=dimension)) {
1279 delta = -[leading RB___collapse];
1286 delta = -[trailing changeDimensionBy:-delta mayCollapse:NO move:YES];
1300- (void)RB___trackMouseEvent:(NSEvent*)theEvent from:(NSPoint)where withBase:(NSPoint)base inDivider:(NSUInteger)indx {
1301 NSArray* subviews = [
self RB___subviews];
1302 NSUInteger subcount = [subviews count];
1304 if (indx>=subcount) {
1313 NSPoint mouse = [
self convertPoint:[theEvent locationInWindow] fromView:nil];
1316 result.x = mouse.x-where.
x;
1317 result.y = mouse.y-where.
y;
1319 BOOL ishor = [
self isHorizontal];
1320 CGFloat delta =
DIM(result);
1327 while (![firstLeading canShrink]) {
1329 firstLeading = leading;
1332 firstLeading = [subviews objectAtIndex:--k];
1334 if (isInScrollView) {
1338 if ([trailing isCollapsed]) {
1339 [
self RB___tryToExpandTrailing:trailing leading:firstLeading delta:delta];
1341 [
self RB___tryToShortenLeading:firstLeading divider:indx trailing:trailing delta:delta always:YES];
1343 }
else if (delta>0.0) {
1348 if (!isInScrollView) {
1349 firstTrailing = trailing;
1351 while (![firstTrailing canShrink]) {
1352 if (++k>=subcount) {
1353 firstTrailing = trailing;
1356 firstTrailing = [subviews objectAtIndex:k];
1360 if ([leading isCollapsed]) {
1361 [
self RB___tryToExpandLeading:leading divider:indx trailing:firstTrailing delta:delta];
1364 [
self RB___tryToShortenTrailing:firstTrailing divider:indx leading:leading delta:delta always:YES];
1370- (void)RB___addCursorRectsTo:(
RBSplitView*)masterView forDividerRect:(NSRect)rect thickness:(CGFloat)delta {
1371 if (dividers&&[
self divider]) {
1372 NSArray* subviews = [
self RB___subviews];
1373 NSInteger divcount = [subviews count]-1;
1379 BOOL ishor = [
self isHorizontal];
1382 for (i=0;i<divcount;i++) {
1383 NSRect divdr = dividers[i];
1384 divdr.origin = [
self convertPoint:divdr.origin toView:masterView];
1385 OTHER(divdr.origin) -= delta;
1386 OTHER(divdr.size) += 2*delta;
1387 divdr = NSIntersectionRect(divdr,rect);
1388 if (!NSIsEmptyRect(divdr)) {
1389 [masterView addCursorRect:divdr cursor:cursor];
1396- (void)RB___drawDividersIn:(
RBSplitView*)masterView forDividerRect:(NSRect)rect thickness:(CGFloat)delta {
1400 NSArray* subviews = [
self RB___subviews];
1401 NSInteger divcount = [subviews count]-1;
1406 BOOL ishor = [
self isHorizontal];
1408 NSImage* image = [masterView
divider];
1410 for (i=0;i<divcount;i++) {
1411 NSRect divdr = dividers[i];
1412 divdr.origin = [
self convertPoint:divdr.origin toView:masterView];
1413 OTHER(divdr.origin) -= delta;
1414 OTHER(divdr.size) += 2*delta;
1415 divdr = NSIntersectionRect(divdr,rect);
1416 if (!NSIsEmptyRect(divdr)) {
1430 if (mustAdjust&&!isAdjusting) {
1431 [
self adjustSubviews];
1442 NSArray* subviews = [
self RB___subviews];
1443 NSUInteger subcount = [subviews count];
1447 NSRect bounds = [
self bounds];
1449 if ((bounds.size.width<1.0)||(bounds.size.height<1.0)) {
1458 if ([delegate respondsToSelector:
@selector(willAdjustSubviews:)]) {
1459 [delegate willAdjustSubviews:self];
1460 bounds = [
self bounds];
1462 NSUInteger divcount = subcount-1;
1471 NSUInteger divsiz =
sizeof(NSRect)*divcount;
1472 dividers = (NSRect*)(dividers?reallocf(dividers,divsiz):malloc(divsiz));
1479 double realsize = 0.0;
1480 double expsize = 0.0;
1481 CGFloat newsize = 0.0;
1482 CGFloat effsize = 0.0;
1486 BOOL ishor = [
self isHorizontal];
1487 CGFloat divt = [
self dividerThickness];
1489 for (i=0;i<subcount;i++) {
1491 [[subviews objectAtIndex:i] RB___copyIntoCache:curr];
1494 NSInteger sanity = excepting?-3:0;
1495 while (sanity++<3) {
1502 NSUInteger smallest = 0;
1503 CGFloat smalldim = -1.0;
1507 for (i=0;i<subcount;i++) {
1510 if (curr->
size>0.0) {
1511 expsize += curr->size;
1512 if (!isInScrollView) {
1514 expsize += curr->fraction;
1518 limit = [curr->sub minDimension];
1519 if (smalldim>limit) {
1527 curr = &caches[smallest];
1529 curr->
size = [curr->sub minDimension];
1531 expsize += curr->
size;
1533 if (isInScrollView) {
1536 DIM(bounds.size) = expsize;
1541 newsize =
DIM(bounds.size)-divcount*divt;
1543 curr->
size = newsize;
1554 double scale = newsize/expsize;
1558 for (i=0;i<subcount;i++) {
1561 if (curr->
size>0.0) {
1563 if (!curr->constrain) {
1565 CGFloat cursize = (curr->size+curr->fraction)*scale;
1567 if (([curr->sub RB___animationData:NO resize:NO]&&((limit = curr->size)>=0.0))||
1568 ((curr->sub==excepting)&&((limit = [curr->sub dimension])>0.0))||
1569 (cursize<(limit = [curr->sub minDimension]))||
1570 (cursize>(limit = [curr->sub maxDimension]))) {
1573 curr->constrain = constrained = YES;
1576 curr->fraction = 0.0;
1580 double rem = fmod(cursize,1.0);
1587 curr->fraction = rem;
1590 curr->size = cursize;
1600 }
while (constrained&&(expsize>0.0));
1604 limit = realsize-effsize;
1609 for (i=0;i<subcount;i++) {
1611 if (curr->
constrain&&(curr->
sub!=excepting)&&([curr->
sub RB___animationData:NO resize:NO]==
nil)&&[curr->
sub canCollapse]) {
1612 realsize -= curr->size;
1617 if ((realsize-effsize)<1.0) {
1622 }
else if (limit<=-1.0) {
1626 for (i=0;i<subcount;i++) {
1628 if (curr->
size<=0.0) {
1629 curr->size = [curr->sub minDimension];
1630 curr->fraction = 0.0;
1631 realsize += curr->size;
1632 if ((realsize-effsize)>-1.0) {
1649 NSRect newframe = NSMakeRect(0.0,0.0,bounds.size.width,bounds.size.height);
1654 NSInteger nested = NSNotFound;
1656 for (i=0;i<subcount;i++) {
1659 if ((nested==NSNotFound)&&([curr->
sub asSplitView]!=
nil)) {
1663 curr->
rect.origin = newframe.origin;
1667 if ((curr->
size>0.0)&&mustClearFractions) {
1668 curr->fraction = 0.0;
1671 [curr->
sub RB___updateFromCache:curr withTotalDimension:effsize];
1673 DIM(newframe.origin) += curr->
size;
1674 if (curr->
size>0.0) {
1680 CGFloat remain =
DIM(bounds.size)-
DIM(newframe.
origin);
1681 if (last&&(fabs(remain)>0.0)) {
1686 newframe = [last frame];
1687 DIM(newframe.size) += remain;
1690 while ((i>0)&&(last!=[subviews objectAtIndex:i])) {
1697 DIM(newframe.size) = divt;
1699 dividers[i] = newframe;
1701 DIM(newframe.origin) += divt;
1705 if (isInScrollView) {
1706 [
super setFrameSize:bounds.size];
1709 for (i=nested;i<subcount;i++) {
1712 if ([sv mustAdjust]) {
1720 mustClearFractions = NO;
1721 [[
self window] invalidateCursorRectsForView:self];
1724 [
self saveState:NO];
1729 [[
self window] invalidateCursorRectsForView:sv];
1733 if ([delegate respondsToSelector:
@selector(didAdjustSubviews:)]) {
1734 [delegate didAdjustSubviews:self];
static CGFloat fMAX(CGFloat a, CGFloat b)
static NSCursor * cursors[RBSVCursorTypeCount]
static const unsigned char RBSplitView_Copyright[] __attribute__((used))
static CGFloat fMIN(CGFloat a, CGFloat b)
NSUInteger RB___numberOfSubviews()
CGFloat RB___dimensionWithoutDividers()
void RB___adjustOutermostIfNeeded()
CGFloat RB___dividerThickness()
NSArray * RB___subviews()
void RB___setMustClearFractions()
BOOL RB___stopAnimation()
void RB___setFrameSize:withFraction:(NSSize size,[withFraction] double value)
CGFloat changeDimensionBy:mayCollapse:move:(CGFloat increment,[mayCollapse] BOOL mayCollapse,[move] BOOL move)
void RB___setHidden:(BOOL flag)
void RB___setFrame:withFraction:notify:(NSRect rect,[withFraction] double value,[notify] BOOL notify)
RBSplitView * splitView()
void RB___trackMouseEvent:from:withBase:inDivider:(NSEvent *theEvent,[from] NSPoint where,[withBase] NSPoint base,[inDivider] NSUInteger indx)
void removeStateUsingName:(NSString *name)
RBSplitView * asSplitView()
void RB___adjustOutermostIfNeeded()
RBSplitView * coupledSplitView()
NSString * stringWithSavedState()
void drawDivider:inRect:betweenView:andView:(NSImage *anImage,[inRect] NSRect rect,[betweenView] RBSplitSubview *leading,[andView] RBSplitSubview *trailing)
BOOL autoresizesSubviews()
NSUInteger RB___dividerHitBy:relativeToView:thickness:(NSPoint point,[relativeToView] RBSplitView *view,[thickness] CGFloat delta)
NSArray * arrayWithStates()
void RB___drawDividersIn:forDividerRect:thickness:(RBSplitView *masterView,[forDividerRect] NSRect rect,[thickness] CGFloat delta)
BOOL mouseDownCanMoveWindow()
void setAutosaveName:recursively:(NSString *aString,[recursively] BOOL flag)
NSCursor * cursor:(RBSVCursorType type)
void RB___addCursorRectsTo:forDividerRect:thickness:(RBSplitView *masterView,[forDividerRect] NSRect rect,[thickness] CGFloat delta)
RBSplitView * couplingSplitView()
void viewDidMoveToSuperview()
NSRect RB___dividerRect:relativeToView:(NSUInteger indx,[relativeToView] RBSplitView *view)
BOOL saveState:(BOOL recurse)