├── screenshots ├── vibrantTitlebarWindowDark.png └── vibrantTitlebarWindowLight.png ├── .gitignore ├── GRVibrantTitlebarWindow ├── GRVibrantTitleView.h ├── GRSeparatorLineView.h ├── GRVibrantTitlebarView.h ├── GRSeparatorLineView.m ├── GRVibrantTitlebarWindow.h ├── GRVibrantTitleView.m ├── GRVibrantTitlebarWindow.m └── GRVibrantTitlebarView.m ├── Vibrant Titlebar Demo ├── ViewController.h ├── main.m ├── AppDelegate.h ├── NSColor+Random.h ├── NSColor+Random.m ├── AppDelegate.m ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── ViewController.m └── Base.lproj │ └── Main.storyboard ├── README.md ├── LICENSE └── Vibrant Titlebar Demo.xcodeproj └── project.pbxproj /screenshots/vibrantTitlebarWindowDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/insidegui/GRVibrantTitlebarWindow/HEAD/screenshots/vibrantTitlebarWindowDark.png -------------------------------------------------------------------------------- /screenshots/vibrantTitlebarWindowLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/insidegui/GRVibrantTitlebarWindow/HEAD/screenshots/vibrantTitlebarWindowLight.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | __MACOSX 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | DerivedData 17 | .idea/ -------------------------------------------------------------------------------- /GRVibrantTitlebarWindow/GRVibrantTitleView.h: -------------------------------------------------------------------------------- 1 | // 2 | // GRVibrantTitleView.h 3 | // Visual Experiments 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GRVibrantTitleView : NSView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /GRVibrantTitlebarWindow/GRSeparatorLineView.h: -------------------------------------------------------------------------------- 1 | // 2 | // GRSeparatorLineView.h 3 | // Visual Experiments 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GRSeparatorLineView : NSView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Vibrant Titlebar Demo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // Vibrant Titlebar Demo 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : NSViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Vibrant Titlebar Demo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Vibrant Titlebar Demo 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | return NSApplicationMain(argc, argv); 13 | } 14 | -------------------------------------------------------------------------------- /Vibrant Titlebar Demo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Vibrant Titlebar Demo 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : NSObject 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Vibrant Titlebar Demo/NSColor+Random.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+Random.h 3 | // Visual Experiments 4 | // 5 | // Created by iCloud Tester on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSColor (Random) 12 | 13 | + (NSColor *)gr_randomColor; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /GRVibrantTitlebarWindow/GRVibrantTitlebarView.h: -------------------------------------------------------------------------------- 1 | // 2 | // GRTitlebarView.h 3 | // Visual Experiments 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class GRVibrantTitleView; 12 | 13 | @interface GRVibrantTitlebarView : NSVisualEffectView 14 | 15 | @property (nonatomic, strong) GRVibrantTitleView *titleView; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Vibrant Titlebar Demo/NSColor+Random.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+Random.m 3 | // Visual Experiments 4 | // 5 | // Created by iCloud Tester on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import "NSColor+Random.h" 10 | 11 | @implementation NSColor (Random) 12 | 13 | + (NSColor *)gr_randomColor 14 | { 15 | CGFloat red = (CGFloat)random()/(CGFloat)RAND_MAX; 16 | CGFloat blue = (CGFloat)random()/(CGFloat)RAND_MAX; 17 | CGFloat green = (CGFloat)random()/(CGFloat)RAND_MAX; 18 | 19 | return [NSColor colorWithCalibratedRed:red green:green blue:blue alpha:1.0]; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Vibrant Titlebar Demo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Vibrant Titlebar Demo 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 18 | // Insert code here to initialize your application 19 | } 20 | 21 | - (void)applicationWillTerminate:(NSNotification *)aNotification { 22 | // Insert code here to tear down your application 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /GRVibrantTitlebarWindow/GRSeparatorLineView.m: -------------------------------------------------------------------------------- 1 | // 2 | // GRSeparatorLineView.m 3 | // Visual Experiments 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import "GRSeparatorLineView.h" 10 | 11 | @implementation GRSeparatorLineView 12 | 13 | - (void)drawRect:(NSRect)dirtyRect { 14 | [super drawRect:dirtyRect]; 15 | 16 | NSColor *lineColor = [[NSColor secondaryLabelColor] colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]]; 17 | [[NSColor colorWithRed:lineColor.redComponent green:lineColor.greenComponent blue:lineColor.blueComponent alpha:0.5] setFill]; 18 | 19 | NSRectFill(dirtyRect); 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /GRVibrantTitlebarWindow/GRVibrantTitlebarWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // GRVibrantTitlebarWindow.h 3 | // Visual Experiments 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GRVibrantTitlebarWindow : NSWindow 12 | 13 | /** 14 | Set whether the window's vibrant titlebar should be hidden when the window enters fullscreen mode 15 | */ 16 | @property (nonatomic, assign) BOOL hidesTitlebarWhenFullscreen; 17 | 18 | /** 19 | Set the titlebar's appearance (use NSAppearanceNameVibrantLight or NSAppearanceNameVibrantDark) 20 | */ 21 | @property (nonatomic, assign) NSAppearance *titlebarAppearance; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GRVibrantTitlebarWindow 2 | 3 | NSWindow with vibrant titlebar. 4 | 5 | ## Usage 6 | 7 | See the included demo for an example of how to use It. It's simple :) 8 | 9 | ## Screenshots 10 | 11 | ![screenshot](https://raw.github.com/insidegui/GRVibrantTitlebarWindow/master/screenshots/vibrantTitlebarWindowDark.png) 12 | ![screenshot](https://raw.github.com/insidegui/GRVibrantTitlebarWindow/master/screenshots/vibrantTitlebarWindowLight.png) 13 | 14 | ## Contributing 15 | 16 | You can contribute with code, just send me a pull request, or open an issue for any bug/enhancement. 17 | 18 | Disclaimer: sending a pull request does not mean I will accept It, if I don't accept your pull request It doesn't mean I don't love you ;) -------------------------------------------------------------------------------- /Vibrant Titlebar Demo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Vibrant Titlebar Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | br.com.guilhermerambo.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2014 Guilherme Rambo. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Guilherme Rambo 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | - Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | - Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /Vibrant Titlebar Demo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // Vibrant Titlebar Demo 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | #import "NSColor+Random.h" 12 | 13 | #import "GRVibrantTitlebarWindow.h" 14 | 15 | @interface ViewController () 16 | 17 | @property (weak) IBOutlet NSTableView *tableView; 18 | 19 | @property (nonatomic, strong) NSMutableArray *items; 20 | 21 | @end 22 | 23 | @implementation ViewController 24 | 25 | - (void)viewDidAppear 26 | { 27 | [super viewDidAppear]; 28 | 29 | // you can change the title's appearance to make It dark instead of light 30 | // [((GRVibrantTitlebarWindow *)self.view.window) setTitlebarAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]]; 31 | } 32 | 33 | - (void)viewDidLoad { 34 | [super viewDidLoad]; 35 | 36 | 37 | // adjust the scrollview so It scrolls past the titlebar 38 | self.tableView.enclosingScrollView.automaticallyAdjustsContentInsets = NO; 39 | self.tableView.enclosingScrollView.contentInsets = NSEdgeInsetsMake(NSHeight(self.view.window.frame)+60.0, 0, 0, 0); 40 | NSRect bounds = self.tableView.enclosingScrollView.contentView.bounds; 41 | bounds.origin.y -= 60.0; 42 | self.tableView.enclosingScrollView.contentView.bounds = bounds; 43 | 44 | 45 | for (int i = 0; i < 100; i++) { 46 | NSDictionary *item = @{@"title": [NSString stringWithFormat:@"Item %d", i+1], 47 | @"color": [NSColor gr_randomColor]}; 48 | [self.items addObject:item]; 49 | } 50 | 51 | [self.tableView reloadData]; 52 | } 53 | 54 | - (NSMutableArray *)items 55 | { 56 | if (!_items) _items = [[NSMutableArray alloc] init]; 57 | 58 | return _items; 59 | } 60 | 61 | #pragma mark Table View 62 | 63 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView 64 | { 65 | return self.items.count; 66 | } 67 | 68 | - (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 69 | { 70 | NSTableCellView *cellView = [tableView makeViewWithIdentifier:@"cell" owner:tableView]; 71 | 72 | NSDictionary *item = self.items[row]; 73 | cellView.textField.stringValue = item[@"title"]; 74 | 75 | return cellView; 76 | } 77 | 78 | - (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row 79 | { 80 | NSDictionary *item = self.items[row]; 81 | rowView.backgroundColor = item[@"color"]; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /GRVibrantTitlebarWindow/GRVibrantTitleView.m: -------------------------------------------------------------------------------- 1 | // 2 | // GRVibrantTitleView.m 3 | // Visual Experiments 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import "GRVibrantTitleView.h" 10 | 11 | static void *_windowTitleObservationContext = &_windowTitleObservationContext; 12 | 13 | @interface GRVibrantTitleView () 14 | 15 | @property (nonatomic, copy) NSString *title; 16 | 17 | @end 18 | 19 | @implementation GRVibrantTitleView 20 | 21 | - (void)viewDidMoveToWindow 22 | { 23 | // update the title when we get moved into a window 24 | self.title = self.window.title; 25 | 26 | // add ourselves as an observer so every time the title of the window changes we are notified about it 27 | [self.window addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:_windowTitleObservationContext]; 28 | } 29 | 30 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 31 | { 32 | if (context != _windowTitleObservationContext) return [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 33 | 34 | self.title = self.window.title; 35 | } 36 | 37 | #define kTextAlignmentPadding 50.0 38 | - (void)drawRect:(NSRect)dirtyRect { 39 | [super drawRect:dirtyRect]; 40 | 41 | NSMutableParagraphStyle *pStyle = [[NSMutableParagraphStyle alloc] init]; 42 | // this will make the text truncate when the titlebar gets too small 43 | pStyle.lineBreakMode = NSLineBreakByTruncatingTail; 44 | // this will center the text 45 | pStyle.alignment = NSCenterTextAlignment; 46 | 47 | // make a dictionary of attributes for our title text 48 | NSDictionary *attributes = @{NSFontAttributeName: [NSFont titleBarFontOfSize:13.0], 49 | NSParagraphStyleAttributeName: pStyle, 50 | // with vibrancy, the labelColor will vary depending on the background contents 51 | NSForegroundColorAttributeName: [NSColor labelColor]}; 52 | 53 | NSAttributedString *textString = [[NSAttributedString alloc] initWithString:self.title attributes:attributes]; 54 | 55 | // voodoo 56 | NSRect textRect = NSMakeRect(0, 0, NSWidth(self.bounds)-kTextAlignmentPadding, NSHeight(self.bounds)); 57 | CGFloat widthDiff = self.bounds.size.width-textString.size.width; 58 | if (widthDiff <= kTextAlignmentPadding && widthDiff > 0) { 59 | textRect.size.width += kTextAlignmentPadding-widthDiff; 60 | } 61 | 62 | // draw :) 63 | [textString drawInRect:textRect]; 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /GRVibrantTitlebarWindow/GRVibrantTitlebarWindow.m: -------------------------------------------------------------------------------- 1 | // 2 | // GRVibrantTitlebarWindow.m 3 | // Visual Experiments 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import "GRVibrantTitlebarWindow.h" 10 | 11 | #import "GRVibrantTitlebarView.h" 12 | #import "GRVibrantTitleView.h" 13 | 14 | @interface GRVibrantTitlebarWindow () 15 | 16 | @property (nonatomic, assign) NSWindowTitleVisibility internalTitleVisibility; 17 | @property (nonatomic, strong) GRVibrantTitlebarView *titlebarView; 18 | 19 | @end 20 | 21 | @implementation GRVibrantTitlebarWindow 22 | 23 | - (void)awakeFromNib 24 | { 25 | [super awakeFromNib]; 26 | 27 | self.styleMask |= NSFullSizeContentViewWindowMask; 28 | self.titlebarAppearsTransparent = YES; 29 | 30 | [self setupTitlebar]; 31 | 32 | [[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillEnterFullScreenNotification object:self queue:nil usingBlock:^(NSNotification *note) { 33 | if (self.hidesTitlebarWhenFullscreen) [self.titlebarView setHidden:YES]; 34 | }]; 35 | [[NSNotificationCenter defaultCenter] addObserverForName:NSWindowWillExitFullScreenNotification object:self queue:nil usingBlock:^(NSNotification *note) { 36 | if (self.hidesTitlebarWhenFullscreen) [self.titlebarView setHidden:NO]; 37 | }]; 38 | 39 | // defaults 40 | self.titleVisibility = NSWindowTitleVisible; 41 | self.titlebarAppearance = [NSAppearance appearanceNamed:NSAppearanceNameVibrantLight]; 42 | self.hidesTitlebarWhenFullscreen = NO; 43 | } 44 | 45 | - (void)setupTitlebar 46 | { 47 | if (self.titlebarView) return; 48 | 49 | // create a vibrant titlebar view and put it in the window 50 | self.titlebarView = [[GRVibrantTitlebarView alloc] initWithFrame:NSMakeRect(0, NSHeight(self.frame)-60, NSWidth(self.frame), 60)]; 51 | self.titlebarView.autoresizingMask = NSViewMinYMargin|NSViewWidthSizable; 52 | self.titlebarView.blendingMode = NSVisualEffectBlendingModeWithinWindow; 53 | 54 | [self.contentView addSubview:self.titlebarView]; 55 | } 56 | 57 | #pragma mark Setters 58 | 59 | - (void)setTitlebarAppearance:(NSAppearance *)titlebarAppearance 60 | { 61 | self.titlebarView.appearance = titlebarAppearance; 62 | } 63 | 64 | - (void)setTitleVisibility:(NSWindowTitleVisibility)titleVisibility 65 | { 66 | self.internalTitleVisibility = titleVisibility; 67 | 68 | [super setTitleVisibility:NSWindowTitleHidden]; 69 | } 70 | 71 | - (void)setInternalTitleVisibility:(NSWindowTitleVisibility)internalTitleVisibility 72 | { 73 | _internalTitleVisibility = internalTitleVisibility; 74 | 75 | self.titlebarView.titleView.hidden = (self.internalTitleVisibility == NSWindowTitleHidden) ? YES : NO; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /GRVibrantTitlebarWindow/GRVibrantTitlebarView.m: -------------------------------------------------------------------------------- 1 | // 2 | // GRTitlebarView.m 3 | // Visual Experiments 4 | // 5 | // Created by Guilherme Rambo on 23/08/14. 6 | // Copyright (c) 2014 Guilherme Rambo. All rights reserved. 7 | // 8 | 9 | #import "GRVibrantTitlebarView.h" 10 | 11 | #import "GRVibrantTitleView.h" 12 | #import "GRSeparatorLineView.h" 13 | 14 | @interface GRVibrantTitlebarView () 15 | 16 | @property (nonatomic, strong) GRSeparatorLineView *lineView; 17 | 18 | @end 19 | 20 | @implementation GRVibrantTitlebarView 21 | 22 | #define kTitleTopOffset 2.0 23 | #define kTitleLeftOffset 70.0 24 | #define kTitleHeight 14.0 25 | - (instancetype)initWithFrame:(NSRect)frameRect 26 | { 27 | self = [super initWithFrame:frameRect]; 28 | 29 | if (!self) return nil; 30 | 31 | self.lineView = [[GRSeparatorLineView alloc] initWithFrame:NSMakeRect(0, 0, NSWidth(self.frame), 1.0)]; 32 | self.lineView.autoresizingMask = NSViewWidthSizable|NSViewMaxYMargin; 33 | [self addSubview:self.lineView]; 34 | 35 | self.titleView = [[GRVibrantTitleView alloc] initWithFrame:NSMakeRect(kTitleLeftOffset, NSHeight(self.frame)-kTitleHeight-kTitleTopOffset, NSWidth(self.frame)-kTitleLeftOffset, kTitleHeight)]; 36 | self.titleView.autoresizingMask = NSViewWidthSizable|NSViewMinYMargin; 37 | [self addSubview:self.titleView]; 38 | 39 | return self; 40 | } 41 | 42 | - (void)mouseDragged:(NSEvent *)theEvent 43 | { 44 | NSWindow *window = self.window; 45 | if (window.isMovableByWindowBackground || (window.styleMask & NSFullScreenWindowMask) == NSFullScreenWindowMask) { 46 | [super mouseDragged:theEvent]; 47 | return; 48 | } 49 | 50 | NSPoint where = [window convertRectToScreen:NSMakeRect(theEvent.locationInWindow.x, theEvent.locationInWindow.y, 0, 0)].origin; 51 | NSPoint origin = window.frame.origin; 52 | CGFloat deltaX = 0.0; 53 | CGFloat deltaY = 0.0; 54 | while ((theEvent = [NSApp nextEventMatchingMask:NSLeftMouseDownMask | NSLeftMouseDraggedMask | NSLeftMouseUpMask untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:YES]) && (theEvent.type != NSLeftMouseUp)) { 55 | @autoreleasepool { 56 | NSPoint now = [window convertRectToScreen:NSMakeRect(theEvent.locationInWindow.x, theEvent.locationInWindow.y, 0, 0)].origin; 57 | deltaX += now.x - where.x; 58 | deltaY += now.y - where.y; 59 | if (fabs(deltaX) >= 1 || fabs(deltaY) >= 1) { 60 | // This part is only called if drag occurs on container view! 61 | origin.x += deltaX; 62 | origin.y += deltaY; 63 | window.frameOrigin = origin; 64 | deltaX = 0.0; 65 | deltaY = 0.0; 66 | } 67 | where = now; // this should be inside above if but doing that results in jittering while moving the window... 68 | } 69 | } 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /Vibrant Titlebar Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 28132D8619A9200E00736410 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 28132D8519A9200E00736410 /* main.m */; }; 11 | 28132D8919A9200E00736410 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28132D8819A9200E00736410 /* ViewController.m */; }; 12 | 28132D8C19A9200E00736410 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 28132D8B19A9200E00736410 /* AppDelegate.m */; }; 13 | 28132D8E19A9200E00736410 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 28132D8D19A9200E00736410 /* Images.xcassets */; }; 14 | 28132D9119A9200E00736410 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 28132D8F19A9200E00736410 /* Main.storyboard */; }; 15 | 28132DAF19A9204200736410 /* GRSeparatorLineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28132DA819A9204200736410 /* GRSeparatorLineView.m */; }; 16 | 28132DB019A9204200736410 /* GRVibrantTitlebarView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28132DAA19A9204200736410 /* GRVibrantTitlebarView.m */; }; 17 | 28132DB119A9204200736410 /* GRVibrantTitlebarWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 28132DAC19A9204200736410 /* GRVibrantTitlebarWindow.m */; }; 18 | 28132DB219A9204200736410 /* GRVibrantTitleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 28132DAE19A9204200736410 /* GRVibrantTitleView.m */; }; 19 | 28132DB519A9226100736410 /* NSColor+Random.m in Sources */ = {isa = PBXBuildFile; fileRef = 28132DB419A9226100736410 /* NSColor+Random.m */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXFileReference section */ 23 | 28132D8019A9200E00736410 /* Vibrant Titlebar Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Vibrant Titlebar Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | 28132D8419A9200E00736410 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 25 | 28132D8519A9200E00736410 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 26 | 28132D8719A9200E00736410 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 27 | 28132D8819A9200E00736410 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 28 | 28132D8A19A9200E00736410 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 29 | 28132D8B19A9200E00736410 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 30 | 28132D8D19A9200E00736410 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 31 | 28132D9019A9200E00736410 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 32 | 28132DA719A9204200736410 /* GRSeparatorLineView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GRSeparatorLineView.h; sourceTree = ""; }; 33 | 28132DA819A9204200736410 /* GRSeparatorLineView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRSeparatorLineView.m; sourceTree = ""; }; 34 | 28132DA919A9204200736410 /* GRVibrantTitlebarView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GRVibrantTitlebarView.h; sourceTree = ""; }; 35 | 28132DAA19A9204200736410 /* GRVibrantTitlebarView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRVibrantTitlebarView.m; sourceTree = ""; }; 36 | 28132DAB19A9204200736410 /* GRVibrantTitlebarWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GRVibrantTitlebarWindow.h; sourceTree = ""; }; 37 | 28132DAC19A9204200736410 /* GRVibrantTitlebarWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRVibrantTitlebarWindow.m; sourceTree = ""; }; 38 | 28132DAD19A9204200736410 /* GRVibrantTitleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GRVibrantTitleView.h; sourceTree = ""; }; 39 | 28132DAE19A9204200736410 /* GRVibrantTitleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRVibrantTitleView.m; sourceTree = ""; }; 40 | 28132DB319A9226100736410 /* NSColor+Random.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+Random.h"; sourceTree = ""; }; 41 | 28132DB419A9226100736410 /* NSColor+Random.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSColor+Random.m"; sourceTree = ""; }; 42 | /* End PBXFileReference section */ 43 | 44 | /* Begin PBXFrameworksBuildPhase section */ 45 | 28132D7D19A9200E00736410 /* Frameworks */ = { 46 | isa = PBXFrameworksBuildPhase; 47 | buildActionMask = 2147483647; 48 | files = ( 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | 28132D7719A9200E00736410 = { 56 | isa = PBXGroup; 57 | children = ( 58 | 28132D8219A9200E00736410 /* Vibrant Titlebar Demo */, 59 | 28132D8119A9200E00736410 /* Products */, 60 | ); 61 | sourceTree = ""; 62 | }; 63 | 28132D8119A9200E00736410 /* Products */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | 28132D8019A9200E00736410 /* Vibrant Titlebar Demo.app */, 67 | ); 68 | name = Products; 69 | sourceTree = ""; 70 | }; 71 | 28132D8219A9200E00736410 /* Vibrant Titlebar Demo */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 28132DB319A9226100736410 /* NSColor+Random.h */, 75 | 28132DB419A9226100736410 /* NSColor+Random.m */, 76 | 28132DA619A9204200736410 /* GRVibrantTitlebarWindow */, 77 | 28132D8719A9200E00736410 /* ViewController.h */, 78 | 28132D8819A9200E00736410 /* ViewController.m */, 79 | 28132D8A19A9200E00736410 /* AppDelegate.h */, 80 | 28132D8B19A9200E00736410 /* AppDelegate.m */, 81 | 28132D8D19A9200E00736410 /* Images.xcassets */, 82 | 28132D8F19A9200E00736410 /* Main.storyboard */, 83 | 28132D8319A9200E00736410 /* Supporting Files */, 84 | ); 85 | path = "Vibrant Titlebar Demo"; 86 | sourceTree = ""; 87 | }; 88 | 28132D8319A9200E00736410 /* Supporting Files */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 28132D8419A9200E00736410 /* Info.plist */, 92 | 28132D8519A9200E00736410 /* main.m */, 93 | ); 94 | name = "Supporting Files"; 95 | sourceTree = ""; 96 | }; 97 | 28132DA619A9204200736410 /* GRVibrantTitlebarWindow */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 28132DA719A9204200736410 /* GRSeparatorLineView.h */, 101 | 28132DA819A9204200736410 /* GRSeparatorLineView.m */, 102 | 28132DA919A9204200736410 /* GRVibrantTitlebarView.h */, 103 | 28132DAA19A9204200736410 /* GRVibrantTitlebarView.m */, 104 | 28132DAB19A9204200736410 /* GRVibrantTitlebarWindow.h */, 105 | 28132DAC19A9204200736410 /* GRVibrantTitlebarWindow.m */, 106 | 28132DAD19A9204200736410 /* GRVibrantTitleView.h */, 107 | 28132DAE19A9204200736410 /* GRVibrantTitleView.m */, 108 | ); 109 | path = GRVibrantTitlebarWindow; 110 | sourceTree = SOURCE_ROOT; 111 | }; 112 | /* End PBXGroup section */ 113 | 114 | /* Begin PBXNativeTarget section */ 115 | 28132D7F19A9200E00736410 /* Vibrant Titlebar Demo */ = { 116 | isa = PBXNativeTarget; 117 | buildConfigurationList = 28132DA019A9200E00736410 /* Build configuration list for PBXNativeTarget "Vibrant Titlebar Demo" */; 118 | buildPhases = ( 119 | 28132D7C19A9200E00736410 /* Sources */, 120 | 28132D7D19A9200E00736410 /* Frameworks */, 121 | 28132D7E19A9200E00736410 /* Resources */, 122 | ); 123 | buildRules = ( 124 | ); 125 | dependencies = ( 126 | ); 127 | name = "Vibrant Titlebar Demo"; 128 | productName = "Vibrant Titlebar Demo"; 129 | productReference = 28132D8019A9200E00736410 /* Vibrant Titlebar Demo.app */; 130 | productType = "com.apple.product-type.application"; 131 | }; 132 | /* End PBXNativeTarget section */ 133 | 134 | /* Begin PBXProject section */ 135 | 28132D7819A9200E00736410 /* Project object */ = { 136 | isa = PBXProject; 137 | attributes = { 138 | LastUpgradeCheck = 0600; 139 | ORGANIZATIONNAME = "Guilherme Rambo"; 140 | TargetAttributes = { 141 | 28132D7F19A9200E00736410 = { 142 | CreatedOnToolsVersion = 6.0; 143 | }; 144 | }; 145 | }; 146 | buildConfigurationList = 28132D7B19A9200E00736410 /* Build configuration list for PBXProject "Vibrant Titlebar Demo" */; 147 | compatibilityVersion = "Xcode 3.2"; 148 | developmentRegion = English; 149 | hasScannedForEncodings = 0; 150 | knownRegions = ( 151 | en, 152 | Base, 153 | ); 154 | mainGroup = 28132D7719A9200E00736410; 155 | productRefGroup = 28132D8119A9200E00736410 /* Products */; 156 | projectDirPath = ""; 157 | projectRoot = ""; 158 | targets = ( 159 | 28132D7F19A9200E00736410 /* Vibrant Titlebar Demo */, 160 | ); 161 | }; 162 | /* End PBXProject section */ 163 | 164 | /* Begin PBXResourcesBuildPhase section */ 165 | 28132D7E19A9200E00736410 /* Resources */ = { 166 | isa = PBXResourcesBuildPhase; 167 | buildActionMask = 2147483647; 168 | files = ( 169 | 28132D8E19A9200E00736410 /* Images.xcassets in Resources */, 170 | 28132D9119A9200E00736410 /* Main.storyboard in Resources */, 171 | ); 172 | runOnlyForDeploymentPostprocessing = 0; 173 | }; 174 | /* End PBXResourcesBuildPhase section */ 175 | 176 | /* Begin PBXSourcesBuildPhase section */ 177 | 28132D7C19A9200E00736410 /* Sources */ = { 178 | isa = PBXSourcesBuildPhase; 179 | buildActionMask = 2147483647; 180 | files = ( 181 | 28132DB019A9204200736410 /* GRVibrantTitlebarView.m in Sources */, 182 | 28132DB219A9204200736410 /* GRVibrantTitleView.m in Sources */, 183 | 28132D8919A9200E00736410 /* ViewController.m in Sources */, 184 | 28132DB119A9204200736410 /* GRVibrantTitlebarWindow.m in Sources */, 185 | 28132DAF19A9204200736410 /* GRSeparatorLineView.m in Sources */, 186 | 28132D8619A9200E00736410 /* main.m in Sources */, 187 | 28132D8C19A9200E00736410 /* AppDelegate.m in Sources */, 188 | 28132DB519A9226100736410 /* NSColor+Random.m in Sources */, 189 | ); 190 | runOnlyForDeploymentPostprocessing = 0; 191 | }; 192 | /* End PBXSourcesBuildPhase section */ 193 | 194 | /* Begin PBXVariantGroup section */ 195 | 28132D8F19A9200E00736410 /* Main.storyboard */ = { 196 | isa = PBXVariantGroup; 197 | children = ( 198 | 28132D9019A9200E00736410 /* Base */, 199 | ); 200 | name = Main.storyboard; 201 | sourceTree = ""; 202 | }; 203 | /* End PBXVariantGroup section */ 204 | 205 | /* Begin XCBuildConfiguration section */ 206 | 28132D9E19A9200E00736410 /* Debug */ = { 207 | isa = XCBuildConfiguration; 208 | buildSettings = { 209 | ALWAYS_SEARCH_USER_PATHS = NO; 210 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 211 | CLANG_CXX_LIBRARY = "libc++"; 212 | CLANG_ENABLE_MODULES = YES; 213 | CLANG_ENABLE_OBJC_ARC = YES; 214 | CLANG_WARN_BOOL_CONVERSION = YES; 215 | CLANG_WARN_CONSTANT_CONVERSION = YES; 216 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 217 | CLANG_WARN_EMPTY_BODY = YES; 218 | CLANG_WARN_ENUM_CONVERSION = YES; 219 | CLANG_WARN_INT_CONVERSION = YES; 220 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 221 | CLANG_WARN_UNREACHABLE_CODE = YES; 222 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 223 | CODE_SIGN_IDENTITY = "-"; 224 | COPY_PHASE_STRIP = NO; 225 | ENABLE_STRICT_OBJC_MSGSEND = YES; 226 | GCC_C_LANGUAGE_STANDARD = gnu99; 227 | GCC_DYNAMIC_NO_PIC = NO; 228 | GCC_OPTIMIZATION_LEVEL = 0; 229 | GCC_PREPROCESSOR_DEFINITIONS = ( 230 | "DEBUG=1", 231 | "$(inherited)", 232 | ); 233 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 234 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 235 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 236 | GCC_WARN_UNDECLARED_SELECTOR = YES; 237 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 238 | GCC_WARN_UNUSED_FUNCTION = YES; 239 | GCC_WARN_UNUSED_VARIABLE = YES; 240 | MACOSX_DEPLOYMENT_TARGET = 10.10; 241 | MTL_ENABLE_DEBUG_INFO = YES; 242 | ONLY_ACTIVE_ARCH = YES; 243 | SDKROOT = macosx; 244 | }; 245 | name = Debug; 246 | }; 247 | 28132D9F19A9200E00736410 /* Release */ = { 248 | isa = XCBuildConfiguration; 249 | buildSettings = { 250 | ALWAYS_SEARCH_USER_PATHS = NO; 251 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 252 | CLANG_CXX_LIBRARY = "libc++"; 253 | CLANG_ENABLE_MODULES = YES; 254 | CLANG_ENABLE_OBJC_ARC = YES; 255 | CLANG_WARN_BOOL_CONVERSION = YES; 256 | CLANG_WARN_CONSTANT_CONVERSION = YES; 257 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 258 | CLANG_WARN_EMPTY_BODY = YES; 259 | CLANG_WARN_ENUM_CONVERSION = YES; 260 | CLANG_WARN_INT_CONVERSION = YES; 261 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 262 | CLANG_WARN_UNREACHABLE_CODE = YES; 263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 264 | CODE_SIGN_IDENTITY = "-"; 265 | COPY_PHASE_STRIP = YES; 266 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 267 | ENABLE_NS_ASSERTIONS = NO; 268 | ENABLE_STRICT_OBJC_MSGSEND = YES; 269 | GCC_C_LANGUAGE_STANDARD = gnu99; 270 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 271 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 272 | GCC_WARN_UNDECLARED_SELECTOR = YES; 273 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 274 | GCC_WARN_UNUSED_FUNCTION = YES; 275 | GCC_WARN_UNUSED_VARIABLE = YES; 276 | MACOSX_DEPLOYMENT_TARGET = 10.10; 277 | MTL_ENABLE_DEBUG_INFO = NO; 278 | SDKROOT = macosx; 279 | }; 280 | name = Release; 281 | }; 282 | 28132DA119A9200E00736410 /* Debug */ = { 283 | isa = XCBuildConfiguration; 284 | buildSettings = { 285 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 286 | COMBINE_HIDPI_IMAGES = YES; 287 | INFOPLIST_FILE = "Vibrant Titlebar Demo/Info.plist"; 288 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 289 | PRODUCT_NAME = "$(TARGET_NAME)"; 290 | }; 291 | name = Debug; 292 | }; 293 | 28132DA219A9200E00736410 /* Release */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 297 | COMBINE_HIDPI_IMAGES = YES; 298 | INFOPLIST_FILE = "Vibrant Titlebar Demo/Info.plist"; 299 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 300 | PRODUCT_NAME = "$(TARGET_NAME)"; 301 | }; 302 | name = Release; 303 | }; 304 | /* End XCBuildConfiguration section */ 305 | 306 | /* Begin XCConfigurationList section */ 307 | 28132D7B19A9200E00736410 /* Build configuration list for PBXProject "Vibrant Titlebar Demo" */ = { 308 | isa = XCConfigurationList; 309 | buildConfigurations = ( 310 | 28132D9E19A9200E00736410 /* Debug */, 311 | 28132D9F19A9200E00736410 /* Release */, 312 | ); 313 | defaultConfigurationIsVisible = 0; 314 | defaultConfigurationName = Release; 315 | }; 316 | 28132DA019A9200E00736410 /* Build configuration list for PBXNativeTarget "Vibrant Titlebar Demo" */ = { 317 | isa = XCConfigurationList; 318 | buildConfigurations = ( 319 | 28132DA119A9200E00736410 /* Debug */, 320 | 28132DA219A9200E00736410 /* Release */, 321 | ); 322 | defaultConfigurationIsVisible = 0; 323 | }; 324 | /* End XCConfigurationList section */ 325 | }; 326 | rootObject = 28132D7819A9200E00736410 /* Project object */; 327 | } 328 | -------------------------------------------------------------------------------- /Vibrant Titlebar Demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | Default 511 | 512 | 513 | 514 | 515 | 516 | 517 | Left to Right 518 | 519 | 520 | 521 | 522 | 523 | 524 | Right to Left 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | Default 536 | 537 | 538 | 539 | 540 | 541 | 542 | Left to Right 543 | 544 | 545 | 546 | 547 | 548 | 549 | Right to Left 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 744 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | --------------------------------------------------------------------------------