Permalink
Browse files

initial commit of split view

  • Loading branch information...
1 parent 13d1236 commit 9d7c11cf1caa38331c6fa590bbc2afade53d228a @jwilling committed Jul 27, 2012
View
25 JWSplitView/JWSplitView.h
@@ -0,0 +1,25 @@
+#import <Cocoa/Cocoa.h>
+
+enum {
+ JWSplitViewDividerStyleThin = 1,
+};
+typedef NSInteger JWSplitViewDividerStyle;
+
+
+@interface JWSplitView : NSView
+
+//- (void)setView:(NSView *)view forSplitView:(NSUInteger)splitView;
+- (void)addSplitView:(NSView *)view;
+
+@property (nonatomic, readwrite) CGFloat dividerThickness;
+//@property (nonatomic, copy) TUIViewDrawRect dividerDrawRectBlock;
+
+@property (nonatomic, getter = isHorizontal) BOOL horizontal;
+
+@property (nonatomic, copy) NSString *autosaveName;
+
+//- (NSLayoutPriority)holdingPriorityForSubviewAtIndex:(NSInteger)subviewIndex;
+//- (void)setHoldingPriority:(NSLayoutPriority)priority forSubviewAtIndex:(NSInteger)subviewIndex;
+
+
+@end
View
288 JWSplitView/JWSplitView.m
@@ -0,0 +1,288 @@
+#import "JWSplitView.h"
+#import <objc/runtime.h>
+
+typedef void (^JWSplitViewDraggingHandler)(NSEvent *dragEvent, NSView *divider, id sender);
+
+@interface JWSplitView()
+@property (nonatomic, strong) NSMutableArray *splitViews;
+@property (nonatomic, strong) NSMutableArray *dividers;
+@property (nonatomic, strong) NSMutableArray *dividerConstraints;
+@property (nonatomic, strong) NSArray *restoredConstants;
+@property (nonatomic, copy) JWSplitViewDraggingHandler dragHandler;
+@end
+
+@interface JWDividerView : NSView
+@property (nonatomic, strong) NSTrackingArea *trackingArea;
+@property (nonatomic, assign) BOOL horizontal;
+@end
+
+@interface NSView (LayoutExtensions)
+- (void)setPriority:(NSLayoutPriority)priority;
+- (NSLayoutPriority)priorityOrDefault:(NSLayoutPriority)defaultPriority;
+@property (nonatomic, assign) NSLayoutConstraint *constraint;
+@end
+
+@interface NSObject (DragEvents)
+- (void)mouseDraggedOnDivider:(NSView *)divider withEvent:(NSEvent *)event;
+- (void)mouseDownOnDivider:(NSView *)divider withEvent:(NSEvent *)event;
+- (void)mouseUpOnDivider:(NSView *)divider withEvent:(NSEvent *)event;
+@end
+
+@implementation JWSplitView
+
+- (id)initWithFrame:(CGRect)frame {
+ if ((self = [super initWithFrame:frame])) {
+
+ //self.backgroundColor = [NSColor grayColor];
+ self.splitViews = [NSMutableArray array];
+ self.dividers = [NSMutableArray array];
+ self.dividerConstraints = [NSMutableArray array];
+ self.dividerThickness = 5.f;
+ self.horizontal = YES;
+
+ [self addDivider];
+ }
+ return self;
+}
+
+- (void)setHorizontal:(BOOL)horizontal {
+ _horizontal = horizontal;
+ for (JWDividerView *view in self.splitViews) {
+ view.horizontal = horizontal;
+ }
+}
+
+- (void)addSplitView:(NSView *)view {
+ [view setTranslatesAutoresizingMaskIntoConstraints:NO];
+ [self.splitViews addObject:view];
+ [self addSubview:view];
+
+
+ [self removeConstraints:self.constraints];
+
+ [self addDivider];
+ [self resetLayout];
+}
+
+- (void)addDivider {
+ JWDividerView *divider = [[JWDividerView alloc] initWithFrame:CGRectZero];
+ [divider setTranslatesAutoresizingMaskIntoConstraints:NO];
+ divider.horizontal = self.horizontal;
+ [self.dividers addObject:divider];
+ [self addSubview:divider];
+
+ [self resetDividerLayout];
+}
+
+
+#pragma mark -
+#pragma mark Constraint setups
+
+- (void)resetDividerLayout {
+ [self.dividerConstraints removeAllObjects];
+
+ NSMutableArray *standardConstraints = [NSMutableArray array];
+
+ [self.dividers enumerateObjectsUsingBlock:^(id div, NSUInteger idx, BOOL *stop) {
+ BOOL last = ([div isEqual:self.dividers.lastObject]);
+ BOOL first = ([div isEqual:self.dividers[0]]);
+ BOOL h = self.horizontal;
+
+ NSDictionary *views = NSDictionaryOfVariableBindings(div);
+ NSDictionary *metrics = @{ @"size" : @(self.dividerThickness), @"negSize" : @(-self.dividerThickness) };
+
+ if (first) {
+ [standardConstraints addObjectsFromArray:
+ [NSLayoutConstraint constraintsWithVisualFormat:h ? @"H:|-(==negSize)-[div]" : @"V:|-(==negSize)-[div]"
+ options:0 metrics:metrics views:views]];
+ } else if (last) {
+ [standardConstraints addObjectsFromArray:
+ [NSLayoutConstraint constraintsWithVisualFormat:h ? @"H:[div]-(==negSize)-|" : @"V:[div]-(==negSize)-|"
+ options:0 metrics:metrics views:views]];
+ } else {
+
+ CGFloat dividedPosition = ceilf( ((self.dividerConstraints.count + 1.f) / self.splitViews.count) * (h ? self.frame.size.width : self.frame.size.height));
+
+ NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:div attribute:(h ? NSLayoutAttributeLeft : NSLayoutAttributeTop)
+ relatedBy:NSLayoutRelationEqual
+ toItem:self attribute:(h ? NSLayoutAttributeLeft : NSLayoutAttributeTop)
+ multiplier:1.0 constant:dividedPosition];
+ [constraint setPriority:490];
+ [self.dividerConstraints addObject:constraint];
+ [div setConstraint:constraint]; // divider weakly stores a reference to this constraint so we can modify it later
+
+ if ([self shouldRestorePositions]) {
+ constraint.constant = [self.restoredConstants[[self.dividerConstraints indexOfObject:constraint]] floatValue];
+ }
+ }
+
+ // set the divider thickness, and stretch to fill the width or height
+ NSArray *stretch = [NSLayoutConstraint constraintsWithVisualFormat:h ? @"V:|[div(>=0)]|" : @"H:|[div(>=0)]|"
+ options:0 metrics:metrics views:views];
+ NSArray *size = [NSLayoutConstraint constraintsWithVisualFormat:h ? @"H:[div(==size)]" : @"V:[div(==size)]"
+ options:0 metrics:metrics views:views];
+ [standardConstraints addObjectsFromArray:stretch];
+ [standardConstraints addObjectsFromArray:size];
+ }];
+ [self addConstraints:self.dividerConstraints];
+ [self addConstraints:standardConstraints];
+}
+
+- (void)resetLayout {
+ NSMutableDictionary *views = [@{} mutableCopy];
+ NSMutableArray *constraints = [@[] mutableCopy];
+ BOOL h = self.horizontal;
+
+ [self.splitViews enumerateObjectsUsingBlock:^(NSView *currentView, NSUInteger idx, BOOL *stop) {
+ views[@"current"] = currentView;
+ views[@"prevDiv"] = self.dividers[idx];
+ views[@"nextDiv"] = self.dividers[idx + 1];
+
+ [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:h ? @"H:[prevDiv][current(>=0@600)][nextDiv]" : @"V:[prevDiv][current(>=0)][nextDiv]"
+ options:0 metrics:0 views:views]];
+ [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:h ? @"V:|[current]|" : @"H:|[current]|"
+ options:0 metrics:0 views:views]];
+ }];
+ [self addConstraints:constraints];
+}
+
+- (void)mouseDownOnDivider:(NSView *)divider withEvent:(NSEvent *)downEvent {
+ NSPoint mouseDownPoint = [downEvent locationInWindow];
+
+ BOOL horizontal = self.horizontal;
+ CGFloat originalConstant = divider.constraint.constant;
+
+ self.dragHandler = ^(NSEvent *event, NSView *currentDivider, id sender) {
+ CGPoint mouseCurrentPoint = [event locationInWindow];
+
+ CGFloat deltaY = ceil(mouseCurrentPoint.y - mouseDownPoint.y);
+ CGFloat deltaX = ceil(mouseDownPoint.x - mouseCurrentPoint.x);
+
+ CGFloat newConstant = originalConstant - (horizontal ? deltaX : deltaY);
+ currentDivider.constraint.constant = newConstant;
+ };
+}
+
+- (void)mouseDraggedOnDivider:(NSView *)divider withEvent:(NSEvent *)event {
+ self.dragHandler(event, divider, self);
+}
+
+- (void)mouseUpOnDivider:(NSView *)divider withEvent:(NSEvent *)event {
+ self.dragHandler = nil;
+
+ [self savePositions];
+}
+
+
+#pragma mark -
+#pragma mark Saving / restoring state
+
+- (BOOL)shouldRestorePositions {
+ return (self.autosaveName != nil && self.restoredConstants.count > 0);
+}
+
+- (void)setAutosaveName:(NSString *)autosaveName {
+ _autosaveName = [autosaveName copy];
+ [self restorePositionsWithAutosaveName:autosaveName];
+}
+
+- (void)restorePositionsWithAutosaveName:(NSString *)autosave {
+ NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:autosave];
+ if (!data)
+ return;
+
+ self.restoredConstants = [NSKeyedUnarchiver unarchiveObjectWithData:data];
+ [self resetDividerLayout];
+}
+
+- (void)savePositions {
+ if (!_autosaveName)
+ return;
+
+ NSMutableArray *constants = [NSMutableArray arrayWithCapacity:self.dividerConstraints.count];
+ for (NSLayoutConstraint *constraint in self.dividerConstraints) {
+ [constants addObject:@(constraint.constant)];
+ }
+
+ NSData *data = [NSKeyedArchiver archivedDataWithRootObject:constants];
+
+ [[NSUserDefaults standardUserDefaults] setObject:data forKey:self.autosaveName];
+}
+
+@end
+
+
+
+@implementation JWDividerView
+
+- (void)mouseDown:(NSEvent *)theEvent {
+ [self.superview mouseDownOnDivider:self withEvent:theEvent];
+}
+
+- (void)mouseDragged:(NSEvent *)theEvent {
+ [self.superview mouseDraggedOnDivider:self withEvent:theEvent];
+}
+
+- (void)mouseUp:(NSEvent *)theEvent {
+ [self.superview mouseUpOnDivider:self withEvent:theEvent];
+}
+
+- (void)mouseEntered:(NSEvent *)event {
+ if (self.horizontal) {
+ [[NSCursor resizeLeftRightCursor] push];
+ } else {
+ [[NSCursor resizeUpDownCursor] push];
+ }
+}
+
+- (void)mouseExited:(NSEvent *)event {
+ [[NSCursor currentCursor] pop];
+}
+
+- (void)updateTrackingAreas {
+ if (_trackingArea) {
+ [self removeTrackingArea:self.trackingArea];
+ self.trackingArea = nil;
+
+ }
+
+ NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:[self bounds]
+ options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveInActiveApp)
+ owner:self userInfo:nil];
+ [self addTrackingArea:area];
+}
+
+- (void)drawRect:(NSRect)dirtyRect {
+ [[NSColor blackColor] set];
+ NSRectFill(dirtyRect);
+}
+
+@end
+
+@implementation NSView (LayoutExtensions)
+
+static char NSViewLayoutPriorityKey;
+static char NSViewLayoutConstraintKey;
+
+- (void)setPriority:(NSLayoutPriority)priority {
+ NSAssert(priority > NSLayoutPriorityDragThatCanResizeWindow, @"Split view layout priority cannot exceed NSLayoutPriorityDragThatCannotResizeWindow");
+ objc_setAssociatedObject(self, &NSViewLayoutPriorityKey, @(priority), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (NSLayoutPriority)priorityOrDefault:(NSLayoutPriority)defaultPriority {
+ NSNumber *obj = objc_getAssociatedObject(self, &NSViewLayoutPriorityKey);
+ if (!obj && obj.floatValue < 1) {
+ return defaultPriority;
+ }
+ return obj.floatValue;
+}
+
+- (void)setConstraint:(NSLayoutConstraint *)constraint {
+ objc_setAssociatedObject(self, &NSViewLayoutConstraintKey, constraint, OBJC_ASSOCIATION_ASSIGN);
+}
+
+- (NSLayoutConstraint *)constraint {
+ return objc_getAssociatedObject(self, &NSViewLayoutConstraintKey);
+}
+
+@end
View
313 JWSplitViewDemo.xcodeproj/project.pbxproj
@@ -0,0 +1,313 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ AB90E11A15C07CAB00382AEF /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB90E11915C07CAB00382AEF /* Cocoa.framework */; };
+ AB90E12415C07CAB00382AEF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AB90E12215C07CAB00382AEF /* InfoPlist.strings */; };
+ AB90E12615C07CAB00382AEF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = AB90E12515C07CAB00382AEF /* main.m */; };
+ AB90E12A15C07CAB00382AEF /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = AB90E12815C07CAB00382AEF /* Credits.rtf */; };
+ AB90E12D15C07CAB00382AEF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AB90E12C15C07CAB00382AEF /* AppDelegate.m */; };
+ AB90E13015C07CAB00382AEF /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB90E12E15C07CAB00382AEF /* MainMenu.xib */; };
+ AB90E13C15C07CE900382AEF /* JWSplitView.m in Sources */ = {isa = PBXBuildFile; fileRef = AB90E13B15C07CE900382AEF /* JWSplitView.m */; };
+ AB90E14015C0868A00382AEF /* ColoredView.m in Sources */ = {isa = PBXBuildFile; fileRef = AB90E13F15C0868A00382AEF /* ColoredView.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ AB90E11515C07CAB00382AEF /* JWSplitViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JWSplitViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ AB90E11915C07CAB00382AEF /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+ AB90E11C15C07CAB00382AEF /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
+ AB90E11D15C07CAB00382AEF /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
+ AB90E11E15C07CAB00382AEF /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+ AB90E12115C07CAB00382AEF /* JWSplitViewDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "JWSplitViewDemo-Info.plist"; sourceTree = "<group>"; };
+ AB90E12315C07CAB00382AEF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+ AB90E12515C07CAB00382AEF /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ AB90E12715C07CAB00382AEF /* JWSplitViewDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JWSplitViewDemo-Prefix.pch"; sourceTree = "<group>"; };
+ AB90E12915C07CAB00382AEF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
+ AB90E12B15C07CAB00382AEF /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ AB90E12C15C07CAB00382AEF /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ AB90E12F15C07CAB00382AEF /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = "<group>"; };
+ AB90E13A15C07CE900382AEF /* JWSplitView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JWSplitView.h; path = JWSplitView/JWSplitView.h; sourceTree = SOURCE_ROOT; };
+ AB90E13B15C07CE900382AEF /* JWSplitView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JWSplitView.m; path = JWSplitView/JWSplitView.m; sourceTree = SOURCE_ROOT; };
+ AB90E13E15C0868A00382AEF /* ColoredView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColoredView.h; sourceTree = "<group>"; };
+ AB90E13F15C0868A00382AEF /* ColoredView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ColoredView.m; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ AB90E11215C07CAB00382AEF /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AB90E11A15C07CAB00382AEF /* Cocoa.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ AB90E10A15C07CAB00382AEF = {
+ isa = PBXGroup;
+ children = (
+ AB90E11F15C07CAB00382AEF /* JWSplitViewDemo */,
+ AB90E11815C07CAB00382AEF /* Frameworks */,
+ AB90E11615C07CAB00382AEF /* Products */,
+ );
+ sourceTree = "<group>";
+ };
+ AB90E11615C07CAB00382AEF /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ AB90E11515C07CAB00382AEF /* JWSplitViewDemo.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ AB90E11815C07CAB00382AEF /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ AB90E11915C07CAB00382AEF /* Cocoa.framework */,
+ AB90E11B15C07CAB00382AEF /* Other Frameworks */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+ AB90E11B15C07CAB00382AEF /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ AB90E11C15C07CAB00382AEF /* AppKit.framework */,
+ AB90E11D15C07CAB00382AEF /* CoreData.framework */,
+ AB90E11E15C07CAB00382AEF /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "<group>";
+ };
+ AB90E11F15C07CAB00382AEF /* JWSplitViewDemo */ = {
+ isa = PBXGroup;
+ children = (
+ AB90E12B15C07CAB00382AEF /* AppDelegate.h */,
+ AB90E12C15C07CAB00382AEF /* AppDelegate.m */,
+ AB90E13E15C0868A00382AEF /* ColoredView.h */,
+ AB90E13F15C0868A00382AEF /* ColoredView.m */,
+ AB90E12E15C07CAB00382AEF /* MainMenu.xib */,
+ AB90E13A15C07CE900382AEF /* JWSplitView.h */,
+ AB90E13B15C07CE900382AEF /* JWSplitView.m */,
+ AB90E12015C07CAB00382AEF /* Supporting Files */,
+ );
+ path = JWSplitViewDemo;
+ sourceTree = "<group>";
+ };
+ AB90E12015C07CAB00382AEF /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ AB90E12115C07CAB00382AEF /* JWSplitViewDemo-Info.plist */,
+ AB90E12215C07CAB00382AEF /* InfoPlist.strings */,
+ AB90E12515C07CAB00382AEF /* main.m */,
+ AB90E12715C07CAB00382AEF /* JWSplitViewDemo-Prefix.pch */,
+ AB90E12815C07CAB00382AEF /* Credits.rtf */,
+ );
+ name = "Supporting Files";
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ AB90E11415C07CAB00382AEF /* JWSplitViewDemo */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = AB90E13315C07CAB00382AEF /* Build configuration list for PBXNativeTarget "JWSplitViewDemo" */;
+ buildPhases = (
+ AB90E11115C07CAB00382AEF /* Sources */,
+ AB90E11215C07CAB00382AEF /* Frameworks */,
+ AB90E11315C07CAB00382AEF /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = JWSplitViewDemo;
+ productName = JWSplitViewDemo;
+ productReference = AB90E11515C07CAB00382AEF /* JWSplitViewDemo.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ AB90E10C15C07CAB00382AEF /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0440;
+ ORGANIZATIONNAME = "Jonathan Willing";
+ };
+ buildConfigurationList = AB90E10F15C07CAB00382AEF /* Build configuration list for PBXProject "JWSplitViewDemo" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = AB90E10A15C07CAB00382AEF;
+ productRefGroup = AB90E11615C07CAB00382AEF /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ AB90E11415C07CAB00382AEF /* JWSplitViewDemo */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ AB90E11315C07CAB00382AEF /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AB90E12415C07CAB00382AEF /* InfoPlist.strings in Resources */,
+ AB90E12A15C07CAB00382AEF /* Credits.rtf in Resources */,
+ AB90E13015C07CAB00382AEF /* MainMenu.xib in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ AB90E11115C07CAB00382AEF /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ AB90E12615C07CAB00382AEF /* main.m in Sources */,
+ AB90E12D15C07CAB00382AEF /* AppDelegate.m in Sources */,
+ AB90E13C15C07CE900382AEF /* JWSplitView.m in Sources */,
+ AB90E14015C0868A00382AEF /* ColoredView.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ AB90E12215C07CAB00382AEF /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ AB90E12315C07CAB00382AEF /* en */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "<group>";
+ };
+ AB90E12815C07CAB00382AEF /* Credits.rtf */ = {
+ isa = PBXVariantGroup;
+ children = (
+ AB90E12915C07CAB00382AEF /* en */,
+ );
+ name = Credits.rtf;
+ sourceTree = "<group>";
+ };
+ AB90E12E15C07CAB00382AEF /* MainMenu.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ AB90E12F15C07CAB00382AEF /* en */,
+ );
+ name = MainMenu.xib;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ AB90E13115C07CAB00382AEF /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.8;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ AB90E13215C07CAB00382AEF /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.8;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+ AB90E13415C07CAB00382AEF /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "JWSplitViewDemo/JWSplitViewDemo-Prefix.pch";
+ INFOPLIST_FILE = "JWSplitViewDemo/JWSplitViewDemo-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Debug;
+ };
+ AB90E13515C07CAB00382AEF /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = "JWSplitViewDemo/JWSplitViewDemo-Prefix.pch";
+ INFOPLIST_FILE = "JWSplitViewDemo/JWSplitViewDemo-Info.plist";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ WRAPPER_EXTENSION = app;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ AB90E10F15C07CAB00382AEF /* Build configuration list for PBXProject "JWSplitViewDemo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ AB90E13115C07CAB00382AEF /* Debug */,
+ AB90E13215C07CAB00382AEF /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ AB90E13315C07CAB00382AEF /* Build configuration list for PBXNativeTarget "JWSplitViewDemo" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ AB90E13415C07CAB00382AEF /* Debug */,
+ AB90E13515C07CAB00382AEF /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = AB90E10C15C07CAB00382AEF /* Project object */;
+}
View
7 JWSplitViewDemo/AppDelegate.h
@@ -0,0 +1,7 @@
+#import <Cocoa/Cocoa.h>
+
+@interface AppDelegate : NSObject <NSApplicationDelegate>
+
+@property (assign) IBOutlet NSWindow *window;
+
+@end
View
26 JWSplitViewDemo/AppDelegate.m
@@ -0,0 +1,26 @@
+#import "AppDelegate.h"
+#import "JWSplitView.h"
+#import "ColoredView.h"
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ CGRect b = [self.window.contentView bounds];
+
+ JWSplitView *splitView = [[JWSplitView alloc] initWithFrame:b];
+ [self.window.contentView addSubview:splitView];
+ [splitView setTranslatesAutoresizingMaskIntoConstraints:YES];
+ [splitView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
+ splitView.horizontal = YES;
+ splitView.autosaveName = @"TestSplitView";
+
+ ColoredView *green = [[ColoredView alloc] initWithFrame:CGRectZero color:[NSColor greenColor]];
+ ColoredView *red = [[ColoredView alloc] initWithFrame:CGRectZero color:[NSColor redColor]];
+ ColoredView *blue = [[ColoredView alloc] initWithFrame:CGRectZero color:[NSColor blueColor]];
+
+ [splitView addSplitView:green];
+ [splitView addSplitView:red];
+ [splitView addSplitView:blue];
+}
+
+@end
View
8 JWSplitViewDemo/ColoredView.h
@@ -0,0 +1,8 @@
+#import <Cocoa/Cocoa.h>
+
+@interface ColoredView : NSView
+
+@property (nonatomic, strong) NSColor *color;
+- (id)initWithFrame:(NSRect)frameRect color:(NSColor *)color;
+
+@end
View
17 JWSplitViewDemo/ColoredView.m
@@ -0,0 +1,17 @@
+#import "ColoredView.h"
+
+@implementation ColoredView
+
+- (id)initWithFrame:(NSRect)frameRect color:(NSColor *)color {
+ self = [super initWithFrame:frameRect];
+ if (!self) return nil;
+ self.color = color;
+ return self;
+}
+
+- (void)drawRect:(NSRect)dirtyRect {
+ [self.color set];
+ NSRectFill(dirtyRect);
+}
+
+@end
View
34 JWSplitViewDemo/JWSplitViewDemo-Info.plist
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>en</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>AppJon.${PRODUCT_NAME:rfc1034identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>${MACOSX_DEPLOYMENT_TARGET}</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>Copyright © 2012 Jonathan Willing. All rights reserved.</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
View
7 JWSplitViewDemo/JWSplitViewDemo-Prefix.pch
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'JWSplitViewDemo' target in the 'JWSplitViewDemo' project
+//
+
+#ifdef __OBJC__
+ #import <Cocoa/Cocoa.h>
+#endif
View
29 JWSplitViewDemo/en.lproj/Credits.rtf
@@ -0,0 +1,29 @@
+{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\paperw9840\paperh8400
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\b\fs24 \cf0 Engineering:
+\b0 \
+ Some people\
+\
+
+\b Human Interface Design:
+\b0 \
+ Some other people\
+\
+
+\b Testing:
+\b0 \
+ Hopefully not nobody\
+\
+
+\b Documentation:
+\b0 \
+ Whoever\
+\
+
+\b With special thanks to:
+\b0 \
+ Mom\
+}
View
2 JWSplitViewDemo/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
View
3,174 JWSplitViewDemo/en.lproj/MainMenu.xib
3,174 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
14 JWSplitViewDemo/main.m
@@ -0,0 +1,14 @@
+//
+// main.m
+// JWSplitViewDemo
+//
+// Created by Jonathan Willing on 7/25/12.
+// Copyright (c) 2012 Jonathan Willing. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+
+int main(int argc, char *argv[])
+{
+ return NSApplicationMain(argc, (const char **)argv);
+}

0 comments on commit 9d7c11c

Please sign in to comment.