Repository: weAreYeah/WAYWindow Branch: master Commit: 7d25185d0a7f Files: 16 Total size: 104.4 KB Directory structure: gitextract_c5i6pguk/ ├── .gitignore ├── LICENSE ├── README.md ├── WAYWindow/ │ ├── WAYWindow.h │ └── WAYWindow.m ├── WAYWindowDemo/ │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj/ │ │ └── MainMenu.xib │ ├── Info.plist │ ├── WAYWindow.h │ ├── WAYWindow.m │ └── main.m └── WAYWindowDemo.xcodeproj/ ├── project.pbxproj └── project.xcworkspace/ ├── contents.xcworkspacedata └── xcshareddata/ ├── WAYWindow.xccheckout └── WAYWindowDemo.xccheckout ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ ##### # OS X temporary files that should never be committed # # c.f. http://www.westwind.com/reference/os-x/invisibles.html .DS_Store # c.f. http://www.westwind.com/reference/os-x/invisibles.html .Trashes # c.f. http://www.westwind.com/reference/os-x/invisibles.html *.swp # # *.lock - this is used and abused by many editors for many different things. # For the main ones I use (e.g. Eclipse), it should be excluded # from source-control, but YMMV. # (lock files are usually local-only file-synchronization on the local FS that should NOT go in git) # c.f. the "OPTIONAL" section at bottom though, for tool-specific variations! *.lock # # profile - REMOVED temporarily (on double-checking, I can't find it in OS X docs?) #profile #### # Xcode temporary files that should never be committed # # NB: NIB/XIB files still exist even on Storyboard projects, so we want this... *~.nib #### # Xcode build files - # # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" DerivedData/ # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" build/ ##### # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) # # This is complicated: # # SOMETIMES you need to put this file in version control. # Apple designed it poorly - if you use "custom executables", they are # saved in this file. # 99% of projects do NOT use those, so they do NOT want to version control this file. # ..but if you're in the 1%, comment out the line "*.pbxuser" # .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html *.pbxuser # .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html *.mode1v3 # .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html *.mode2v3 # .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file *.perspectivev3 # NB: also, whitelist the default ones, some projects need to use these !default.pbxuser !default.mode1v3 !default.mode2v3 !default.perspectivev3 #### # Xcode 4 - semi-personal settings # # # OPTION 1: --------------------------------- # throw away ALL personal settings (including custom schemes! # - unless they are "shared") # # NB: this is exclusive with OPTION 2 below xcuserdata # OPTION 2: --------------------------------- # get rid of ALL personal settings, but KEEP SOME OF THEM # - NB: you must manually uncomment the bits you want to keep # # NB: this *requires* git v1.8.2 or above; you may need to upgrade to latest OS X, # or manually install git over the top of the OS X version # NB: this is exclusive with OPTION 1 above # #xcuserdata/**/* # (requires option 2 above): Personal Schemes # #!xcuserdata/**/xcschemes/* #### # XCode 4 workspaces - more detailed # # Workspaces are important! They are a core feature of Xcode - don't exclude them :) # # Workspace layout is quite spammy. For reference: # # /(root)/ # /(project-name).xcodeproj/ # project.pbxproj # /project.xcworkspace/ # contents.xcworkspacedata # /xcuserdata/ # /(your name)/xcuserdatad/ # UserInterfaceState.xcuserstate # /xcsshareddata/ # /xcschemes/ # (shared scheme name).xcscheme # /xcuserdata/ # /(your name)/xcuserdatad/ # (private scheme).xcscheme # xcschememanagement.plist # # #### # Xcode 4 - Deprecated classes # # Allegedly, if you manually "deprecate" your classes, they get moved here. # # We're using source-control, so this is a "feature" that we do not want! *.moved-aside #### # OPTIONAL: Some well-known tools that people use side-by-side with Xcode / iOS development # # NB: I'd rather not include these here, but gitignore's design is weak and doesn't allow # modular gitignore: you have to put EVERYTHING in one file. # # COCOAPODS: # # c.f. http://guides.cocoapods.org/using/using-cocoapods.html#what-is-a-podfilelock # c.f. http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control # #!Podfile.lock # # RUBY: # # c.f. http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/ # #!Gemfile.lock # # IDEA: # #.idea # # TEXTMATE: # # -- UNVERIFIED: c.f. http://stackoverflow.com/a/50283/153422 # #tm_build_errors #### # UNKNOWN: recommended by others, but I can't discover what these files are # # Community suggestions (unverified, no evidence available - DISABLED by default) # # 1. Xcode 5 - VCS file # # "The data in this file not represent state of your project. # If you'll leave this file in git - you will have merge conflicts during # pull your cahnges to other's repo" # #*.xccheckout ================================================ FILE: LICENSE ================================================ WAYWindow by Raffael Hannemann (@raffael_me, @weAreYeah) Licensed under the BSD License http://www.opensource.org/licenses/bsd-license THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================ WAYWindow ========= ```NSWindow``` subclass that simplifies Yosemite exclusive features: - custom titlebar height - custom traffic lights margings - simplified NSAppearance switching - and more This NSWindow subclass provides an interface to enable OS X 10.10 Yosemite exclusive features conveniently. Next to customizing the look of the ```WAYWindow``` content view, you can also customize the title bar and standard window buttons ('traffic lights'). The public interface is generally similar to ```INAppStoreWindow``` to facilitate the migration. Whenever it makes sense, the properties of your ```WAYWindow``` instance in Interface Builder are inspectable. Tips: - Check out the WWDC '14 session "Adopting Advanced Features of the New UI of OS X Yosemite", which provides more details on how to make use of the new Yosemite APIs. - Also check out the new APIs in ```NSScrollView``` to make use of contentInsets, scrollInsets, and more. Many thanks to [@indragie](http://twitter.com/indragie) for his [INAppStoreWindow](https://github.com/indragiek/INAppStoreWindow/), which has been the inspiration for this class. Example ------- ![WAYWindow](WAYWindow%20Example.png) Usage ----- 1. Drag a new ```NSWindow``` instance to your XIB 2. Set the class of the instance to ```WAYWindow``` 3. Customize the properties via Interface Builder or programmatically **Note: You should probably consider using [WAYAppStoreWindow](https://github.com/weAreYeah/WAYAppStoreWindow/) instead of this class directly!** Interesting ----------- We are new, weAreYeah.com. Follow us on [@weAreYeah](http://twitter.com/weAreYeah) for upcoming goodies. License ------- Licensed under the BSD License THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: WAYWindow/WAYWindow.h ================================================ // // WAYWindow.m // WAYWindow // // Created by Raffael Hannemann on 15.11.14. // Copyright (c) 2014 Raffael Hannemann. All rights reserved. // Visit weAreYeah.com or follow @weareYeah for updates. // // Licensed under the BSD License // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // #import /** This NSWindow subclass provides an interface to enable OS X 10.10 Yosemite exclusive features conveniently. Next to customizing the look of the WAYWindow content view, you can also customize the title bar and standard window buttons (`traffic lights´). The public interface is generally similar to INAppStoreWindow to simplify the migration. Whenever it makes sense, the properties of your WAYWindow instance in Interface Builder are inspectable. Tips: - Check out the WWDC '14 session `Adopting Advanced Features of the New UI of OS X Yosemite´, which provides more details on how to make use of the new Yosemite APIs. - Also check out the new APIs in NSScrollView to make use of contentInsets, scrollInsets, and more. */ @interface WAYWindow : NSWindow /// Returns YES, if the class supports vibrant appearances. Can be used to determine if running on OS X 10.10+ + (BOOL) supportsVibrantAppearances; /// Defines the window's titlebar height. Defaut: OS X default value. @property (nonatomic) IBInspectable CGFloat titleBarHeight; //// Returns the titlebar view of the window, which you can add arbitrary subviews to. @property (strong,readonly) IBOutlet NSView *titleBarView; /// If set to YES, the standard window button will be vertically centered. Default: YES. @property (nonatomic) IBInspectable BOOL centerTrafficLightButtons; /// Defines the left margin of the standard window buttons. Defaut: OS X default value. @property (nonatomic) IBInspectable CGFloat trafficLightButtonsLeftMargin; /// Defines the top margin of the standard window buttons. Used if not centered. Defaut: OS X default value. @property (nonatomic) IBInspectable CGFloat trafficLightButtonsTopMargin; /// If set to YES, the title of the window will be hidden. Default: YES. @property (nonatomic) IBInspectable BOOL hidesTitle; /// Replaces the window's content view with an instance of NSVisualEffectView and applies the Vibrant Dark look. Transfers all subviews to the new content view. - (void) setContentViewAppearanceVibrantDark; /// Replaces the window's content view with an instance of NSVisualEffectView and applies the Vibrant Light look. Transfers all subviews to the new content view. - (void) setContentViewAppearanceVibrantLight; /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantDark - (void) setVibrantDarkAppearance; /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantLight - (void) setVibrantLightAppearance; /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantAqua - (void) setAquaAppearance; /// Replaces a view of the window subview hierarchy with the specified view, and transfers all current subviews to the new one. The frame of the new view will be set to the frame of the old view, if flag is YES. - (void) replaceSubview: (NSView *) aView withView: (NSView *) newView resizing: (BOOL) flag; /// Replaces a view of the window subview hierarchy with a new view of the specified NSView class, and transfers all current subviews to the new one. - (NSView *) replaceSubview: (NSView *) aView withViewOfClass: (Class) newViewClass; /// Returns YES if the window is currently in full-screen. - (BOOL) isFullScreen; @end ================================================ FILE: WAYWindow/WAYWindow.m ================================================ // // WAYWindow.m // WAYWindow // // Created by Raffael Hannemann on 15.11.14. // Copyright (c) 2014 Raffael Hannemann. All rights reserved. // Visit weAreYeah.com or follow @weareYeah for updates. // // Licensed under the BSD License // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // #import "WAYWindow.h" /** Convenience methods to make NSPointerArray act like a stack of selectors. It would be a subclass, but NSPointerArray is a class cluster and doesn't really like being subclassed. */ #pragma mark - WAY_SelectorStack @interface NSPointerArray (WAY_SelectorStack) - (instancetype)initWAYSelectorStack; - (BOOL)way_containsSelector:(SEL)aSelector; - (void)way_pushSelector:(SEL)aSelector; - (SEL)way_pop; @end @implementation NSPointerArray (WAY_SelectorStack) - (instancetype)initWAYSelectorStack { NSPointerFunctions *pointerFunctions = [NSPointerFunctions pointerFunctionsWithOptions:(NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality)]; self = [self initWithPointerFunctions:pointerFunctions]; return self; } - (BOOL)way_containsSelector:(SEL)aSelector { NSInteger count = self.count; for (NSInteger i=0; i @property (nonatomic, weak) id secondaryDelegate; @property (nonatomic, weak) id firstDelegate; @end /** Since the window needs to update itself at specific events, e.g., windowDidResize:;, we need to set the window as its own delegate. To allow proper window delegates as usual, we need to make use of a proxy object, which forwards all method invovations first to the WAYWindow instance, and then to the real delegate. */ #pragma mark - WAYWindowDelegateProxy @implementation WAYWindowDelegateProxy { NSPointerArray *_selectorStack; } - (instancetype)init { _selectorStack = [[NSPointerArray alloc] initWAYSelectorStack]; return self; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { NSMethodSignature *signature = [[self.firstDelegate class] instanceMethodSignatureForSelector:selector]; if (!signature) { signature = [[self.secondaryDelegate class] instanceMethodSignatureForSelector:selector]; if (!signature) { signature = [super methodSignatureForSelector:selector]; } } return signature; } - (BOOL)respondsToSelector:(SEL)aSelector { if (aSelector==@selector(windowDidResize:)) { return YES; } else if ([self.secondaryDelegate respondsToSelector:aSelector]) { return YES; } else { return NO; } } - (void)forwardInvocation:(NSInvocation *)anInvocation { SEL selector = anInvocation.selector; if ([_selectorStack way_containsSelector:selector]) { // We're already in the middle of forwarding this selector; stop the infinite recursion right here. return; } [_selectorStack way_pushSelector:selector]; { if ([self.firstDelegate respondsToSelector:selector]) { [anInvocation invokeWithTarget:self.firstDelegate]; } if ([self.secondaryDelegate respondsToSelector:selector]) { [anInvocation invokeWithTarget:self.secondaryDelegate]; } } [_selectorStack way_pop]; } - (BOOL)isKindOfClass:(Class)aClass { if (self.secondaryDelegate) { return [self.secondaryDelegate isKindOfClass:aClass]; } return NO; } @end #pragma mark - WAYWindow @interface WAYWindow () @property (strong) WAYWindowDelegateProxy* delegateProxy; @property (strong) NSArray* standardButtons; @property (strong) NSTitlebarAccessoryViewController *dummyTitlebarAccessoryViewController; @end static float kWAYWindowDefaultTrafficLightButtonsLeftMargin = 0; static float kWAYWindowDefaultTrafficLightButtonsTopMargin = 0; @implementation WAYWindow + (BOOL) supportsVibrantAppearances { return (NSClassFromString(@"NSVisualEffectView")!=nil); } + (float) defaultTitleBarHeight { NSRect frame = NSMakeRect(0, 0, 800, 600); NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask: NSTitledWindowMask]; return NSHeight(frame) - NSHeight(contentRect); } #pragma mark - NSWindow Overwritings - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag { if ((self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag])) { [self _setUp]; } return self; } - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)screen { if ((self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag screen:screen])) { [self _setUp]; } return self; } - (void) setDelegate:(id)delegate { [_delegateProxy setSecondaryDelegate:delegate]; [super setDelegate:nil]; [super setDelegate:_delegateProxy]; } - (id) delegate { return [_delegateProxy secondaryDelegate]; } - (void) setFrame:(NSRect)frameRect display:(BOOL)flag { [super setFrame:frameRect display:flag]; [self _setNeedsLayout]; } - (void) restoreStateWithCoder:(NSCoder *)coder { [super restoreStateWithCoder:coder]; [self _setNeedsLayout]; } - (void) orderFront:(id)sender { [super orderFront:sender]; [self _setNeedsLayout]; } #pragma mark - Public - (NSView *) titleBarView { return [_standardButtons[0] superview]; } - (void) setCenterTrafficLightButtons:(BOOL)centerTrafficLightButtons { _centerTrafficLightButtons = centerTrafficLightButtons; [self _setNeedsLayout]; } - (void) setTitleBarHeight:(CGFloat)titleBarHeight { titleBarHeight = MAX(titleBarHeight,[[self class] defaultTitleBarHeight]); CGFloat delta = titleBarHeight - _titleBarHeight; _titleBarHeight = titleBarHeight; if (_dummyTitlebarAccessoryViewController) { [self removeTitlebarAccessoryViewControllerAtIndex:0]; } NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 10, titleBarHeight-[WAYWindow defaultTitleBarHeight])]; _dummyTitlebarAccessoryViewController = [NSTitlebarAccessoryViewController new]; _dummyTitlebarAccessoryViewController.view = view; _dummyTitlebarAccessoryViewController.fullScreenMinHeight = titleBarHeight; [self addTitlebarAccessoryViewController:_dummyTitlebarAccessoryViewController]; NSRect frame = self.frame; frame.size.height += delta; frame.origin.y -= delta; [self _setNeedsLayout]; [self setFrame:frame display:NO]; // NO is important. } - (void) setHidesTitle:(BOOL)hidesTitle { _hidesTitle = hidesTitle; [self setTitleVisibility:hidesTitle ? NSWindowTitleHidden : NSWindowTitleVisible]; } - (void) setContentViewAppearanceVibrantDark { [self setContentViewAppearance:NSVisualEffectMaterialDark]; } - (void) setContentViewAppearanceVibrantLight { [self setContentViewAppearance:NSVisualEffectMaterialLight]; } - (void) setContentViewAppearance: (int) material { if (![WAYWindow supportsVibrantAppearances]) return; NSVisualEffectView *newContentView = (NSVisualEffectView *)[self replaceSubview:self.contentView withViewOfClass:[NSVisualEffectView class]]; [newContentView setMaterial:material]; [self setContentView:newContentView]; } - (void) setVibrantDarkAppearance { [self setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]]; } - (void) setVibrantLightAppearance { [self setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantLight]]; } - (void) setAquaAppearance { [self setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameAqua]]; } - (BOOL) isFullScreen { return (([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask); } - (void) replaceSubview: (NSView *) aView withView: (NSView *) newView resizing:(BOOL)flag { if (flag) { [newView setFrame:aView.frame]; } [newView setAutoresizesSubviews:aView.autoresizesSubviews]; [aView.subviews.copy enumerateObjectsUsingBlock:^(NSView *subview, NSUInteger idx, BOOL *stop) { NSRect frame = subview.frame; if (subview.constraints.count>0) { // Note: so far, constraint based contentView subviews are not supported yet NSLog(@"WARNING: [%@ %@] does not work yet with NSView instances, that use auto-layout.", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); } [subview removeFromSuperview]; [newView addSubview:subview]; [subview setFrame:frame]; }]; if (aView==self.contentView) { [self setContentView: newView]; } else { [aView.superview replaceSubview:aView with:newView]; } [self _setNeedsLayout]; } - (NSView *) replaceSubview:(NSView *)aView withViewOfClass:(Class)newViewClass { NSView *view = [[newViewClass alloc] initWithFrame:aView.frame]; [self replaceSubview:aView withView:view resizing:YES]; return view; } #pragma mark - Private - (void) _setUp { _delegateProxy = [[WAYWindowDelegateProxy alloc] init]; _delegateProxy.firstDelegate = self; super.delegate = _delegateProxy; _standardButtons = @[[self standardWindowButton:NSWindowCloseButton], [self standardWindowButton:NSWindowMiniaturizeButton], [self standardWindowButton:NSWindowZoomButton]]; _centerTrafficLightButtons = YES; NSButton *closeButton = [self standardWindowButton:NSWindowCloseButton]; kWAYWindowDefaultTrafficLightButtonsLeftMargin = NSMinX(closeButton.frame); kWAYWindowDefaultTrafficLightButtonsTopMargin = NSHeight(closeButton.superview.frame)-NSMaxY(closeButton.frame); self.styleMask |= NSFullSizeContentViewWindowMask; _trafficLightButtonsLeftMargin = kWAYWindowDefaultTrafficLightButtonsLeftMargin; _trafficLightButtonsTopMargin = kWAYWindowDefaultTrafficLightButtonsTopMargin; self.hidesTitle = YES; [super setDelegate:self]; [self _setNeedsLayout]; } - (void) _setNeedsLayout { [_standardButtons enumerateObjectsUsingBlock:^(NSButton *standardButton, NSUInteger idx, BOOL *stop) { NSRect frame = standardButton.frame; if (_centerTrafficLightButtons) frame.origin.y = NSHeight(standardButton.superview.frame)/2-NSHeight(standardButton.frame)/2; else frame.origin.y = NSHeight(standardButton.superview.frame)-NSHeight(standardButton.frame)-_trafficLightButtonsTopMargin; frame.origin.x = _trafficLightButtonsLeftMargin +idx*(NSWidth(frame) + 6); [standardButton setFrame:frame]; }]; } #pragma mark - NSWindow Delegate - (void) windowDidResize:(NSNotification *)notification { [self _setNeedsLayout]; } @end ================================================ FILE: WAYWindowDemo/AppDelegate.h ================================================ // // AppDelegate.h // WAYWindow // // Created by Raffael Hannemann on 15.11.14. // Copyright (c) 2014 We Are Yeah!. All rights reserved. // #import @interface AppDelegate : NSObject @end ================================================ FILE: WAYWindowDemo/AppDelegate.m ================================================ // // AppDelegate.m // WAYWindow // // Created by Raffael Hannemann on 15.11.14. // Copyright (c) 2014 We Are Yeah!. All rights reserved. // #import "AppDelegate.h" #import "WAYWindow.h" @interface AppDelegate () @property (weak) IBOutlet WAYWindow *window; @property (weak) IBOutlet NSView *titlebar; @end @implementation AppDelegate - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Insert code here to initialize your application [_window setVibrantDarkAppearance]; [_window setContentViewAppearanceVibrantDark]; [_window.titleBarView addSubview:_titlebar]; } - (void)applicationWillTerminate:(NSNotification *)aNotification { // Insert code here to tear down your application } @end ================================================ FILE: WAYWindowDemo/Base.lproj/MainMenu.xib ================================================ Default Left to Right Right to Left Default Left to Right Right to Left ================================================ FILE: WAYWindowDemo/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIconFile CFBundleIdentifier com.weareyeah.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) NSHumanReadableCopyright Copyright © 2014 We Are Yeah!. All rights reserved. NSMainNibFile MainMenu NSPrincipalClass NSApplication ================================================ FILE: WAYWindowDemo/WAYWindow.h ================================================ // // WAYWindow.m // WAYWindow // // Created by Raffael Hannemann on 15.11.14. // Copyright (c) 2014 Raffael Hannemann. All rights reserved. // Visit weAreYeah.com or follow @weareYeah for updates. // // Licensed under the BSD License // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // #import /** This NSWindow subclass provides an interface to enable OS X 10.10 Yosemite exclusive features conveniently. Next to customizing the look of the WAYWindow content view, you can also customize the title bar and standard window buttons (`traffic lights´). The public interface is generally similar to INAppStoreWindow to facilitate the migration. Whenever it makes sense, the properties of your WAYWindow instance in Interface Builder are inspectable. Tips: - Check out the WWDC '14 session `Adopting Advanced Features of the New UI of OS X Yosemite´, which provides more details on how to make use of the new Yosemite APIs. - Also check out the new APIs in NSScrollView to make use of contentInsets, scrollInsets, and more. */ @interface WAYWindow : NSWindow /// Returns YES, if the class supports vibrant appearances. Can be used to determine if running on OS X 10.10+ + (BOOL) supportsVibrantAppearances; /// Defines the window's titlebar height. @property (nonatomic) IBInspectable CGFloat titleBarHeight; //// Returns the titlebar view of the window, which you can add arbitrary subviews to. @property (strong,readonly) NSView *titleBarView; /// If set to YES, the standard window button will be vertically centered. @property (nonatomic) IBInspectable BOOL centerTrafficLightButtons; /// Defines the left margin of the standard window buttons @property (nonatomic) IBInspectable CGFloat trafficLightButtonsLeftMargin; /// If set to YES, the title of the window will be hidden. @property (nonatomic) IBInspectable BOOL hidesTitle; /// Replaces the window's content view with an instance of NSVisualEffectView and applies the Vibrant Dark look. Transfers all subviews to the new content view. - (void) setContentViewAppearanceVibrantDark; /// Replaces the window's content view with an instance of NSVisualEffectView and applies the Vibrant Light look. Transfers all subviews to the new content view. - (void) setContentViewAppearanceVibrantLight; /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantDark - (void) setVibrantDarkAppearance; /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantLight - (void) setVibrantLightAppearance; /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantAqua - (void) setAquaAppearance; /// Replaces a view of the window subview hierarchy with the specified view, and transfers all current subviews to the new one. The frame of the new view will be set to the frame of the old view, if flag is YES. - (void) replaceSubview: (NSView *) aView withView: (NSView *) newView resizing: (BOOL) flag; /// Replaces a view of the window subview hierarchy with a new view of the specified NSView class, and transfers all current subviews to the new one. - (NSView *) replaceSubview: (NSView *) aView withViewOfClass: (Class) newViewClass; /// Returns YES if the window is currently in full-screen. - (BOOL) isFullScreen; @end ================================================ FILE: WAYWindowDemo/WAYWindow.m ================================================ // // WAYWindow.m // WAYWindow // // Created by Raffael Hannemann on 15.11.14. // Copyright (c) 2014 Raffael Hannemann. All rights reserved. // Visit weAreYeah.com or follow @weareYeah for updates. // // Licensed under the BSD License // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // #import "WAYWindow.h" @interface WAYWindowDelegateProxy : NSProxy @property (nonatomic, assign) id secondaryDelegate; @end @implementation WAYWindowDelegateProxy @end @interface WAYWindow () @property (strong) WAYWindowDelegateProxy* delegateProxy; @property (strong) NSArray* standardButtons; @property (strong) NSTitlebarAccessoryViewController *dummyTitlebarAccessoryViewController; @end static float kWAYWindowDefaultTrafficLightButtonsLeftMargin = 0; static float kWAYWindowDefaultTrafficLightButtonsTopMargin = 0; @implementation WAYWindow + (BOOL) supportsVibrantAppearances { return (NSClassFromString(@"NSVisualEffectView")!=nil); } + (float) defaultTitleBarHeight { NSRect frame = NSMakeRect(0, 0, 800, 600); NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask: NSTitledWindowMask]; return NSHeight(frame) - NSHeight(contentRect); } #pragma mark - NSWindow Overwritings - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag { if ((self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag])) { [self setUp]; } return self; } - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)screen { if ((self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag screen:screen])) { [self setUp]; } return self; } - (void) setDelegate:(id)delegate { [_delegateProxy setSecondaryDelegate:delegate]; [super setDelegate:_delegateProxy]; } - (id) delegate { return [_delegateProxy secondaryDelegate]; } - (void) setFrame:(NSRect)frameRect display:(BOOL)flag { [super setFrame:frameRect display:flag]; [self setNeedsLayout]; } #pragma mark - Public - (NSView *) titleBarView { return [_standardButtons[0] superview]; } - (void) setCenterTrafficLightButtons:(BOOL)centerTrafficLightButtons { _centerTrafficLightButtons = centerTrafficLightButtons; [self setNeedsLayout]; } - (void) setTitleBarHeight:(CGFloat)titleBarHeight { if (_dummyTitlebarAccessoryViewController) { [self removeTitlebarAccessoryViewControllerAtIndex:0]; } NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 10, titleBarHeight-[WAYWindow defaultTitleBarHeight])]; _dummyTitlebarAccessoryViewController = [NSTitlebarAccessoryViewController new]; _dummyTitlebarAccessoryViewController.view = view; [self addTitlebarAccessoryViewController:_dummyTitlebarAccessoryViewController]; } - (void) setHidesTitle:(BOOL)hidesTitle { _hidesTitle = hidesTitle; [self setTitleVisibility:hidesTitle ? NSWindowTitleHidden : NSWindowTitleVisible]; } - (void) setContentViewAppearanceVibrantDark { [self setContentViewAppearance:NSVisualEffectMaterialDark]; } - (void) setContentViewAppearanceVibrantLight { [self setContentViewAppearance:NSVisualEffectMaterialLight]; } - (void) setContentViewAppearance: (int) material { if (![WAYWindow supportsVibrantAppearances]) return; NSVisualEffectView *newContentView = [self replaceSubview:self.contentView withViewOfClass:[NSVisualEffectView class]]; [newContentView setMaterial:material]; [self setContentView:newContentView]; } - (void) setVibrantDarkAppearance { [self setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]]; } - (void) setVibrantLightAppearance { [self setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantLight]]; } - (void) setAquaAppearance { [self setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameAqua]]; } - (BOOL) isFullScreen { return (([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask); } - (void) replaceSubview: (NSView *) aView withView: (NSView *) newView resizing:(BOOL)flag { if (flag) { [newView setFrame:aView.frame]; } [newView setAutoresizesSubviews:aView.autoresizesSubviews]; [aView.subviews.copy enumerateObjectsUsingBlock:^(NSView *subview, NSUInteger idx, BOOL *stop) { NSRect frame = subview.frame; if (subview.constraints.count>0) { NSLog(@"WARNING: [%@ %@] does not work yet with NSView instances, that use auto-layout.", NSStringFromClass([self class]), NSStringFromSelector(_cmd)); } [subview removeFromSuperview]; [newView addSubview:subview]; [subview setFrame:frame]; }]; if (aView==self.contentView) { [self setContentView: newView]; } else { [aView.superview replaceSubview:aView with:newView]; } } - (NSView *) replaceSubview:(NSView *)aView withViewOfClass:(Class)newViewClass { NSView *view = [[newViewClass alloc] initWithFrame:aView.frame]; [self replaceSubview:aView withView:view resizing:YES]; return view; } #pragma mark - Private - (void) setUp { _delegateProxy = [WAYWindowDelegateProxy alloc]; _standardButtons = @[[self standardWindowButton:NSWindowCloseButton], [self standardWindowButton:NSWindowMiniaturizeButton], [self standardWindowButton:NSWindowZoomButton]]; _centerTrafficLightButtons = YES; NSButton *closeButton = [self standardWindowButton:NSWindowCloseButton]; kWAYWindowDefaultTrafficLightButtonsLeftMargin = NSMinX(closeButton.frame); kWAYWindowDefaultTrafficLightButtonsTopMargin = NSHeight(closeButton.superview.frame)-NSMaxY(closeButton.frame); self.styleMask |= NSFullSizeContentViewWindowMask; _trafficLightButtonsLeftMargin = kWAYWindowDefaultTrafficLightButtonsLeftMargin; [super setDelegate:self]; [self setNeedsLayout]; } - (void) setNeedsLayout { [_standardButtons enumerateObjectsUsingBlock:^(NSButton *standardButton, NSUInteger idx, BOOL *stop) { NSRect frame = standardButton.frame; if (_centerTrafficLightButtons) frame.origin.y = NSHeight(standardButton.superview.frame)/2-NSHeight(standardButton.frame)/2; else frame.origin.y = NSHeight(standardButton.superview.frame)-NSHeight(standardButton.frame)-kWAYWindowDefaultTrafficLightButtonsTopMargin; frame.origin.x = _trafficLightButtonsLeftMargin +idx*(NSWidth(frame) + 6); [standardButton setFrame:frame]; }]; } #pragma mark - NSWindow Delegate - (void) windowDidResize:(NSNotification *)notification { [self setNeedsLayout]; } @end ================================================ FILE: WAYWindowDemo/main.m ================================================ // // main.m // WAYWindow // // Created by Raffael Hannemann on 15.11.14. // Copyright (c) 2014 We Are Yeah!. All rights reserved. // #import int main(int argc, const char * argv[]) { return NSApplicationMain(argc, argv); } ================================================ FILE: WAYWindowDemo.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 4D06F6551A18C13600B725C6 /* WAYWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D06F6541A18C13600B725C6 /* WAYWindow.m */; }; 4DF97AD11A17DA7700351BC9 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DF97AD01A17DA7700351BC9 /* AppDelegate.m */; }; 4DF97AD31A17DA7700351BC9 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DF97AD21A17DA7700351BC9 /* main.m */; }; 4DF97AD81A17DA7700351BC9 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4DF97AD61A17DA7700351BC9 /* MainMenu.xib */; }; 4DF97AFA1A17F11900351BC9 /* calculatorIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DF97AF81A17F11900351BC9 /* calculatorIcon@2x.png */; }; 4DF97AFB1A17F11900351BC9 /* viewIcon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DF97AF91A17F11900351BC9 /* viewIcon@2x.png */; }; 4DF97AFD1A17F1E600351BC9 /* dummyBackground@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DF97AFC1A17F1E600351BC9 /* dummyBackground@2x.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 4D06F6531A18C13600B725C6 /* WAYWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WAYWindow.h; sourceTree = ""; }; 4D06F6541A18C13600B725C6 /* WAYWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WAYWindow.m; sourceTree = ""; }; 4DF97ACA1A17DA7700351BC9 /* WAYWindowDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WAYWindowDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4DF97ACE1A17DA7700351BC9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 4DF97ACF1A17DA7700351BC9 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.objj.h; path = AppDelegate.h; sourceTree = ""; }; 4DF97AD01A17DA7700351BC9 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 4DF97AD21A17DA7700351BC9 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 4DF97AD71A17DA7700351BC9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; 4DF97AF81A17F11900351BC9 /* calculatorIcon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "calculatorIcon@2x.png"; sourceTree = ""; }; 4DF97AF91A17F11900351BC9 /* viewIcon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "viewIcon@2x.png"; sourceTree = ""; }; 4DF97AFC1A17F1E600351BC9 /* dummyBackground@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "dummyBackground@2x.png"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 4DF97AC71A17DA7700351BC9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 4D06F6521A18C13600B725C6 /* WAYWindow */ = { isa = PBXGroup; children = ( 4D06F6531A18C13600B725C6 /* WAYWindow.h */, 4D06F6541A18C13600B725C6 /* WAYWindow.m */, ); path = WAYWindow; sourceTree = SOURCE_ROOT; }; 4DF97AC11A17DA7700351BC9 = { isa = PBXGroup; children = ( 4DF97ACC1A17DA7700351BC9 /* WAYWindowDemo */, 4DF97ACB1A17DA7700351BC9 /* Products */, ); sourceTree = ""; }; 4DF97ACB1A17DA7700351BC9 /* Products */ = { isa = PBXGroup; children = ( 4DF97ACA1A17DA7700351BC9 /* WAYWindowDemo.app */, ); name = Products; sourceTree = ""; }; 4DF97ACC1A17DA7700351BC9 /* WAYWindowDemo */ = { isa = PBXGroup; children = ( 4D06F6521A18C13600B725C6 /* WAYWindow */, 4DF97ACF1A17DA7700351BC9 /* AppDelegate.h */, 4DF97AD01A17DA7700351BC9 /* AppDelegate.m */, 4DF97AF81A17F11900351BC9 /* calculatorIcon@2x.png */, 4DF97AF91A17F11900351BC9 /* viewIcon@2x.png */, 4DF97AFC1A17F1E600351BC9 /* dummyBackground@2x.png */, 4DF97AD61A17DA7700351BC9 /* MainMenu.xib */, 4DF97ACD1A17DA7700351BC9 /* Supporting Files */, ); path = WAYWindowDemo; sourceTree = ""; }; 4DF97ACD1A17DA7700351BC9 /* Supporting Files */ = { isa = PBXGroup; children = ( 4DF97ACE1A17DA7700351BC9 /* Info.plist */, 4DF97AD21A17DA7700351BC9 /* main.m */, ); name = "Supporting Files"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 4DF97AC91A17DA7700351BC9 /* WAYWindowDemo */ = { isa = PBXNativeTarget; buildConfigurationList = 4DF97AE71A17DA7700351BC9 /* Build configuration list for PBXNativeTarget "WAYWindowDemo" */; buildPhases = ( 4DF97AC61A17DA7700351BC9 /* Sources */, 4DF97AC71A17DA7700351BC9 /* Frameworks */, 4DF97AC81A17DA7700351BC9 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = WAYWindowDemo; productName = WAYWindow; productReference = 4DF97ACA1A17DA7700351BC9 /* WAYWindowDemo.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 4DF97AC21A17DA7700351BC9 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0610; ORGANIZATIONNAME = "We Are Yeah!"; TargetAttributes = { 4DF97AC91A17DA7700351BC9 = { CreatedOnToolsVersion = 6.1; }; }; }; buildConfigurationList = 4DF97AC51A17DA7700351BC9 /* Build configuration list for PBXProject "WAYWindowDemo" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 4DF97AC11A17DA7700351BC9; productRefGroup = 4DF97ACB1A17DA7700351BC9 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 4DF97AC91A17DA7700351BC9 /* WAYWindowDemo */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 4DF97AC81A17DA7700351BC9 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 4DF97AD81A17DA7700351BC9 /* MainMenu.xib in Resources */, 4DF97AFB1A17F11900351BC9 /* viewIcon@2x.png in Resources */, 4DF97AFA1A17F11900351BC9 /* calculatorIcon@2x.png in Resources */, 4DF97AFD1A17F1E600351BC9 /* dummyBackground@2x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 4DF97AC61A17DA7700351BC9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4D06F6551A18C13600B725C6 /* WAYWindow.m in Sources */, 4DF97AD31A17DA7700351BC9 /* main.m in Sources */, 4DF97AD11A17DA7700351BC9 /* AppDelegate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 4DF97AD61A17DA7700351BC9 /* MainMenu.xib */ = { isa = PBXVariantGroup; children = ( 4DF97AD71A17DA7700351BC9 /* Base */, ); name = MainMenu.xib; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 4DF97AE51A17DA7700351BC9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; 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_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; }; name = Debug; }; 4DF97AE61A17DA7700351BC9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; name = Release; }; 4DF97AE81A17DA7700351BC9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = "$(SRCROOT)/WAYWindowDemo/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_NAME = WAYWindowDemo; }; name = Debug; }; 4DF97AE91A17DA7700351BC9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = "$(SRCROOT)/WAYWindowDemo/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_NAME = WAYWindowDemo; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 4DF97AC51A17DA7700351BC9 /* Build configuration list for PBXProject "WAYWindowDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( 4DF97AE51A17DA7700351BC9 /* Debug */, 4DF97AE61A17DA7700351BC9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 4DF97AE71A17DA7700351BC9 /* Build configuration list for PBXNativeTarget "WAYWindowDemo" */ = { isa = XCConfigurationList; buildConfigurations = ( 4DF97AE81A17DA7700351BC9 /* Debug */, 4DF97AE91A17DA7700351BC9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 4DF97AC21A17DA7700351BC9 /* Project object */; } ================================================ FILE: WAYWindowDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: WAYWindowDemo.xcodeproj/project.xcworkspace/xcshareddata/WAYWindow.xccheckout ================================================ IDESourceControlProjectFavoriteDictionaryKey IDESourceControlProjectIdentifier A133E621-7D99-47BA-83AB-1FBAB9AE441B IDESourceControlProjectOriginsDictionary C1421C99D055D3A535089DA2BBEC5EFC9A0200F0 https://github.com/weAreYeah/WAYWindow.git IDESourceControlProjectRelativeInstallPathDictionary C1421C99D055D3A535089DA2BBEC5EFC9A0200F0 WAYWindow/ IDESourceControlProjectURL https://github.com/weAreYeah/WAYWindow.git IDESourceControlProjectVersion 111 IDESourceControlProjectWCCIdentifier C1421C99D055D3A535089DA2BBEC5EFC9A0200F0 IDESourceControlProjectWCConfigurations IDESourceControlRepositoryExtensionIdentifierKey public.vcs.git IDESourceControlWCCIdentifierKey C1421C99D055D3A535089DA2BBEC5EFC9A0200F0 IDESourceControlWCCName WAYWindow ================================================ FILE: WAYWindowDemo.xcodeproj/project.xcworkspace/xcshareddata/WAYWindowDemo.xccheckout ================================================ IDESourceControlProjectFavoriteDictionaryKey IDESourceControlProjectIdentifier D7D9DF91-EC69-454D-809B-D007E8C6135B IDESourceControlProjectName WAYWindowDemo IDESourceControlProjectOriginsDictionary C1421C99D055D3A535089DA2BBEC5EFC9A0200F0 https://github.com/weAreYeah/WAYWindow.git IDESourceControlProjectPath WAYWindowDemo.xcodeproj IDESourceControlProjectRelativeInstallPathDictionary C1421C99D055D3A535089DA2BBEC5EFC9A0200F0 ../.. IDESourceControlProjectURL https://github.com/weAreYeah/WAYWindow.git IDESourceControlProjectVersion 111 IDESourceControlProjectWCCIdentifier C1421C99D055D3A535089DA2BBEC5EFC9A0200F0 IDESourceControlProjectWCConfigurations IDESourceControlRepositoryExtensionIdentifierKey public.vcs.git IDESourceControlWCCIdentifierKey C1421C99D055D3A535089DA2BBEC5EFC9A0200F0 IDESourceControlWCCName WAYWindow