Oolite 1.91.0.7645-241119-222d325
Loading...
Searching...
No Matches
RBSplitView Class Reference

#include <RBSplitView.h>

+ Inheritance diagram for RBSplitView:
+ Collaboration diagram for RBSplitView:

Instance Methods

(void) - setAutosaveName:recursively:
 
(NSString *) - autosaveName
 
(BOOL) - saveState:
 
(BOOL) - restoreState:
 
(NSString *) - stringWithSavedState
 
(BOOL) - setStateFromString:
 
(NSArray *) - arrayWithStates
 
(BOOL) - setStatesFromArray:
 
(id) - initWithFrame:
 
(id) - initWithFrame:andSubviews:
 
(void) - setDelegate:
 
(id) - delegate
 
(RBSplitSubview *) - subviewWithIdentifier:
 
(RBSplitSubview *) - subviewAtPosition:
 
(void) - addSubview:atPosition:
 
(void) - setDividerThickness:
 
(CGFloat) - dividerThickness
 
(void) - setDivider:
 
(NSImage *) - divider
 
(void) - setBackground:
 
(NSColor *) - background
 
(void) - setVertical:
 
(BOOL) - isVertical
 
(void) - setHorizontal:
 
(BOOL) - isHorizontal
 
(void) - setMustAdjust
 
(BOOL) - mustAdjust
 
(BOOL) - isAdjusting
 
(BOOL) - isDragging
 
(BOOL) - isInScrollView
 
(void) - adjustSubviews
 
(void) - adjustSubviewsExcepting:
 
(void) - drawDivider:inRect:betweenView:andView:
 
(void) - dealloc [implementation]
 
(void) - setCoupled: [implementation]
 
(RBSplitView *) - couplingSplitView [implementation]
 
(RBSplitView *) - asSplitView [implementation]
 
(RBSplitView *) - coupledSplitView [implementation]
 
(BOOL) - mouseDownCanMoveWindow [implementation]
 
(BOOL) - isFlipped [implementation]
 
(BOOL) - acceptsFirstMouse: [implementation]
 
(BOOL) - shouldDelayWindowOrderingForEvent: [implementation]
 
(BOOL) - isOpaque [implementation]
 
(NSString *) - description [implementation]
 
(void) - addSubview: [implementation]
 
(void) - addSubview:positioned:relativeTo: [implementation]
 
(void) - viewDidMoveToSuperview [implementation]
 
(void) - willRemoveSubview: [implementation]
 
(BOOL) - autoresizesSubviews [implementation]
 
(void) - setFrameSize: [implementation]
 
(void) - mouseDown: [implementation]
 
(BOOL) - needsDisplay [implementation]
 
(void) - awakeFromNib [implementation]
 
(void) - display [implementation]
 
(void) - drawRect: [implementation]
 
(void) - resetCursorRects [implementation]
 
(void) - encodeWithCoder: [implementation]
 
(id) - initWithCoder: [implementation]
 
(void) - RB___adjustOutermostIfNeeded [implementation]
 
(void) - RB___setDragging: [implementation]
 
(CGFloat) - RB___dividerOrigin: [implementation]
 
(NSArray *) - RB___subviews [implementation]
 
(NSUInteger) - RB___numberOfSubviews [implementation]
 
(void) - RB___adjustSubviewsExcepting: [implementation]
 
(CGFloat) - RB___dimensionWithoutDividers [implementation]
 
(CGFloat) - RB___dividerThickness [implementation]
 
(NSRect) - RB___dividerRect:relativeToView: [implementation]
 
(void) - RB___setMustClearFractions [implementation]
 
(BOOL) - RB___shouldResizeWindowForDivider:betweenView:andView:willGrow: [implementation]
 
(void) - RB___tryToExpandLeading:divider:trailing:delta: [implementation]
 
(void) - RB___tryToShortenLeading:divider:trailing:delta:always: [implementation]
 
(void) - RB___tryToExpandTrailing:leading:delta: [implementation]
 
(void) - RB___tryToShortenTrailing:divider:leading:delta:always: [implementation]
 
(void) - RB___trackMouseEvent:from:withBase:inDivider: [implementation]
 
(void) - RB___addCursorRectsTo:forDividerRect:thickness: [implementation]
 
(NSUInteger) - RB___dividerHitBy:relativeToView:thickness: [implementation]
 
(void) - RB___drawDividersIn:forDividerRect:thickness: [implementation]
 
- Instance Methods inherited from RBSplitSubview
(RBSplitView *) - splitView
 
(RBSplitView *) - outermostSplitView
 
(BOOL) - isCoupled
 
(BOOL) - splitViewIsHorizontal
 
(NSUInteger) - numberOfSubviews
 
(void) - setTag:
 
(NSInteger) - tag
 
(void) - setIdentifier:
 
(NSString *) - identifier
 
(NSUInteger) - position
 
(void) - setPosition:
 
(BOOL) - isCollapsed
 
(RBSSubviewStatus- status
 
(BOOL) - canCollapse
 
(void) - setCanCollapse:
 
(BOOL) - canShrink
 
(BOOL) - canExpand
 
(CGFloat) - minDimension
 
(CGFloat) - maxDimension
 
(void) - setMinDimension:andMaxDimension:
 
(CGFloat) - expand
 
(CGFloat) - collapse
 
(BOOL) - collapseWithAnimation
 
(BOOL) - expandWithAnimation
 
(BOOL) - collapseWithAnimation:withResize:
 
(BOOL) - expandWithAnimation:withResize:
 
(CGFloat) - dimension
 
(void) - setDimension:
 
(CGFloat) - changeDimensionBy:mayCollapse:move:
 
(void) - setHidden: [implementation]
 
(BOOL) - acceptsFirstResponder [implementation]
 
(void) - setAutoresizesSubviews: [implementation]
 
(void) - resizeSubviewsWithOldSize: [implementation]
 
(NSView *) - hitTest: [implementation]
 
(void) - RB___setHidden: [implementation]
 
(animationData *) - RB___animationData:resize: [implementation]
 
(void) - RB___stepAnimation [implementation]
 
(BOOL) - RB___stopAnimation [implementation]
 
(CGFloat) - RB___visibleDimension [implementation]
 
(CGFloat) - RB___setMinAndMaxTo:savingMin:andMax: [implementation]
 
(CGFloat) - RB___collapse [implementation]
 
(CGFloat) - RB___expandAndSetToMinimum: [implementation]
 
(void) - RB___finishCollapse:withFraction: [implementation]
 
(void) - RB___finishExpand:withFraction: [implementation]
 
(void) - RB___setFrameSize:withFraction: [implementation]
 
(void) - RB___setFrame:withFraction:notify: [implementation]
 
(double) - RB___fraction [implementation]
 
(void) - RB___copyIntoCache: [implementation]
 
(void) - RB___updateFromCache:withTotalDimension: [implementation]
 
(BOOL) - RB___clearResponder [implementation]
 

Class Methods

(NSCursor *) + cursor:
 
(void) + setCursor:toCursor:
 
(void) + removeStateUsingName:
 
(NSString *) + defaultsKeyForName:isHorizontal:
 
- Class Methods inherited from RBSplitSubview
(BOOL) + animating
 

Protected Attributes

IBOutlet id delegate
 
NSString * autosaveName
 
NSColor * background
 
NSImage * divider
 
NSRect * dividers
 
CGFloat dividerThickness
 
BOOL mustAdjust
 
BOOL mustClearFractions
 
BOOL isHorizontal
 
BOOL canSaveState
 
BOOL isCoupled
 
BOOL isAdjusting
 
BOOL isDragging
 
BOOL isInScrollView
 
- Protected Attributes inherited from RBSplitSubview
NSString * identifier
 
NSInteger tag
 
CGFloat minDimension
 
CGFloat maxDimension
 
double fraction
 
NSRect previous
 
NSSize savedSize
 
NSUInteger actDivider
 
BOOL canDragWindow
 
BOOL canCollapse
 
BOOL notInLimits
 

Detailed Description

Definition at line 21 of file RBSplitView.h.

Method Documentation

◆ acceptsFirstMouse:

- (BOOL) acceptsFirstMouse: (NSEvent*) theEvent
implementation

Definition at line 25 of file RBSplitView.m.

355 :(NSEvent*)theEvent {
356 return ([theEvent modifierFlags]&NSCommandKeyMask)==0;
357}

◆ addSubview:

- (void) addSubview: (NSView*) aView
implementation

Definition at line 25 of file RBSplitView.m.

500 :(NSView*)aView {
501 if ([aView isKindOfClass:[RBSplitSubview class]]) {
502 [super addSubview:aView];
503 } else {
504 [aView setFrameOrigin:NSZeroPoint];
505 RBSplitSubview* sub = [[[RBSplitSubview alloc] initWithFrame:[aView frame]] autorelease];
506 [aView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
507 [sub addSubview:aView];
508 [super addSubview:sub];
509 }
510 [self setMustAdjust];
511}

◆ addSubview:atPosition:

- (void) addSubview: (NSView*) aView
atPosition: (NSUInteger) position 

Definition at line 25 of file RBSplitView.m.

527 :(NSView*)aView atPosition:(NSUInteger)position {
528 RBSplitSubview* suv = [self subviewAtPosition:position];
529 if (suv) {
530 [self addSubview:aView positioned:NSWindowBelow relativeTo:suv];
531 } else {
532 [self addSubview:aView];
533 }
534}
return self
NSUInteger position()

◆ addSubview:positioned:relativeTo:

- (void) addSubview: (NSView*) aView
positioned: (NSWindowOrderingMode) place
relativeTo: (NSView*) otherView 
implementation

Definition at line 25 of file RBSplitView.m.

513 :(NSView*)aView positioned:(NSWindowOrderingMode)place relativeTo:(NSView*)otherView {
514 if ([aView isKindOfClass:[RBSplitSubview class]]) {
515 [super addSubview:aView positioned:place relativeTo:otherView];
516 } else {
517 [aView setFrameOrigin:NSZeroPoint];
518 RBSplitSubview* sub = [[[RBSplitSubview alloc] initWithFrame:[aView frame]] autorelease];
519 [aView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
520 [sub addSubview:aView];
521 [super addSubview:sub positioned:place relativeTo:otherView];
522 [aView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
523 }
524 [self setMustAdjust];
525}

◆ adjustSubviews

- (void) adjustSubviews

Definition at line 25 of file RBSplitView.m.

844 {
845 [self RB___adjustSubviewsExcepting:nil];
846}

◆ adjustSubviewsExcepting:

- (void) adjustSubviewsExcepting: (RBSplitSubview*) excepting

Definition at line 25 of file RBSplitView.m.

839 :(RBSplitSubview*)excepting {
840 [self RB___adjustSubviewsExcepting:[excepting isCollapsed]?nil:excepting];
841}

◆ arrayWithStates

- (NSArray *) arrayWithStates

Definition at line 25 of file RBSplitView.m.

146 {
147 NSMutableArray* array = [NSMutableArray array];
148 [array addObject:[self stringWithSavedState]];
149 for (RBSplitSubview* sub in [self subviews]){
150 RBSplitView* suv = [sub asSplitView];
151 if (suv) {
152 [array addObject:[suv arrayWithStates]];
153 } else {
154 [array addObject:[NSNull null]];
155 }
156 }
157 return array;
158}
NSArray * arrayWithStates()

◆ asSplitView

- (RBSplitView *) asSplitView
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

311 {
312 return self;
313}

◆ autoresizesSubviews

- (BOOL) autoresizesSubviews
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

553 {
554 return NO;
555}

◆ autosaveName

- (NSString *) autosaveName

◆ awakeFromNib

- (void) awakeFromNib
implementation

Definition at line 25 of file RBSplitView.m.

743 {
744 if ([RBSplitSubview instancesRespondToSelector:@selector(awakeFromNib)]) {
745 [super awakeFromNib];
746 }
747 if (![self splitView]) {
748 [self restoreState:YES];
749 }
750}
RBSplitView * splitView()
void awakeFromNib()

◆ background

- (NSColor *) background

◆ coupledSplitView

- (RBSplitView *) coupledSplitView
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

316 {
317 return [self isCoupled]?self:nil;
318}
return nil

◆ couplingSplitView

- (RBSplitView *) couplingSplitView
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

306 {
307 return isCoupled?[super couplingSplitView]:nil;
308}

◆ cursor:

+ (NSCursor *) cursor: (RBSVCursorType) type

Definition at line 25 of file RBSplitView.m.

33 :(RBSVCursorType)type {
34 if ((type>=0)&&(type<RBSVCursorTypeCount)) {
35 NSCursor* result = cursors[type];
36 if (result) {
37 return result;
38 }
39 switch (type) {
41 return [NSCursor resizeUpDownCursor];
43 return [NSCursor resizeLeftRightCursor];
44 case RBSV2WayCursor:
45 return [NSCursor openHandCursor];
46 case RBSVDragCursor:
47 return [NSCursor closedHandCursor];
48 default:
49 break;
50 }
51 }
52 return [NSCursor currentCursor];
53}
RBSVCursorType
Definition RBSplitView.h:13
@ RBSVHorizontalCursor
Definition RBSplitView.h:14
@ RBSVDragCursor
Definition RBSplitView.h:17
@ RBSVVerticalCursor
Definition RBSplitView.h:15
@ RBSVCursorTypeCount
Definition RBSplitView.h:18
@ RBSV2WayCursor
Definition RBSplitView.h:16
static NSCursor * cursors[RBSVCursorTypeCount]
Definition RBSplitView.m:18

◆ dealloc

- (void) dealloc
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

277 {
278 if (dividers) {
279 free(dividers);
280 }
281 [autosaveName release];
282 [divider release];
283 [background release];
284 [super dealloc];
285}
NSRect * dividers
Definition RBSplitView.h:29

◆ defaultsKeyForName:isHorizontal:

+ (NSString *) defaultsKeyForName: (NSString*) name
isHorizontal: (BOOL) orientation 

Definition at line 25 of file RBSplitView.m.

72 :(NSString*)name isHorizontal:(BOOL)orientation {
73 return [NSString stringWithFormat:@"RBSplitView %@ %@",orientation?@"H":@"V",name];
74}
BOOL isHorizontal
Definition RBSplitView.h:33

◆ delegate

- (id) delegate

◆ description

- (NSString *) description
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

389 {
390 return [NSString stringWithFormat:@"%@ {%@}",[super description],[self stringWithSavedState]];
391}

◆ display

- (void) display
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

753 {
754 if (mustAdjust&&!isAdjusting) {
755 [self adjustSubviews];
756 }
757 [super display];
758}
BOOL mustAdjust
Definition RBSplitView.h:31
BOOL isAdjusting
Definition RBSplitView.h:36

◆ divider

- (NSImage *) divider

◆ dividerThickness

- (CGFloat) dividerThickness

◆ drawDivider:inRect:betweenView:andView:

- (void) drawDivider: (NSImage*) anImage
inRect: (NSRect) rect
betweenView: (RBSplitSubview*) leading
andView: (RBSplitSubview*) trailing 

Definition at line 25 of file RBSplitView.m.

809 :(NSImage*)anImage inRect:(NSRect)rect betweenView:(RBSplitSubview*)leading andView:(RBSplitSubview*)trailing {
810// Fill the view with the background color (if there's any). Don't draw the background again for
811// thumbs.
812 if (leading||trailing) {
813 NSColor* bg = [self background];
814 if (bg) {
815 [bg set];
816 NSRectFillUsingOperation(rect,NSCompositeSourceOver);
817 }
818 }
819// Center the image, if there is one.
820 NSRect imrect = NSZeroRect;
821 NSRect dorect = NSZeroRect;
822 if (anImage) {
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));
826 }
827// Ask the delegate for the final rect where the image should be drawn.
828 if ([delegate respondsToSelector:@selector(splitView:willDrawDividerInRect:betweenView:andView:withProposedRect:)]) {
829 dorect = [delegate splitView:self willDrawDividerInRect:rect betweenView:leading andView:trailing withProposedRect:dorect];
830 }
831// Draw the image if the delegate returned a non-empty rect.
832 if (!NSIsEmptyRect(dorect)) {
833 [anImage drawInRect:dorect fromRect:imrect operation:NSCompositeSourceOver fraction:1.0];
834 }
835}
IBOutlet id delegate
Definition RBSplitView.h:25

◆ drawRect:

- (void) drawRect: (NSRect) rect
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

761 :(NSRect)rect {
762 [super drawRect:rect];
763 if (!dividers) {
764 return;
765 }
766 NSArray* subviews = [self RB___subviews];
767 NSUInteger subcount = [subviews count];
768// Return if there are no dividers to draw.
769 if (subcount<2) {
770 return;
771 }
772 --subcount;
773 NSUInteger i;
774// Cache the divider image.
775 NSImage* divdr = [self divider];
776 CGFloat divt = [self dividerThickness];
777// Loop over the divider rectangles.
778 for (i=0;i<subcount;i++) {
779// Check if we need to draw this particular divider.
780 if ([self needsToDrawRect:dividers[i]]) {
781 RBSplitView* leading = [subviews objectAtIndex:i];
782 RBSplitView* trailing = [subviews objectAtIndex:i+1];
783 BOOL lexp = divdr?![leading isCollapsed]:NO;
784 BOOL texp = divdr?![trailing isCollapsed]:NO;
785// We don't draw the divider image if either of the neighboring subviews is a non-collapsed
786// nested split view.
787 BOOL nodiv = (lexp&&[leading coupledSplitView])||(texp&&[trailing coupledSplitView]);
788 [self drawDivider:nodiv?nil:divdr inRect:dividers[i] betweenView:leading andView:trailing];
789 if (divdr) {
790// Draw the corresponding two-axis thumbs if the leading view is a nested RBSplitView.
791 if ((leading = [leading coupledSplitView])&&lexp) {
792 [leading RB___drawDividersIn:self forDividerRect:dividers[i] thickness:divt];
793 }
794// Draw the corresponding two-axis thumbs if the trailing view is a nested RBSplitView.
795 if ((trailing = [trailing coupledSplitView])&&texp) {
796 [trailing RB___drawDividersIn:self forDividerRect:dividers[i] thickness:divt];
797 }
798 }
799 }
800 }
801}
RBSplitView * coupledSplitView()
void RB___drawDividersIn:forDividerRect:thickness:(RBSplitView *masterView,[forDividerRect] NSRect rect,[thickness] CGFloat delta)

◆ encodeWithCoder:

- (void) encodeWithCoder: (NSCoder *) coder
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

890 :(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"];
900 } else {
901 [coder encodeConditionalObject:delegate];
902 [coder encodeObject:autosaveName];
903 [coder encodeObject:[divider TIFFRepresentation]];
904 [coder encodeObject:background];
905 [coder encodeValueOfObjCType:@encode(typeof(dividerThickness)) at:&dividerThickness];
906 [coder encodeValueOfObjCType:@encode(typeof(isHorizontal)) at:&isHorizontal];
907 [coder encodeValueOfObjCType:@encode(typeof(isCoupled)) at:&isCoupled];
908 }
909}

◆ initWithCoder:

- (id) initWithCoder: (NSCoder *) coder
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

911 :(NSCoder *)coder {
912 if ((self = [super initWithCoder:coder])) {
913 NSData* data = nil;
914 CGFloat divt = 0.0;
915 isCoupled = YES;
916 isDragging = NO;
917 isInScrollView = NO;
918 canSaveState = NO;
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"];
927 } else {
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];
935 }
936 dividers = NULL;
937 if (data) {
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];
943 } else {
944 [self setDivider:nil];
945 }
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];
950 }
951 return self;
952}
BOOL canSaveState
Definition RBSplitView.h:34
BOOL isInScrollView
Definition RBSplitView.h:38
BOOL isDragging
Definition RBSplitView.h:37

◆ initWithFrame:

- (id) initWithFrame: (NSRect) frame

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

248 :(NSRect)frame {
249 self = [super initWithFrame:frame];
250 if (self) {
251 dividers = NULL;
252 isCoupled = YES;
253 isDragging = NO;
254 isInScrollView = NO;
255 canSaveState = NO;
256 [self setVertical:YES];
257 [self setDivider:nil];
258 [self setAutosaveName:nil recursively:NO];
259 [self setBackground:nil];
260 }
261 return self;
262}

◆ initWithFrame:andSubviews:

- (id) initWithFrame: (NSRect) frame
andSubviews: (NSUInteger) count 

Definition at line 25 of file RBSplitView.m.

265 :(NSRect)frame andSubviews:(NSUInteger)count {
266 self = [self initWithFrame:frame];
267 if (self) {
268 while (count-->0) {
269 [self addSubview:[[[RBSplitSubview alloc] initWithFrame:frame] autorelease]];
270 }
271 [self setMustAdjust];
272 }
273 return self;
274}
unsigned count

◆ isAdjusting

- (BOOL) isAdjusting

◆ isDragging

- (BOOL) isDragging

◆ isFlipped

- (BOOL) isFlipped
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

327 {
328 return YES;
329}

◆ isHorizontal

- (BOOL) isHorizontal

◆ isInScrollView

- (BOOL) isInScrollView

◆ isOpaque

- (BOOL) isOpaque
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

382 {
383 RBSplitView* sv = [self couplingSplitView];
384 return sv?[sv isOpaque]:(background&&([background alphaComponent]>=1.0));
385}
NSColor * background
Definition RBSplitView.h:27

◆ isVertical

- (BOOL) isVertical

Definition at line 25 of file RBSplitView.m.

412 {
413 return ![self isHorizontal];
414}

◆ mouseDown:

- (void) mouseDown: (NSEvent*) theEvent
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

582 :(NSEvent*)theEvent {
583 if (!dividers) {
584 return;
585 }
586 NSArray* subviews = [self RB___subviews];
587 NSUInteger subcount = [subviews count];
588 if (subcount<2) {
589 return;
590 }
591// If the mousedown was in an alternate dragview, or if there's no divider image, handle it in RBSplitSubview.
592 if ((actDivider<NSNotFound)||![self divider]) {
593 [super mouseDown:theEvent];
594 return;
595 }
596 NSPoint where = [self convertPoint:[theEvent locationInWindow] fromView:nil];
597 BOOL ishor = [self isHorizontal];
598 NSUInteger i;
599 --subcount;
600// Loop over the divider rectangles.
601 for (i=0;i<subcount;i++) {
602 NSRect* divdr = &dividers[i];
603 if ([self mouse:where inRect:*divdr]) {
604// leading points at the subview immediately leading the divider being tracked.
605 RBSplitView* leading = [subviews objectAtIndex:i];
606// trailing points at the subview immediately trailing the divider being tracked.
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]) {
610 return;
611 }
612 }
613// If it's a double click, try to expand or collapse one of the neighboring subviews.
614 if ([theEvent clickCount]>1) {
615// If both are collapsed, we do nothing. If one of them is collapsed, we try to expand it.
616 if ([trailing isCollapsed]) {
617 if (![leading isCollapsed]) {
618 [self RB___tryToExpandTrailing:trailing leading:leading delta:-[trailing dimension]];
619 }
620 } else {
621 if ([leading isCollapsed]) {
622 [self RB___tryToExpandLeading:leading divider:i trailing:trailing delta:[leading dimension]];
623 } else {
624// If neither are collapsed, we check if both are collapsible.
625 BOOL lcan = [leading canCollapse];
626 BOOL tcan = [trailing canCollapse];
627 CGFloat ldim = [leading dimension];
628 if (lcan&&tcan) {
629// If both are collapsible, we try asking the delegate.
630 if ([delegate respondsToSelector:@selector(splitView:collapseLeading:orTrailing:)]) {
631 RBSplitSubview* sub = [delegate splitView:self collapseLeading:leading orTrailing:trailing];
632// If the delegate returns nil, neither view will collapse.
633 lcan = sub==leading;
634 tcan = sub==trailing;
635 } else {
636// Otherwise we try collapsing the smaller one. If they're equal, the trailing one will be collapsed.
637 lcan = ldim<[trailing dimension];
638 }
639 }
640// At this point, we'll try to collapse the leading subview.
641 if (lcan) {
642 [self RB___tryToShortenLeading:leading divider:i trailing:trailing delta:-ldim always:NO];
643 }
644// If the leading subview didn't collapse for some reason, we try to collapse the trailing one.
645 if (!mustAdjust&&tcan) {
646 [self RB___tryToShortenTrailing:trailing divider:i leading:leading delta:[trailing dimension] always:NO];
647 }
648 }
649 }
650// If the subviews have changed, clear the fractions, adjust and redisplay
651 if (mustAdjust) {
652 [self RB___setMustClearFractions];
653 RBSplitView* sv = [self splitView];
654 [sv?sv:self adjustSubviews];
655 [super display];
656 }
657 } else {
658// Single click; record the offsets within the divider rectangle and check for nesting.
659 CGFloat divt = [self dividerThickness];
660 CGFloat offset = DIM(where)-DIM(divdr->origin);
661// Check if the leading subview is nested and if yes, if one of its two-axis thumbs was hit.
662 NSInteger ldivdr = NSNotFound;
663 CGFloat loffset = 0.0;
664 NSPoint lwhere = where;
665 NSRect lrect = NSZeroRect;
666 if ((leading = [leading coupledSplitView])) {
667 ldivdr = [leading RB___dividerHitBy:lwhere relativeToView:self thickness:divt];
668 if (ldivdr!=NSNotFound) {
669 lrect = [leading RB___dividerRect:ldivdr relativeToView:self];
670 loffset = OTHER(lwhere)-OTHER(lrect.origin);
671 }
672 }
673// Check if the trailing subview is nested and if yes, if one of its two-axis thumbs was hit.
674 NSInteger tdivdr = NSNotFound;
675 CGFloat toffset = 0.0;
676 NSPoint twhere = where;
677 NSRect trect = NSZeroRect;
678 if ((trailing = [trailing coupledSplitView])) {
679 tdivdr = [trailing RB___dividerHitBy:twhere relativeToView:self thickness:divt];
680 if (tdivdr!=NSNotFound) {
681 trect = [trailing RB___dividerRect:tdivdr relativeToView:self];
682 toffset = OTHER(twhere)-OTHER(trect.origin);
683 }
684 }
685// Now we loop handling mouse events until we get a mouse up event, while showing the drag cursor.
686 [[RBSplitView cursor:RBSVDragCursor] push];
687 [self RB___setDragging:YES];
688 while ((theEvent = [NSApp nextEventMatchingMask:NSLeftMouseDownMask|NSLeftMouseDraggedMask|NSLeftMouseUpMask untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:YES])&&([theEvent type]!=NSLeftMouseUp)) {
689// Set up a local autorelease pool for the loop to prevent buildup of temporary objects.
690 NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
691 NSDisableScreenUpdates();
692// Track the mouse along the main coordinate.
693 [self RB___trackMouseEvent:theEvent from:where withBase:NSZeroPoint inDivider:i];
694 if (ldivdr!=NSNotFound) {
695// Track any two-axis thumbs for the leading nested RBSplitView.
696 [leading RB___trackMouseEvent:theEvent from:[self convertPoint:lwhere toView:leading] withBase:NSZeroPoint inDivider:ldivdr];
697 }
698 if (tdivdr!=NSNotFound) {
699// Track any two-axis thumbs for the trailing nested RBSplitView.
700 [trailing RB___trackMouseEvent:theEvent from:[self convertPoint:twhere toView:trailing] withBase:NSZeroPoint inDivider:tdivdr];
701 }
702 if (mustAdjust||[leading mustAdjust]||[trailing mustAdjust]) {
703// The mouse was dragged and the subviews changed, so we must redisplay, as
704// several divider rectangles may have changed.
705 RBSplitView* sv = [self splitView];
706 [sv?sv:self adjustSubviews];
707 [super display];
708 divdr = &dividers[i];
709// Adjust to the new cursor coordinates.
710 DIM(where) = DIM(divdr->origin)+offset;
711 if ((ldivdr!=NSNotFound)&&![leading isCollapsed]) {
712// Adjust for the leading nested RBSplitView's thumbs while it's not collapsed.
713 lrect = [leading RB___dividerRect:ldivdr relativeToView:self];
714 OTHER(lwhere) = OTHER(lrect.origin)+loffset;
715 }
716 if ((tdivdr!=NSNotFound)&&![trailing isCollapsed]) {
717// Adjust for the trailing nested RBSplitView's thumbs while it's not collapsed.
718 trect = [trailing RB___dividerRect:tdivdr relativeToView:self];
719 OTHER(twhere) = OTHER(trect.origin)+toffset;
720 }
721 }
722 NSEnableScreenUpdates();
723 [pool drain];
724 }
725 [self RB___setDragging:NO];
726// Redisplay the previous cursor.
727 [NSCursor pop];
728 }
729 }
730 }
731}
#define OTHER(x)
#define DIM(x)
NSUInteger actDivider
void RB___trackMouseEvent:from:withBase:inDivider:(NSEvent *theEvent,[from] NSPoint where,[withBase] NSPoint base,[inDivider] NSUInteger indx)
NSUInteger RB___dividerHitBy:relativeToView:thickness:(NSPoint point,[relativeToView] RBSplitView *view,[thickness] CGFloat delta)
NSImage * divider
Definition RBSplitView.h:28
NSCursor * cursor:(RBSVCursorType type)
Definition RBSplitView.m:33
NSRect RB___dividerRect:relativeToView:(NSUInteger indx,[relativeToView] RBSplitView *view)
voidpf uLong int origin
Definition ioapi.h:140
voidpf uLong offset
Definition ioapi.h:140

◆ mouseDownCanMoveWindow

- (BOOL) mouseDownCanMoveWindow
implementation

Definition at line 25 of file RBSplitView.m.

321 {
322 return NO;
323}

◆ mustAdjust

- (BOOL) mustAdjust

◆ needsDisplay

- (BOOL) needsDisplay
implementation

Definition at line 25 of file RBSplitView.m.

734 {
735 if (mustAdjust&&!isAdjusting) {
736 [self adjustSubviews];
737 return YES;
738 }
739 return [super needsDisplay];
740}

◆ RB___addCursorRectsTo:forDividerRect:thickness:

- (void) RB___addCursorRectsTo: (RBSplitView*) masterView
forDividerRect: (NSRect) rect
thickness: (CGFloat) delta 
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1370 :(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;
1374 if (divcount<1) {
1375 return;
1376 }
1377 NSInteger i;
1378 NSCursor* cursor = [RBSplitView cursor:RBSV2WayCursor];
1379 BOOL ishor = [self isHorizontal];
1380// Loop over the divider rectangles, intersect them with the view's own, and add the thumb rectangle
1381// to the containing split view.
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];
1390 }
1391 }
1392 }
1393}

◆ RB___adjustOutermostIfNeeded

- (void) RB___adjustOutermostIfNeeded
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1424 {
1425 RBSplitView* sv = [self splitView];
1426 if (sv) {
1428 return;
1429 }
1430 if (mustAdjust&&!isAdjusting) {
1431 [self adjustSubviews];
1432 }
1433}
void RB___adjustOutermostIfNeeded()

◆ RB___adjustSubviewsExcepting:

- (void) RB___adjustSubviewsExcepting: (RBSplitSubview*) excepting
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1440 :(RBSplitSubview*)excepting {
1441 mustAdjust = NO;
1442 NSArray* subviews = [self RB___subviews];
1443 NSUInteger subcount = [subviews count];
1444 if (subcount<1) {
1445 return;
1446 }
1447 NSRect bounds = [self bounds];
1448// Never adjust if the splitview itself is collapsed.
1449 if ((bounds.size.width<1.0)||(bounds.size.height<1.0)) {
1450 return;
1451 }
1452// Prevents adjustSubviews being called recursively, which unfortunately may happen otherwise.
1453 if (isAdjusting) {
1454 return;
1455 }
1456 isAdjusting = YES;
1457// Tell the delegate we're about to adjust subviews.
1458 if ([delegate respondsToSelector:@selector(willAdjustSubviews:)]) {
1459 [delegate willAdjustSubviews:self];
1460 bounds = [self bounds];
1461 }
1462 NSUInteger divcount = subcount-1;
1463 if (divcount<1) {
1464// No dividers at all.
1465 if (dividers) {
1466 free(dividers);
1467 dividers = NULL;
1468 }
1469 } else {
1470// Try to allocate or resize if we already have a dividers array.
1471 NSUInteger divsiz = sizeof(NSRect)*divcount;
1472 dividers = (NSRect*)(dividers?reallocf(dividers,divsiz):malloc(divsiz));
1473 if (!dividers) {
1474 return;
1475 }
1476 }
1477// This C array of subviewCaches is used to cache the subview information.
1478 subviewCache* caches = (subviewCache*)malloc(sizeof(subviewCache)*subcount);
1479 double realsize = 0.0;
1480 double expsize = 0.0;
1481 CGFloat newsize = 0.0;
1482 CGFloat effsize = 0.0;
1483 CGFloat limit;
1484 subviewCache* curr;
1485 NSUInteger i;
1486 BOOL ishor = [self isHorizontal];
1487 CGFloat divt = [self dividerThickness];
1488// First we loop over subviews and cache their information.
1489 for (i=0;i<subcount;i++) {
1490 curr = &caches[i];
1491 [[subviews objectAtIndex:i] RB___copyIntoCache:curr];
1492 }
1493// This is a counter to limit the outer loop to three iterations (six if excepting is non-nil).
1494 NSInteger sanity = excepting?-3:0;
1495 while (sanity++<3) {
1496// We try to accomodate the exception for the first group of loops, turn it off for the second.
1497 if (sanity==1) {
1498 excepting = nil;
1499 }
1500// newsize is the available space for actual subviews (so dividers don't count). It will be an integer.
1501// Same as calling [self RB___dimensionWithoutDividers].
1502 NSUInteger smallest = 0;
1503 CGFloat smalldim = -1.0;
1504 BOOL haveexp = NO;
1505// Loop over subviews and sum the expanded dimensions into expsize, including fractions.
1506// Also find the collapsed subview with the smallest minimum dimension.
1507 for (i=0;i<subcount;i++) {
1508 curr = &caches[i];
1509 curr->constrain = NO;
1510 if (curr->size>0.0) {
1511 expsize += curr->size;
1512 if (!isInScrollView) {
1513// ignore fractions if we're in a NSScrollView, however.
1514 expsize += curr->fraction;
1515 }
1516 haveexp = YES;
1517 } else {
1518 limit = [curr->sub minDimension];
1519 if (smalldim>limit) {
1520 smalldim = limit;
1521 smallest = i;
1522 }
1523 }
1524 }
1525// haveexp should be YES at this point. If not, all subviews were collapsed; can't have that, so we
1526// expand the smallest subview (or the first, if all have the same minimum).
1527 curr = &caches[smallest];
1528 if (!haveexp) {
1529 curr->size = [curr->sub minDimension];
1530 curr->fraction = 0.0;
1531 expsize += curr->size;
1532 }
1533 if (isInScrollView) {
1534// If we're inside an NSScrollView, we just grow the view to accommodate the subviews, instead of
1535// the other way around.
1536 DIM(bounds.size) = expsize;
1537 break;
1538 } else {
1539// If the total dimension of all expanded subviews is less than 1.0 we set the dimension of the smallest
1540// subview (which we're sure is expanded at this point) to the available space.
1541 newsize = DIM(bounds.size)-divcount*divt;
1542 if (expsize<1.0) {
1543 curr->size = newsize;
1544 curr->fraction = 0.0;
1545 expsize = newsize;
1546 }
1547// Loop over the subviews and check if they're within the limits after scaling. We also recalculate the
1548// exposed size and repeat until no more subviews hit the constraints during that loop.
1549 BOOL constrained;
1550 effsize = newsize;// we're caching newsize here, this is an integer.
1551 do {
1552// scale is the scalefactor by which all views should be scaled - assuming none have constraints.
1553// It's a double to (hopefully) keep rounding errors small enough for all practical purposes.
1554 double scale = newsize/expsize;
1555 constrained = NO;
1556 realsize = 0.0;
1557 expsize = 0.0;
1558 for (i=0;i<subcount;i++) {
1559// Loop over the cached subview info.
1560 curr = &caches[i];
1561 if (curr->size>0.0) {
1562// Check non-collapsed subviews only.
1563 if (!curr->constrain) {
1564// Check non-constrained subviews only; calculate the proposed new size.
1565 CGFloat cursize = (curr->size+curr->fraction)*scale;
1566// Check if we hit a limit. limit will contain either the max or min dimension, whichever was hit.
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]))) {
1571// If we hit a limit, we mark the view and set to repeat the loop; non-constrained subviews will
1572// have to be recalculated.
1573 curr->constrain = constrained = YES;
1574// We set the new size to the limit we hit, and subtract it from the total size to be subdivided.
1575 cursize = limit;
1576 curr->fraction = 0.0;
1577 newsize -= cursize;
1578 } else {
1579// If we didn't hit a limit, we round the size to the nearest integer and recalculate the fraction.
1580 double rem = fmod(cursize,1.0);
1581 cursize -= rem;
1582 if (rem>0.5) {
1583 ++cursize;
1584 --rem;
1585 }
1586 expsize += cursize;
1587 curr->fraction = rem;
1588 }
1589// We store the new size in the cache.
1590 curr->size = cursize;
1591 }
1592// And add the full size with fraction to the actual sum of all expanded subviews.
1593 realsize += curr->size+curr->fraction;
1594 }
1595 }
1596// At this point, newsize will be the sum of the new dimensions of non-constrained views.
1597// expsize will be the sum of the recalculated dimensions of the same views, if any.
1598// We repeat the loop if any view has been recently constrained, and if there are any
1599// unconstrained views left.
1600 } while (constrained&&(expsize>0.0));
1601// At this point, the difference between realsize and effsize should be less than 1 pixel.
1602// realsize is the total size of expanded subviews as recalculated above, and
1603// effsize is the value realsize should have.
1604 limit = realsize-effsize;
1605 if (limit>=1.0) {
1606// If realsize is larger than effsize by 1 pixel or more, we will need to collapse subviews to make room.
1607// This in turn might expand previously collapsed subviews. So, we'll try collapsing constrained subviews
1608// until we're back into range, and then recalculate everything from the beginning.
1609 for (i=0;i<subcount;i++) {
1610 curr = &caches[i];
1611 if (curr->constrain&&(curr->sub!=excepting)&&([curr->sub RB___animationData:NO resize:NO]==nil)&&[curr->sub canCollapse]) {
1612 realsize -= curr->size;
1613 if (realsize<1.0) {
1614 break;
1615 }
1616 curr->size = 0.0;
1617 if ((realsize-effsize)<1.0) {
1618 break;
1619 }
1620 }
1621 }
1622 } else if (limit<=-1.0) {
1623// If realsize is smaller than effsize by 1 pixel or more, we will need to expand subviews.
1624// This in turn might collapse previously expanded subviews. So, we'll try expanding collapsed subviews
1625// until we're back into range, and then recalculate everything from the beginning.
1626 for (i=0;i<subcount;i++) {
1627 curr = &caches[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) {
1633 break;
1634 }
1635 }
1636 }
1637 } else {
1638// The difference is less than 1 pixel, meaning that in all probability our calculations are
1639// exact or off by at most one pixel after rounding, so we break the loop here.
1640 break;
1641 }
1642 }
1643// After passing through the outer loop a few times, the frames may still be wrong, but there's nothing
1644// else we can do about it. You probably should avoid this by some other means like setting a minimum
1645// or maximum size for the window, for instance, or leaving at least one unlimited subview.
1646 }
1647// newframe is used to reset all subview frames. Subviews always fill the entire RBSplitView along the
1648// current orientation.
1649 NSRect newframe = NSMakeRect(0.0,0.0,bounds.size.width,bounds.size.height);
1650// We now loop over the subviews yet again and set the definite frames, also recalculating the
1651// divider rectangles as we go along, and collapsing and expanding subviews whenever requested.
1652 RBSplitSubview* last = nil;
1653// And we make a note if there's any nested RBSplitView.
1654 NSInteger nested = NSNotFound;
1655// newsize = DIM(bounds.size)-divcount*divt;
1656 for (i=0;i<subcount;i++) {
1657 curr = &caches[i];
1658// If we have a nested split view store its index.
1659 if ((nested==NSNotFound)&&([curr->sub asSplitView]!=nil)) {
1660 nested = i;
1661 }
1662// Adjust the subview to the correct origin and resize it to fit into the "other" dimension.
1663 curr->rect.origin = newframe.origin;
1664 OTHER(curr->rect.size) = OTHER(newframe.size);
1665 DIM(curr->rect.size) = curr->size;
1666// Clear fractions for expanded subviews if requested.
1667 if ((curr->size>0.0)&&mustClearFractions) {
1668 curr->fraction = 0.0;
1669 }
1670// Ask the subview to do the actual moving/resizing etc. from the cache.
1671 [curr->sub RB___updateFromCache:curr withTotalDimension:effsize];
1672// Step to the next position and record the subview if it's not collapsed.
1673 DIM(newframe.origin) += curr->size;
1674 if (curr->size>0.0) {
1675 last = curr->sub;
1676 }
1677 if (i==divcount) {
1678// We're at the last subview, so we now check if the actual and calculated dimensions
1679// are the same.
1680 CGFloat remain = DIM(bounds.size)-DIM(newframe.origin);
1681 if (last&&(fabs(remain)>0.0)) {
1682// We'll resize the last expanded subview to whatever it takes to squeeze within the frame.
1683// Normally the change should be at most one pixel, but if too many subviews were constrained,
1684// this may be a large value, and the last subview may be resized beyond its constraints;
1685// there's nothing else to do at this point.
1686 newframe = [last frame];
1687 DIM(newframe.size) += remain;
1688 [last RB___setFrameSize:newframe.size withFraction:[last RB___fraction]-remain];
1689// And we loop back over the rightmost dividers (if any) to adjust their offsets.
1690 while ((i>0)&&(last!=[subviews objectAtIndex:i])) {
1691 DIM(dividers[--i].origin) += remain;
1692 }
1693 break;
1694 }
1695 } else {
1696// For any but the last subview, we just calculate the divider frame.
1697 DIM(newframe.size) = divt;
1698 if (dividers) { // test for NULL to satisfy the analyzer
1699 dividers[i] = newframe;
1700 }
1701 DIM(newframe.origin) += divt;
1702 }
1703 }
1704// We resize our frame at this point, if we're inside an NSScrollView.
1705 if (isInScrollView) {
1706 [super setFrameSize:bounds.size];
1707 }
1708// If there was at least one nested RBSplitView, we loop over the subviews and adjust those that need it.
1709 for (i=nested;i<subcount;i++) {
1710 curr = &caches[i];
1711 RBSplitView* sv = [curr->sub asSplitView];
1712 if ([sv mustAdjust]) {
1713 [sv adjustSubviews];
1714 }
1715 }
1716// Free the cache array.
1717 free(caches);
1718// Clear cursor rects.
1719 mustAdjust = NO;
1720 mustClearFractions = NO;
1721 [[self window] invalidateCursorRectsForView:self];
1722// Save the state for all subviews.
1723 if (!isDragging) {
1724 [self saveState:NO];
1725 }
1726// If we're a nested RBSplitView, also invalidate cursorRects for the superview.
1727 RBSplitView* sv = [self couplingSplitView];
1728 if (sv) {
1729 [[self window] invalidateCursorRectsForView:sv];
1730 }
1731 isAdjusting = NO;
1732// Tell the delegate we're finished.
1733 if ([delegate respondsToSelector:@selector(didAdjustSubviews:)]) {
1734 [delegate didAdjustSubviews:self];
1735 }
1736}
void RB___setFrameSize:withFraction:(NSSize size,[withFraction] double value)
void adjustSubviews()
voidpf void uLong size
Definition ioapi.h:134

◆ RB___dimensionWithoutDividers

- (CGFloat) RB___dimensionWithoutDividers
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1011 {
1012 BOOL ishor = [self isHorizontal];
1013 NSSize size = [self frame].size;
1014 return fMAX(1.0,DIM(size)-[self dividerThickness]*([self RB___numberOfSubviews]-1));
1015}
static CGFloat fMAX(CGFloat a, CGFloat b)
Definition RBSplitView.m:25

◆ RB___dividerHitBy:relativeToView:thickness:

- (NSUInteger) RB___dividerHitBy: (NSPoint) point
relativeToView: (RBSplitView*) view
thickness: (CGFloat) delta 
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1034 :(NSPoint)point relativeToView:(RBSplitView*)view thickness:(CGFloat)delta {
1035 if (!dividers) {
1036 return NSNotFound;
1037 }
1038 NSInteger divcount = [self RB___numberOfSubviews]-1;
1039 if (divcount<1) {
1040 return NSNotFound;
1041 }
1042 NSInteger i;
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]) {
1050 return i;
1051 }
1052 }
1053 return NSNotFound;
1054}

◆ RB___dividerOrigin:

- (CGFloat) RB___dividerOrigin: (NSUInteger) indx
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

983 :(NSUInteger)indx {
984 CGFloat result = 0.0;
985 if (dividers) {
986 BOOL ishor = [self isHorizontal];
987 result = DIM(dividers[indx].origin);
988 }
989 return result;
990}

◆ RB___dividerRect:relativeToView:

- (NSRect) RB___dividerRect: (NSUInteger) indx
relativeToView: (RBSplitView*) view 
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1020 :(NSUInteger)indx relativeToView:(RBSplitView*)view {
1021 if (dividers&&(indx<[self RB___numberOfSubviews]-1)) {
1022 NSRect result = dividers[indx];
1023 if (view&&(view!=self)) {
1024 result = [self convertRect:result toView:view];
1025 }
1026 return result;
1027 }
1028 return NSZeroRect;
1029}

◆ RB___dividerThickness

- (CGFloat) RB___dividerThickness
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1006 {
1007 return dividerThickness;
1008}

◆ RB___drawDividersIn:forDividerRect:thickness:

- (void) RB___drawDividersIn: (RBSplitView*) masterView
forDividerRect: (NSRect) rect
thickness: (CGFloat) delta 
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1396 :(RBSplitView*)masterView forDividerRect:(NSRect)rect thickness:(CGFloat)delta {
1397 if (!dividers) {
1398 return;
1399 }
1400 NSArray* subviews = [self RB___subviews];
1401 NSInteger divcount = [subviews count]-1;
1402 if (divcount<1) {
1403 return;
1404 }
1405 NSInteger i;
1406 BOOL ishor = [self isHorizontal];
1407// Get the outer split view's divider image.
1408 NSImage* image = [masterView divider];
1409// Loop over the divider rectangles, intersect them with the view's own, and draw the thumb there.
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)) {
1417 [masterView drawDivider:image inRect:divdr betweenView:nil andView:nil];
1418 }
1419 }
1420}
void drawDivider:inRect:betweenView:andView:(NSImage *anImage,[inRect] NSRect rect,[betweenView] RBSplitSubview *leading,[andView] RBSplitSubview *trailing)

◆ RB___numberOfSubviews

- (NSUInteger) RB___numberOfSubviews
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

972 {
973 NSUInteger result = 0;
974 for (RBSplitSubview* sub in [self subviews]) {
975 if (![sub isHidden]) {
976 ++result;
977 }
978 }
979 return result;
980}

◆ RB___setDragging:

- (void) RB___setDragging: (BOOL) flag
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

963 :(BOOL)flag {
964 BOOL save = isDragging&&!flag;
965 isDragging = flag;
966 if (save) {
967 [self saveState:NO];
968 }
969}

◆ RB___setMustClearFractions

- (void) RB___setMustClearFractions
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1057 {
1058 mustClearFractions = YES;
1059}

◆ RB___shouldResizeWindowForDivider:betweenView:andView:willGrow:

- (BOOL) RB___shouldResizeWindowForDivider: (NSUInteger) indx
betweenView: (RBSplitSubview*) leading
andView: (RBSplitSubview*) trailing
willGrow: (BOOL) grow 
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1063 :(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];
1066 }
1067 return NO;
1068}

◆ RB___subviews

- (NSArray *) RB___subviews
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

993 {
994 NSMutableArray* result = [NSMutableArray arrayWithArray:[self subviews]];
995 NSInteger i;
996 for (i=[result count]-1;i>=0;i--) {
997 RBSplitSubview* view = [result objectAtIndex:i];
998 if ([view isHidden]) {
999 [result removeObjectAtIndex:i];
1000 }
1001 }
1002 return result;
1003}

◆ RB___trackMouseEvent:from:withBase:inDivider:

- (void) RB___trackMouseEvent: (NSEvent*) theEvent
from: (NSPoint) where
withBase: (NSPoint) base
inDivider: (NSUInteger) indx 
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1300 :(NSEvent*)theEvent from:(NSPoint)where withBase:(NSPoint)base inDivider:(NSUInteger)indx {
1301 NSArray* subviews = [self RB___subviews];
1302 NSUInteger subcount = [subviews count];
1303// Make sure that the divider number is valid.
1304 if (indx>=subcount) {
1305 return;
1306 }
1307 NSPoint result;
1308 NSUInteger k;
1309// leading and trailing point at the subviews immediately leading and trailing the divider being tracked
1310 RBSplitSubview* leading = [subviews objectAtIndex:indx];
1311 RBSplitSubview* trailing = [subviews objectAtIndex:indx+1];
1312// Convert the mouse coordinates to apply to the same system the divider rects are in.
1313 NSPoint mouse = [self convertPoint:[theEvent locationInWindow] fromView:nil];
1314 mouse.x -= base.x;
1315 mouse.y -= base.y;
1316 result.x = mouse.x-where.x;
1317 result.y = mouse.y-where.y;
1318// delta is the actual amount the mouse has moved in the relevant coordinate since the last event.
1319 BOOL ishor = [self isHorizontal];
1320 CGFloat delta = DIM(result);
1321 if (delta<0.0) {
1322// Negative delta means the mouse is being moved left or upwards.
1323// firstLeading will point at the first expanded subview to the left (or upwards) of the divider.
1324// If there's none (all subviews are collapsed) it will point at the nearest subview.
1325 RBSplitSubview* firstLeading = leading;
1326 k = indx;
1327 while (![firstLeading canShrink]) {
1328 if (k==0) {
1329 firstLeading = leading;
1330 break;
1331 }
1332 firstLeading = [subviews objectAtIndex:--k];
1333 }
1334 if (isInScrollView) {
1335 trailing = nil;
1336 }
1337// If the trailing subview is collapsed, it might be expanded if some conditions are met.
1338 if ([trailing isCollapsed]) {
1339 [self RB___tryToExpandTrailing:trailing leading:firstLeading delta:delta];
1340 } else {
1341 [self RB___tryToShortenLeading:firstLeading divider:indx trailing:trailing delta:delta always:YES];
1342 }
1343 } else if (delta>0.0) {
1344// Positive delta means the mouse is being moved right or downwards.
1345// firstTrailing will point at the first expanded subview to the right (or downwards) of the divider.
1346// If there's none (all subviews are collapsed) it will point at the nearest subview.
1347 RBSplitSubview* firstTrailing = nil;
1348 if (!isInScrollView) {
1349 firstTrailing = trailing;
1350 k = indx+1;
1351 while (![firstTrailing canShrink]) {
1352 if (++k>=subcount) {
1353 firstTrailing = trailing;
1354 break;
1355 }
1356 firstTrailing = [subviews objectAtIndex:k];
1357 }
1358 }
1359// If the leading subview is collapsed, it might be expanded if some conditions are met.
1360 if ([leading isCollapsed]) {
1361 [self RB___tryToExpandLeading:leading divider:indx trailing:firstTrailing delta:delta];
1362 } else {
1363// The leading subview is not collapsed, so we try to shorten or even collapse it
1364 [self RB___tryToShortenTrailing:firstTrailing divider:indx leading:leading delta:delta always:YES];
1365 }
1366 }
1367}
float y
float x

◆ RB___tryToExpandLeading:divider:trailing:delta:

- (void) RB___tryToExpandLeading: (RBSplitSubview*) leading
divider: (NSUInteger) indx
trailing: (RBSplitSubview*) trailing
delta: (CGFloat) delta 
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1071 :(RBSplitSubview*)leading divider:(NSUInteger)indx trailing:(RBSplitSubview*)trailing delta:(CGFloat)delta {
1072 NSWindow* window = nil;
1073 NSView* document = nil;
1074 NSSize maxsize = NSMakeSize(WAYOUT,WAYOUT);
1075 NSRect frame = NSZeroRect;
1076 NSRect screen = NSMakeRect(0,0,WAYOUT,WAYOUT);
1077 BOOL ishor = NO;
1078// First we ask the delegate, if there's any, if the window should resize.
1079 BOOL dowin = ([self RB___shouldResizeWindowForDivider:indx betweenView:leading andView:trailing willGrow:YES]);
1080 if (dowin) {
1081// We initialize the other local variables only if we need them for the window.
1082 ishor = [self isHorizontal];
1083 document = [[self enclosingScrollView] documentView];
1084 if (document) {
1085 frame = [document frame];
1086 } else {
1087 window = [self window];
1088 frame = [window frame];
1089 maxsize = [window maxSize];
1090 screen = [[NSScreen mainScreen] visibleFrame];
1091 }
1092 }
1093// The mouse has to move over half of the expanded size (plus hysteresis) and the expansion shouldn't
1094// reduce the trailing subview to less than its minimum size (or grow the window beyond its maximum).
1095 CGFloat limit = [leading minDimension];
1096 CGFloat dimension = 0.0;
1097 if (dowin) {
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);
1100 } else {
1101 dimension = trailing?[trailing dimension]:WAYOUT;
1102 }
1103 if (limit>dimension) {
1104 return;
1105 }
1106 if (!dowin&&trailing) {
1107 limit += [trailing minDimension];
1108 if (limit>dimension) {
1109// If the trailing subview is going below its minimum, we try to collapse it first.
1110// However, we don't collapse if that would cause the leading subview to become larger than its maximum.
1111 if (([trailing canCollapse])&&(delta>(0.5+HYSTERESIS)*dimension)&&([leading maxDimension]<=dimension)) {
1112 delta = -[trailing RB___collapse];
1113 [leading changeDimensionBy:delta mayCollapse:NO move:NO];
1114 }
1115 return;
1116 }
1117 }
1118// The leading subview may be expanded normally.
1119 delta = -[leading changeDimensionBy:delta mayCollapse:NO move:NO];
1120 if (dowin) {
1121// If it does expand, we widen the window.
1122 DIM(frame.size) -= delta;
1123 if (ishor) {
1124 DIM(frame.origin) += delta;
1125 }
1126 if (document) {
1127 [document setFrame:frame];
1128 [document setNeedsDisplay:YES];
1129 } else {
1130 [window setFrame:frame display:YES];
1131 }
1132 [self setMustAdjust];
1133 } else {
1134// If it does expand, we shorten the trailing subview.
1135 [trailing changeDimensionBy:delta mayCollapse:NO move:YES];
1136 }
1137}
#define HYSTERESIS
#define WAYOUT
static CGFloat fMIN(CGFloat a, CGFloat b)
Definition RBSplitView.m:21
CGFloat changeDimensionBy:mayCollapse:move:(CGFloat increment,[mayCollapse] BOOL mayCollapse,[move] BOOL move)

◆ RB___tryToExpandTrailing:leading:delta:

- (void) RB___tryToExpandTrailing: (RBSplitSubview*) trailing
leading: (RBSplitSubview*) leading
delta: (CGFloat) delta 
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1267 :(RBSplitSubview*)trailing leading:(RBSplitSubview*)leading delta:(CGFloat)delta {
1268// The mouse has to move over half of the expanded size (plus hysteresis) and the expansion shouldn't
1269// reduce the leading subview to less than its minimum size. If it does, we try to collapse it first.
1270// However, we don't collapse if that would cause the trailing subview to become larger than its maximum.
1271 CGFloat limit = trailing?[trailing minDimension]:0.0;
1272 CGFloat dimension = [leading dimension];
1273 if (limit>dimension) {
1274 return;
1275 }
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];
1280 [trailing changeDimensionBy:delta mayCollapse:NO move:YES];
1281 }
1282 return;
1283 }
1284// The trailing subview may be expanded normally. If it does expand, we shorten the leading subview.
1285 if (trailing) {
1286 delta = -[trailing changeDimensionBy:-delta mayCollapse:NO move:YES];
1287 }
1288 [leading changeDimensionBy:delta mayCollapse:NO move:NO];
1289}

◆ RB___tryToShortenLeading:divider:trailing:delta:always:

- (void) RB___tryToShortenLeading: (RBSplitSubview*) leading
divider: (NSUInteger) indx
trailing: (RBSplitSubview*) trailing
delta: (CGFloat) delta
always: (BOOL) always 
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1142 :(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;
1147 BOOL ishor = NO;
1148// First we ask the delegate, if there's any, if the window should resize.
1149 BOOL dowin = ([self RB___shouldResizeWindowForDivider:indx betweenView:leading andView:trailing willGrow:NO]);
1150 if (dowin) {
1151// We initialize the other local variables only if we need them for the window.
1152 ishor = [self isHorizontal];
1153 document = [[self enclosingScrollView] documentView];
1154 if (document) {
1155 frame = [document frame];
1156 } else {
1157 window = [self window];
1158 frame = [window frame];
1159 minsize = [window minSize];
1160 }
1161 }
1162// We avoid making the trailing subview larger than its maximum, or the window smaller than its minimum.
1163 CGFloat limit = 0.0;
1164 if (dowin) {
1165 limit = DIM(frame.size)-DIM(minsize);
1166 } else {
1167 limit = trailing?([trailing maxDimension]-[trailing dimension]):WAYOUT;
1168 }
1169 if (-delta>limit) {
1170 if (always) {
1171 delta = -limit;
1172 } else {
1173 return;
1174 }
1175 }
1176 BOOL okl = limit>=[leading dimension];
1177 if (always||okl) {
1178// Resize leading.
1179 delta = -[leading changeDimensionBy:delta mayCollapse:okl move:NO];
1180 if (dowin) {
1181// Resize the window.
1182 DIM(frame.size) -= delta;
1183 if (ishor) {
1184 DIM(frame.origin) += delta;
1185 }
1186 if (document) {
1187 [document setFrame:frame];
1188 [document setNeedsDisplay:YES];
1189 } else {
1190 [window setFrame:frame display:YES];
1191 }
1192 [self setMustAdjust];
1193 } else {
1194// Otherwise, resize trailing.
1195 [trailing changeDimensionBy:delta mayCollapse:NO move:YES];
1196 }
1197 }
1198}

◆ RB___tryToShortenTrailing:divider:leading:delta:always:

- (void) RB___tryToShortenTrailing: (RBSplitSubview*) trailing
divider: (NSUInteger) indx
leading: (RBSplitSubview*) leading
delta: (CGFloat) delta
always: (BOOL) always 
implementation

Provided by category RBSplitView(RB___ViewAdditions).

Definition at line 25 of file RBSplitView.m.

1203 :(RBSplitSubview*)trailing divider:(NSUInteger)indx leading:(RBSplitSubview*)leading delta:(CGFloat)delta always:(BOOL)always {
1204 NSWindow* window = nil;
1205 NSView* document = nil;
1206 NSSize maxsize = NSMakeSize(WAYOUT,WAYOUT);
1207 NSRect frame = NSZeroRect;
1208 NSRect screen = NSMakeRect(0,0,WAYOUT,WAYOUT);
1209 BOOL ishor = NO;
1210// First we ask the delegate, if there's any, if the window should resize.
1211 BOOL dowin = ([self RB___shouldResizeWindowForDivider:indx betweenView:leading andView:trailing willGrow:YES]);
1212 if (dowin) {
1213// We initialize the other local variables only if we need them for the window.
1214 ishor = [self isHorizontal];
1215 document = [[self enclosingScrollView] documentView];
1216 if (document) {
1217 frame = [document frame];
1218 } else {
1219 window = [self window];
1220 frame = [window frame];
1221 maxsize = [window maxSize];
1222 screen = [[NSScreen mainScreen] visibleFrame];
1223 }
1224 }
1225// We avoid making the leading subview larger than its maximum, or the window larger than its maximum.
1226 CGFloat limit = 0.0;
1227 if (dowin) {
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);
1230 } else {
1231 limit = [leading maxDimension]-[leading dimension];
1232 }
1233 if (delta>limit) {
1234 if (always) {
1235 delta = limit;
1236 } else {
1237 return;
1238 }
1239 }
1240 BOOL okl = dowin||(limit>=(trailing?[trailing dimension]:WAYOUT));
1241 if (always||okl) {
1242 if (dowin) {
1243// If we should resize the window, resize leading, then the window.
1244 delta = [leading changeDimensionBy:delta mayCollapse:NO move:NO];
1245 DIM(frame.size) += delta;
1246 if (ishor) {
1247 DIM(frame.origin) -= delta;
1248 }
1249 if (document) {
1250 [document setFrame:frame];
1251 [document setNeedsDisplay:YES];
1252 } else {
1253 [window setFrame:frame display:YES];
1254 }
1255 [self setMustAdjust];
1256 } else {
1257// Otherwise, resize trailing, then leading.
1258 if (trailing) {
1259 delta = -[trailing changeDimensionBy:-delta mayCollapse:okl move:YES];
1260 }
1261 [leading changeDimensionBy:delta mayCollapse:NO move:NO];
1262 }
1263 }
1264}

◆ removeStateUsingName:

+ (void) removeStateUsingName: (NSString*) name

Definition at line 25 of file RBSplitView.m.

63 :(NSString*)name {
64 if ([name length]) {
65 NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
66 [defaults removeObjectForKey:[[self class] defaultsKeyForName:name isHorizontal:NO]];
67 [defaults removeObjectForKey:[[self class] defaultsKeyForName:name isHorizontal:YES]];
68 }
69}

◆ resetCursorRects

- (void) resetCursorRects
implementation

Definition at line 25 of file RBSplitView.m.

850 {
851 if (!dividers) {
852 return;
853 }
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];
859 return;
860 }
861 NSInteger i;
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];
866// If the leading subview is a nested RBSplitView, add the thumb rectangles first.
867 if (sub) {
868 [sub RB___addCursorRectsTo:self forDividerRect:dividers[i] thickness:divt];
869 }
870 sub = [[subviews objectAtIndex:i+1] coupledSplitView];
871// If the trailing subview is a nested RBSplitView, add the thumb rectangles first.
872 if (sub) {
873 [sub RB___addCursorRectsTo:self forDividerRect:dividers[i] thickness:divt];
874 }
875// Now add the divider rectangle.
876 NSRect divrect = dividers[i];
877 if (del) {
878 divrect = [del splitView:self cursorRect:divrect forDivider:i];
879 }
880 if (!NSIsEmptyRect(divrect)) {
881 [self addCursorRect:divrect cursor:cursor];
882 }
883 }
884}
void RB___addCursorRectsTo:forDividerRect:thickness:(RBSplitView *masterView,[forDividerRect] NSRect rect,[thickness] CGFloat delta)

◆ restoreState:

- (BOOL) restoreState: (BOOL) recurse

Definition at line 25 of file RBSplitView.m.

129 :(BOOL)recurse {
130 BOOL result = NO;
131 if ([autosaveName length]) {
132 result = [self setStateFromString:[[NSUserDefaults standardUserDefaults] stringForKey:[[self class] defaultsKeyForName:autosaveName isHorizontal:[self isHorizontal]]]];
133 if (result&&recurse) {
134 for (RBSplitSubview* sub in [self subviews]){
135 [[sub asSplitView] restoreState:YES];
136 }
137 }
138 }
139 canSaveState = YES;
140 return result;
141}
NSString * autosaveName
Definition RBSplitView.h:26

◆ saveState:

- (BOOL) saveState: (BOOL) recurse

Definition at line 25 of file RBSplitView.m.

112 :(BOOL)recurse {
113// Saving the state is also disabled while dragging.
114 if (canSaveState&&![self isDragging]&&[autosaveName length]) {
115 [[NSUserDefaults standardUserDefaults] setObject:[self stringWithSavedState] forKey:[[self class] defaultsKeyForName:autosaveName isHorizontal:[self isHorizontal]]];
116 if (recurse) {
117 for (RBSplitSubview* sub in [self subviews]){
118 [[sub asSplitView] saveState:YES];
119 }
120 }
121 return YES;
122 }
123 return NO;
124}

◆ setAutosaveName:recursively:

- (void) setAutosaveName: (NSString*) aString
recursively: (BOOL) flag 

Definition at line 25 of file RBSplitView.m.

87 :(NSString*)aString recursively:(BOOL)flag {
88 BOOL clear;
89 if ((clear = ![aString length])) {
90 aString = @"";
91 }
92 [RBSplitView removeStateUsingName:autosaveName];
93 [autosaveName autorelease];
94 autosaveName = [aString retain];
95 if (flag) {
96 NSArray* subviews = [self subviews];
97 NSUInteger subcount = [subviews count];
98 NSUInteger i;
99 for (i=0;i<subcount;i++) {
100 RBSplitView* sv = [[subviews objectAtIndex:i] asSplitView];
101 if (sv) {
102 NSString* subst = clear?@"":[aString stringByAppendingFormat:@"[%ld]",i];
103 [sv setAutosaveName:subst recursively:YES];
104 }
105 }
106 }
107}
void removeStateUsingName:(NSString *name)
Definition RBSplitView.m:63
void setAutosaveName:recursively:(NSString *aString,[recursively] BOOL flag)
Definition RBSplitView.m:87

◆ setBackground:

- (void) setBackground: (NSColor*) color

Definition at line 25 of file RBSplitView.m.

374 :(NSColor*)color {
375 if (![self couplingSplitView]) {
376 [background autorelease];
377 background = color?([color alphaComponent]>0.0?[color retain]:nil):nil;
378 [self setNeedsDisplay:YES];
379 }
380}
RBSplitView * couplingSplitView()

◆ setCoupled:

- (void) setCoupled: (BOOL) flag
implementation

Reimplemented from RBSplitSubview.

Definition at line 25 of file RBSplitView.m.

290 :(BOOL)flag {
291 if (flag!=isCoupled) {
292 isCoupled = flag;
293// If we've just been uncoupled and there's no divider image, we copy it from the containing view.
294 if (!isCoupled&&!divider) {
295 [self setDivider:[[self splitView] divider]];
296 }
297 [self setMustAdjust];
298 }
299}

◆ setCursor:toCursor:

+ (void) setCursor: (RBSVCursorType) type
toCursor: (NSCursor*) cursor 

Definition at line 25 of file RBSplitView.m.

55 :(RBSVCursorType)type toCursor:(NSCursor*)cursor {
56 if ((type>=0)&&(type<RBSVCursorTypeCount)) {
57 [cursors[type] release];
58 cursors[type] = [cursor retain];
59 }
60}

◆ setDelegate:

- (void) setDelegate: (id) anObject

Definition at line 25 of file RBSplitView.m.

445 :(id)anObject {
446 delegate = anObject;
447}

◆ setDivider:

- (void) setDivider: (NSImage*) image

Definition at line 25 of file RBSplitView.m.

458 :(NSImage*)image {
459 if (![self couplingSplitView]) {
460 [divider autorelease];
461 if ([image isFlipped]) {
462// If the image is flipped, we just retain it.
463 divider = [image retain];
464 } else {
465// if the image isn't flipped, we copy the image instead of retaining it, and flip the copy.
466 divider = [image copy];
467 [divider setFlipped:YES];
468 }
469// We set the thickness to 0.0 so the image dimension will prevail.
470 [self setDividerThickness:0.0];
471 [self setMustAdjust];
472 }
473}

◆ setDividerThickness:

- (void) setDividerThickness: (CGFloat) thickness

Definition at line 25 of file RBSplitView.m.

490 :(CGFloat)thickness {
491 CGFloat t = fMAX(0.0,floor(thickness));
492 if ((NSInteger)dividerThickness!=(NSInteger)t) {
494 [self setMustAdjust];
495 }
496}
CGFloat dividerThickness
Definition RBSplitView.h:30

◆ setFrameSize:

- (void) setFrameSize: (NSSize) size
implementation

Definition at line 25 of file RBSplitView.m.

559 :(NSSize)size {
560// NSLog(@"setFrameSize of %@ to %@",self,NSStringFromSize(size));
561 NSSize oldsize = [self frame].size;
562 [super setFrameSize:size];
563 [self setMustAdjust];
564 if ([delegate respondsToSelector:@selector(splitView:wasResizedFrom:to:)]) {
565 BOOL ishor = [self isHorizontal];
566 CGFloat olddim = DIM(oldsize);
567 CGFloat newdim = DIM(size);
568// The delegate is not called if the dimension hasn't changed.
569 if (((NSInteger)newdim!=(NSInteger)olddim)) {
570 [delegate splitView:self wasResizedFrom:olddim to:newdim];
571 }
572 }
573// We adjust the subviews only if the delegate didn't.
574 if (mustAdjust&&!isAdjusting) {
575 [self adjustSubviews];
576 }
577}

◆ setHorizontal:

- (void) setHorizontal: (BOOL) flag

Definition at line 25 of file RBSplitView.m.

403 :(BOOL)flag {
404 if (![self splitView]&&(isHorizontal!=flag)) {
405 BOOL ishor = isHorizontal = flag;
406 NSSize size = divider?[divider size]:NSZeroSize;
407 [self setDividerThickness:DIM(size)];
408 [self setMustAdjust];
409 }
410}

◆ setMustAdjust

- (void) setMustAdjust

Definition at line 25 of file RBSplitView.m.

333 {
334 mustAdjust = YES;
335 [self setNeedsDisplay:YES];
336}

◆ setStateFromString:

- (BOOL) setStateFromString: (NSString*) aString

Definition at line 25 of file RBSplitView.m.

210 :(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)) {
217 NSInteger i;
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;
225 if (negative) {
226 size = -size;
227 }
228 double fract = size;
229 size = floor(size);
230 fract -= size;
231 DIM(frame.size) = size;
232 RBSplitSubview* sub = [subviews objectAtIndex:i];
233 [sub RB___setFrame:frame withFraction:fract notify:NO];
234 if (negative) {
235 [sub RB___collapse];
236 }
237 [sub RB___setHidden:hidden];
238 }
239 [self setMustAdjust];
240 return YES;
241 }
242 }
243 return NO;
244}
CGFloat RB___collapse()
void RB___setHidden:(BOOL flag)
void RB___setFrame:withFraction:notify:(NSRect rect,[withFraction] double value,[notify] BOOL notify)

◆ setStatesFromArray:

- (BOOL) setStatesFromArray: (NSArray*) array

Definition at line 25 of file RBSplitView.m.

164 :(NSArray*)array {
165 NSArray* subviews = [self subviews];
166 NSUInteger count = [array count];
167 if (count==([subviews count]+1)) {
168 NSString* me = [array objectAtIndex:0];
169 if ([me isKindOfClass:[NSString class]]) {
170 if ([self setStateFromString:me]) {
171 NSUInteger i;
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]) {
177 return NO;
178 }
179 } else {
180 return NO;
181 }
182 }
183 return YES;
184 }
185 }
186 }
187 return NO;
188}

◆ setVertical:

- (void) setVertical: (BOOL) flag

Definition at line 25 of file RBSplitView.m.

416 :(BOOL)flag {
417 [self setHorizontal:!flag];
418}

◆ shouldDelayWindowOrderingForEvent:

- (BOOL) shouldDelayWindowOrderingForEvent: (NSEvent*) theEvent
implementation

Definition at line 25 of file RBSplitView.m.

359 :(NSEvent*)theEvent {
360 return ([theEvent modifierFlags]&NSCommandKeyMask)!=0;
361}

◆ stringWithSavedState

- (NSString *) stringWithSavedState

Definition at line 25 of file RBSplitView.m.

193 {
194 NSArray* subviews = [self subviews];
195 NSMutableString* result = [NSMutableString stringWithFormat:@"%ld",[subviews count]];
196 for (RBSplitSubview* sub in [self subviews]){
197 double size = [sub dimension];
198 if ([sub isCollapsed]) {
199 size = -size;
200 } else {
201 size += +[sub RB___fraction];
202 }
203 [result appendFormat:[sub isHidden]?@" %gH":@" %g",size];
204 }
205 return result;
206}

◆ subviewAtPosition:

- (RBSplitSubview *) subviewAtPosition: (NSUInteger) position

Definition at line 25 of file RBSplitView.m.

431 :(NSUInteger)position {
432 NSArray* subviews = [super subviews];
433 NSUInteger subcount = [subviews count];
434 if (position<subcount) {
435 return [subviews objectAtIndex:position];
436 }
437 return nil;
438}

◆ subviewWithIdentifier:

- (RBSplitSubview *) subviewWithIdentifier: (NSString*) anIdentifier

Definition at line 25 of file RBSplitView.m.

421 :(NSString*)anIdentifier {
422 for (RBSplitSubview* sub in [self subviews]){
423 if ([anIdentifier isEqualToString:[sub identifier]]) {
424 return sub;
425 }
426 }
427 return nil;
428}
NSString * identifier

◆ viewDidMoveToSuperview

- (void) viewDidMoveToSuperview
implementation

Definition at line 25 of file RBSplitView.m.

537 {
538 [super viewDidMoveToSuperview];
539 NSScrollView* scrollv = [self enclosingScrollView];
540 isInScrollView = scrollv?[scrollv documentView]==self:NO;
541}

◆ willRemoveSubview:

- (void) willRemoveSubview: (NSView*) subview
implementation

Definition at line 25 of file RBSplitView.m.

544 :(NSView*)subview {
545 if ([subview respondsToSelector:@selector(RB___stopAnimation)]) {
546 [(RBSplitSubview*)subview RB___stopAnimation];
547 }
548 [super willRemoveSubview:subview];
549 [self setMustAdjust];
550}

Member Data Documentation

◆ autosaveName

- (NSString *) autosaveName
protected

Definition at line 26 of file RBSplitView.h.

◆ background

- (NSColor *) background
protected

Definition at line 27 of file RBSplitView.h.

◆ canSaveState

- (BOOL) canSaveState
protected

Definition at line 34 of file RBSplitView.h.

◆ delegate

- (id) delegate
protected

Definition at line 25 of file RBSplitView.h.

◆ divider

- (NSImage *) divider
protected

Definition at line 28 of file RBSplitView.h.

◆ dividers

- (NSRect*) dividers
protected

Definition at line 29 of file RBSplitView.h.

◆ dividerThickness

- (CGFloat) dividerThickness
protected

Definition at line 30 of file RBSplitView.h.

◆ isAdjusting

- (BOOL) isAdjusting
protected

Definition at line 36 of file RBSplitView.h.

◆ isCoupled

- (BOOL) isCoupled
protected

Definition at line 35 of file RBSplitView.h.

◆ isDragging

- (BOOL) isDragging
protected

Definition at line 37 of file RBSplitView.h.

◆ isHorizontal

- (BOOL) isHorizontal
protected

Definition at line 33 of file RBSplitView.h.

◆ isInScrollView

- (BOOL) isInScrollView
protected

Definition at line 38 of file RBSplitView.h.

◆ mustAdjust

- (BOOL) mustAdjust
protected

Definition at line 31 of file RBSplitView.h.

◆ mustClearFractions

- (BOOL) mustClearFractions
protected

Definition at line 32 of file RBSplitView.h.


The documentation for this class was generated from the following files: