├── Inbox for Mac
├── appicon.icns
├── main.m
├── AppDelegate.h
├── Extensions
│ ├── INWindowBackgroundView+CoreUIRendering.h
│ ├── INAppStoreWindowSwizzling.h
│ ├── NSDocument+INAppStoreWindowFixes.h
│ ├── INAppStoreWindowSwizzling.c
│ ├── NSDocument+INAppStoreWindowFixes.m
│ └── INWindowBackgroundView+CoreUIRendering.m
├── ViewController.h
├── AppDelegate.m
├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── INWindowButton.h
├── INAppStoreWindowCompatibility.h
├── ViewController.m
├── WAYAppStoreWindow.m
├── WAYWindow.h
├── INWindowButton.m
├── INAppStoreWindow.h
├── WAYAppStoreWindow.h
├── WAYWindow.m
└── Base.lproj
│ └── Main.storyboard
├── Inbox for Mac.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── Inbox for Mac.xccheckout
├── xcuserdata
│ └── amonk.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── Inbox for Mac.xcscheme
│ │ └── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
└── project.pbxproj
├── README.md
└── Inbox for MacTests
├── Info.plist
└── Inbox_for_MacTests.m
/Inbox for Mac/appicon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/almonk/Inbox-for-Mac/HEAD/Inbox for Mac/appicon.icns
--------------------------------------------------------------------------------
/Inbox for Mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Inbox for Mac/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Inbox for Mac
4 | //
5 | // Created by Alasdair Lampon-Monk on 9/16/15.
6 | // Copyright (c) 2015 Alasdair Lampon-Monk. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/Inbox for Mac/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // Inbox for Mac
4 | //
5 | // Created by Alasdair Lampon-Monk on 9/16/15.
6 | // Copyright (c) 2015 Alasdair Lampon-Monk. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : NSObject
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Inbox for Mac/Extensions/INWindowBackgroundView+CoreUIRendering.h:
--------------------------------------------------------------------------------
1 | //
2 | // INWindowBackgroundView+CoreUIRendering.h
3 | //
4 | // Copyright (c) 2014 Petroules Corporation. All rights reserved.
5 | //
6 | // Licensed under the BSD 2-clause License. See LICENSE file distributed in the source
7 | // code of this project.
8 | //
9 |
10 | #import "INAppStoreWindow.h"
11 |
12 | @interface INWindowBackgroundView (CoreUIRendering)
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/Inbox for Mac/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // Inbox for Mac
4 | //
5 | // Created by Alasdair Lampon-Monk on 9/16/15.
6 | // Copyright (c) 2015 Alasdair Lampon-Monk. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface ViewController : NSViewController {
13 | IBOutlet WebView *webView;
14 | IBOutlet WebView *webView2;
15 | }
16 |
17 |
18 | @end
19 |
20 |
--------------------------------------------------------------------------------
/Inbox for Mac/Extensions/INAppStoreWindowSwizzling.h:
--------------------------------------------------------------------------------
1 | //
2 | // INAppStoreWindowSwizzling.h
3 | //
4 | // Created by Jake Petroules on 1/13/2014.
5 | // Copyright (c) 2011-2014 Indragie Karunaratne. All rights reserved.
6 | //
7 | // Licensed under the BSD 2-clause License. See LICENSE file distributed in the source
8 | // code of this project.
9 | //
10 |
11 | #import
12 |
13 | void INAppStoreWindowSwizzle(Class c, SEL orig, SEL new);
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Inbox-for-Mac
2 | A handsomely simple OSX app wrapper around Google Inbox. Use Inbox as if it were a native OSX app.
3 |
4 | #### Features
5 | * Cleanly supports multiple accounts
6 | * URLs open in your default browser
7 | * Beautiful app icon by Jason Zigrino (source)
8 |
9 | #### Installation
10 | * Download the latest binary
11 | * Drag to your `/Applications` folder
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Inbox for Mac/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // Inbox for Mac
4 | //
5 | // Created by Alasdair Lampon-Monk on 9/16/15.
6 | // Copyright (c) 2015 Alasdair Lampon-Monk. 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 |
--------------------------------------------------------------------------------
/Inbox for Mac.xcodeproj/xcuserdata/amonk.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | Inbox for Mac.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 9F836A291BA9C09B00DE4D39
16 |
17 | primary
18 |
19 |
20 | 9F836A3F1BA9C09C00DE4D39
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Inbox for Mac/Extensions/NSDocument+INAppStoreWindowFixes.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSDocument+INAppStoreWindowFixes.h
3 | // SampleApp
4 | //
5 | // Created by Indragie Karunaratne on 1/5/2014.
6 | // Copyright (c) 2014 Indragie Karunaratne. All rights reserved.
7 | //
8 | // Licensed under the BSD 2-clause License. See LICENSE file distributed in the source
9 | // code of this project.
10 | //
11 |
12 | #import
13 |
14 | // Fix for the issue described here: https://github.com/indragiek/INAppStoreWindow/issues/91
15 | //
16 | // Including this category in your project will swizzle NSDocument -updateChangeCount: such
17 | // that any INAppStoreWindow instances belonging to the document's window controllers will
18 | // automatically relayout their title bars when the change count is updated.
19 | @interface NSDocument (INAppStoreWindowFixes)
20 | @end
21 |
--------------------------------------------------------------------------------
/Inbox for MacTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | alasdairmonk.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Inbox for Mac/Extensions/INAppStoreWindowSwizzling.c:
--------------------------------------------------------------------------------
1 | //
2 | // INAppStoreWindowSwizzling.c
3 | //
4 | // Created by Jake Petroules on 1/13/2014.
5 | // Copyright (c) 2011-2014 Indragie Karunaratne. All rights reserved.
6 | //
7 | // Licensed under the BSD 2-clause License. See LICENSE file distributed in the source
8 | // code of this project.
9 | //
10 |
11 | #import "INAppStoreWindowSwizzling.h"
12 |
13 | void INAppStoreWindowSwizzle(Class c, SEL orig, SEL new)
14 | {
15 | Method origMethod = class_getInstanceMethod(c, orig);
16 | Method newMethod = class_getInstanceMethod(c, new);
17 | if (class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) {
18 | class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
19 | } else {
20 | method_exchangeImplementations(origMethod, newMethod);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Inbox for Mac.xcodeproj/xcuserdata/amonk.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Inbox for MacTests/Inbox_for_MacTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // Inbox_for_MacTests.m
3 | // Inbox for MacTests
4 | //
5 | // Created by Alasdair Lampon-Monk on 9/16/15.
6 | // Copyright (c) 2015 Alasdair Lampon-Monk. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface Inbox_for_MacTests : XCTestCase
13 |
14 | @end
15 |
16 | @implementation Inbox_for_MacTests
17 |
18 | - (void)setUp {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown {
24 | // Put teardown code here. This method is called after the invocation of each test method in the class.
25 | [super tearDown];
26 | }
27 |
28 | - (void)testExample {
29 | // This is an example of a functional test case.
30 | XCTAssert(YES, @"Pass");
31 | }
32 |
33 | - (void)testPerformanceExample {
34 | // This is an example of a performance test case.
35 | [self measureBlock:^{
36 | // Put the code you want to measure the time of here.
37 | }];
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/Inbox for Mac/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 | }
--------------------------------------------------------------------------------
/Inbox for Mac/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 | appicon.icns
11 | CFBundleIdentifier
12 | alasdairmonk.$(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 © 2015 Alasdair Monk. All rights reserved.
29 | NSMainStoryboardFile
30 | Main
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Inbox for Mac/Extensions/NSDocument+INAppStoreWindowFixes.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDocument+INAppStoreWindowFixes.m
3 | // SampleApp
4 | //
5 | // Created by Indragie Karunaratne on 1/5/2014.
6 | // Copyright (c) 2014 Indragie Karunaratne. All rights reserved.
7 | //
8 | // Licensed under the BSD 2-clause License. See LICENSE file distributed in the source
9 | // code of this project.
10 | //
11 |
12 | #import "NSDocument+INAppStoreWindowFixes.h"
13 | #import "INAppStoreWindow.h"
14 | #import "INAppStoreWindowSwizzling.h"
15 |
16 | @interface INAppStoreWindow (Private)
17 | - (void)_layoutTrafficLightsAndContent;
18 | @end
19 |
20 | @implementation NSDocument (INAppStoreWindowFixes)
21 |
22 | + (void)load
23 | {
24 | INAppStoreWindowSwizzle(self, @selector(updateChangeCount:), @selector(ind_updateChangeCount:));
25 | }
26 |
27 | - (void)ind_updateChangeCount:(NSDocumentChangeType)changeType
28 | {
29 | [self ind_updateChangeCount:changeType]; // Original implementation
30 | NSArray *windowControllers = self.windowControllers;
31 | for (NSWindowController *wc in windowControllers) {
32 | if ([wc.window isKindOfClass:INAppStoreWindow.class]) {
33 | [(INAppStoreWindow *)wc.window _layoutTrafficLightsAndContent];
34 | }
35 | }
36 | }
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/Inbox for Mac.xcodeproj/project.xcworkspace/xcshareddata/Inbox for Mac.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | AED412BF-A74D-4C69-8EBB-747F187A49F4
9 | IDESourceControlProjectName
10 | Inbox for Mac
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | C094795CC3531D29D7A2A8916814F085D9823269
14 | https://github.com/almonk/Inbox-for-Mac.git
15 |
16 | IDESourceControlProjectPath
17 | Inbox for Mac.xcodeproj
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | C094795CC3531D29D7A2A8916814F085D9823269
21 | ../..
22 |
23 | IDESourceControlProjectURL
24 | https://github.com/almonk/Inbox-for-Mac.git
25 | IDESourceControlProjectVersion
26 | 111
27 | IDESourceControlProjectWCCIdentifier
28 | C094795CC3531D29D7A2A8916814F085D9823269
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | C094795CC3531D29D7A2A8916814F085D9823269
36 | IDESourceControlWCCName
37 | Inbox%20for%20Mac
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Inbox for Mac/INWindowButton.h:
--------------------------------------------------------------------------------
1 | //
2 | // INWindowButton.h
3 | //
4 | // Copyright 2013-2014 Vladislav Alexeev. All rights reserved.
5 | //
6 | // Licensed under the BSD 2-clause License. See LICENSE file distributed in the source
7 | // code of this project.
8 | //
9 |
10 | #import
11 |
12 | /**
13 | A concrete NSButton subclass that allows to mimic standard window title bar "traffic light" buttons
14 | and replace their graphics with custom ones.
15 | */
16 | @interface INWindowButton : NSButton
17 |
18 | /**
19 | The group identifier the receiver was initialized with.
20 | */
21 | @property (nonatomic, copy, readonly) NSString *groupIdentifier;
22 |
23 | /**
24 | An image for the normal state.
25 | */
26 | @property (nonatomic, strong) NSImage *activeImage;
27 |
28 | /**
29 | An image for the normal state, but displayed when receiver's window in not a key.
30 | */
31 | @property (nonatomic, strong) NSImage *activeNotKeyWindowImage;
32 |
33 | /**
34 | An image used in disabled state.
35 | */
36 | @property (nonatomic, strong) NSImage *inactiveImage;
37 |
38 | /**
39 | An image used when user hovers receiver with mouse pointer.
40 | */
41 | @property (nonatomic, strong) NSImage *rolloverImage;
42 |
43 | /**
44 | An image for the pressed state.
45 | */
46 | @property (nonatomic, strong) NSImage *pressedImage;
47 |
48 | /**
49 | @param size Designated size of the button. System size is 14x16 and you are considered to use it.
50 | @param groupIdentifier ID of the group which will apply rollover effect to its members.
51 | You may pass \c nil.
52 | @see initWithSize:groupIdentifier:
53 | */
54 | + (instancetype)windowButtonWithSize:(NSSize)size groupIdentifier:(NSString *)groupIdentifier;
55 |
56 | /**
57 | @abstract Designated initializer.
58 | @discussion Initializes the receiver with the given size and includes it in the group with the
59 | given identifier.
60 | Groups are used to apply rollover effect to all buttons that are inside the same group.
61 | For example, close, minimize and zoom buttons should be inside the same group since they all get a
62 | rollover effect when the mouse pointer hovers over one of these buttons.
63 | @param size Designated size of the button. System size is 14x16 and you are considered to use it.
64 | @param groupIdentifier ID of the group which will apply rollover effect to its members.
65 | You may pass \c nil.
66 | */
67 | - (instancetype)initWithSize:(NSSize)size groupIdentifier:(NSString *)groupIdentifier;
68 |
69 | @end
70 |
--------------------------------------------------------------------------------
/Inbox for Mac/INAppStoreWindowCompatibility.h:
--------------------------------------------------------------------------------
1 | //
2 | // INAppStoreWindowCompatibility.h
3 | // INAppStoreWindow
4 | //
5 | // Copyright (c) 2011-2014 Indragie Karunaratne. All rights reserved.
6 | // Copyright (c) 2014 Petroules Corporation. All rights reserved.
7 | //
8 | // Licensed under the BSD 2-clause License. See LICENSE file distributed in the source
9 | // code of this project.
10 | //
11 |
12 | #import
13 |
14 | #ifndef NSAppKitVersionNumber10_7
15 | #define NSAppKitVersionNumber10_7 1138
16 | #endif
17 |
18 | #ifndef NSAppKitVersionNumber10_9
19 | #define NSAppKitVersionNumber10_9 1265
20 | #endif
21 |
22 | #ifndef NSAppKitVersionNumber10_10
23 | #define NSAppKitVersionNumber10_10 1343
24 | #endif
25 |
26 | #if __MAC_OS_X_VERSION_MAX_ALLOWED < 1070
27 | enum { NSWindowDocumentVersionsButton = 6, NSWindowFullScreenButton = 7 };
28 | enum { NSFullScreenWindowMask = 1 << 14 };
29 | extern NSString * const NSAccessibilityFullScreenButtonSubrole;
30 | extern NSString * const NSWindowWillEnterFullScreenNotification;
31 | extern NSString * const NSWindowDidEnterFullScreenNotification;
32 | extern NSString * const NSWindowWillExitFullScreenNotification;
33 | extern NSString * const NSWindowDidExitFullScreenNotification;
34 | extern NSString * const NSWindowWillEnterVersionBrowserNotification;
35 | extern NSString * const NSWindowDidEnterVersionBrowserNotification;
36 | extern NSString * const NSWindowWillExitVersionBrowserNotification;
37 | extern NSString * const NSWindowDidExitVersionBrowserNotification;
38 | #endif
39 |
40 | #if __MAC_OS_X_VERSION_MAX_ALLOWED < 1080
41 | @interface NSDictionary (INNSDictionaryBackwardCompatibility)
42 |
43 | // NS_AVAILABLE(10_8, 6_0), but this is a lie - this responds in 10.7
44 | - (id)objectForKeyedSubscript:(id)aKey;
45 |
46 | @end
47 |
48 | @interface NSMutableDictionary (INNSMutableDictionaryBackwardCompatibility)
49 |
50 | // NS_AVAILABLE(10_8, 6_0), but this is a lie - this responds in 10.7
51 | - (void)setObject:(id)obj forKeyedSubscript:(id )key;
52 |
53 | @end
54 | #endif
55 |
56 | #if __MAC_OS_X_VERSION_MAX_ALLOWED < 1090
57 | @interface NSArray (INNSArrayBackwardCompatibility)
58 | - (id)firstObject; // not present in the 10.8 SDK but available since 10.6
59 | @end
60 |
61 | @interface NSData (INNSDataBackwardCompatibility)
62 | - (id)initWithBase64Encoding:(NSString *)base64String;
63 | @end
64 | #endif
65 |
66 | NS_INLINE bool INRunningLion() {
67 | return (NSInteger)NSAppKitVersionNumber >= NSAppKitVersionNumber10_7;
68 | }
69 |
70 | NS_INLINE bool INRunningMavericks() {
71 | return (NSInteger)NSAppKitVersionNumber >= NSAppKitVersionNumber10_9;
72 | }
73 |
74 | NS_INLINE bool INRunningYosemite() {
75 | return (NSInteger)NSAppKitVersionNumber >= NSAppKitVersionNumber10_10;
76 | }
77 |
--------------------------------------------------------------------------------
/Inbox for Mac/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // Inbox for Mac
4 | //
5 | // Created by Alasdair Lampon-Monk on 9/16/15.
6 | // Copyright (c) 2015 Alasdair Lampon-Monk. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | @implementation ViewController
12 |
13 | - (void)viewDidLoad {
14 | [super viewDidLoad];
15 |
16 | [webView setPolicyDelegate:self];
17 |
18 | NSURL*url=[NSURL URLWithString:@"https://inbox.google.com/u/0/"];
19 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
20 | [webView setCustomUserAgent:@"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"];
21 | [[webView mainFrame] loadRequest:request];
22 |
23 | [webView2 setPolicyDelegate:self];
24 |
25 | NSURL*url2=[NSURL URLWithString:@"https://inbox.google.com/u/1/"];
26 | NSMutableURLRequest *request2 = [NSMutableURLRequest requestWithURL:url2];
27 | [webView2 setCustomUserAgent:@"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"];
28 | [[webView2 mainFrame] loadRequest:request2];
29 | // Do any additional setup after loading the view.
30 | }
31 |
32 | - (void)setRepresentedObject:(id)representedObject {
33 | [super setRepresentedObject:representedObject];
34 | // Update the view, if already loaded.
35 | }
36 | //
37 | //- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
38 | //{
39 | // // HACK: This is all a hack to get around a bug/misfeature in Tiger's WebKit
40 | // // (should be fixed in Leopard). On Javascript window.open, Tiger sends a null
41 | // // request here, then sends a loadRequest: to the new WebView, which will
42 | // // include a decidePolicyForNavigation (which is where we'll open our
43 | // // external window). In Leopard, we should be getting the request here from
44 | // // the start, and we should just be able to create a new window.
45 | //
46 | // WebView *newWebView = [[WebView alloc] init];
47 | // [newWebView setUIDelegate:self];
48 | // [newWebView setPolicyDelegate:self];
49 | //
50 | // return newWebView;
51 | //}
52 |
53 | - (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id)listener {
54 | if( [sender isEqual:webView] ) {
55 | [listener use];
56 | }
57 | else {
58 |
59 | if ([[[actionInformation valueForKey:WebActionOriginalURLKey] absoluteString]containsString:@".google.com"]) {
60 | [listener use];
61 | } else {
62 | [[NSWorkspace sharedWorkspace] openURL:[actionInformation objectForKey:WebActionOriginalURLKey]];
63 | [listener ignore];
64 | }
65 |
66 | }
67 | }
68 |
69 | - (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id)listener {
70 | NSLog(@"%@", [actionInformation valueForKey:WebActionOriginalURLKey]);
71 |
72 | if ([[[actionInformation valueForKey:WebActionOriginalURLKey] absoluteString]containsString:@".google.com"]) {
73 | NSURL*url=[NSURL URLWithString:[[actionInformation valueForKey:WebActionOriginalURLKey] absoluteString]];
74 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
75 | [[webView mainFrame] loadRequest:request];
76 | [listener use];
77 | } else {
78 | [[NSWorkspace sharedWorkspace] openURL:[actionInformation objectForKey:WebActionOriginalURLKey]];
79 | [listener ignore];
80 | }
81 |
82 |
83 | }
84 |
85 | @end
86 |
--------------------------------------------------------------------------------
/Inbox for Mac/WAYAppStoreWindow.m:
--------------------------------------------------------------------------------
1 | //
2 | // WAYAppStoreWindow.m
3 | // WAYAppStoreWindow
4 | //
5 | // Created by Raffael Hannemann on 15.11.14.
6 | // Copyright (c) 2014 Raffael Hannemann. All rights reserved.
7 | // Visit weAreYeah.com or follow @weareYeah for updates.
8 | //
9 | // Licensed under the BSD License
10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
11 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
12 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
13 | // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
15 | // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
16 | // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
17 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
18 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19 | //
20 |
21 | #import "WAYAppStoreWindow.h"
22 | #import
23 | #import "WAYWindow.h"
24 | #import "INAppStoreWindow.h"
25 |
26 | // Set this flag to 1, if you want to force the usage of INAppStoreWindow
27 | #define SIMULATE_PRE_YOSEMITE 0
28 |
29 | #pragma mark - WAYDefensiveWindow
30 | /** Internally, if the class decides to use WAYWindow instead of INAppStoreWindow, we won't use WAYWindow directly, but its subclass WAYDefensiveWindow instead, which logs warnings, if the developer calls a method, which is only implemented by INAppStoreWindow. This may happen if the developer tries to make use of features of INAppStoreWindow, which have not been ported yet to WAYWindow. */
31 | @interface WAYDefensiveWindow : WAYWindow
32 | @end
33 |
34 | // DUMMY FUNCTION
35 | void WAYDefensiveWindowDummyIMP(id self, SEL _cmd) {
36 | // This function will be used as method implementation for
37 | // methods which are available in INAppStoreWindow, but not
38 | // in WAYWindow
39 | NSLog(@"WARNING: Instances of '%@' do not implement %@; yet. Prevented an exception for sending unrecognized selector.",
40 | [self superclass],
41 | NSStringFromSelector(_cmd));
42 | }
43 |
44 | @implementation WAYDefensiveWindow : WAYWindow
45 |
46 | + (BOOL) resolveInstanceMethod:(SEL)aSelector {
47 | // If INAppStoreWindow implements this method, and WAYWindow does not, add a new dummy method, which does nothing but logging a warning.
48 | if ([INAppStoreWindow instancesRespondToSelector:aSelector] && ![WAYWindow instancesRespondToSelector:aSelector]) {
49 | class_addMethod([self class], aSelector, (IMP)WAYDefensiveWindowDummyIMP, "v@:");
50 | return YES;
51 | }
52 | return [super resolveInstanceMethod:aSelector];
53 | }
54 |
55 | @end
56 |
57 | /** We need to add private properties of the NSWindow subclasses here. */
58 | @class WAYWindowDelegateProxy;
59 | @interface WAYAppStoreWindow ()
60 | @property (strong) WAYWindowDelegateProxy* delegateProxy;
61 | @property (strong) NSArray* standardButtons;
62 | @property (strong) NSTitlebarAccessoryViewController *dummyTitlebarAccessoryViewController;
63 | @end
64 |
65 | static int isYosemiteOrGreater = -1;
66 |
67 | // Let's suppress Incomplete Implementation warnings
68 | #pragma clang diagnostic ignored "-Wincomplete-implementation"
69 | @implementation WAYAppStoreWindow
70 |
71 | + (BOOL) isYosemiteOrGreater {
72 | if (isYosemiteOrGreater==-1) {
73 | isYosemiteOrGreater = NSClassFromString(@"NSVisualEffectView")!=nil ? 1 : 0;
74 | #if SIMULATE_PRE_YOSEMITE
75 | isYosemiteOrGreater = 0;
76 | #endif
77 | }
78 | return isYosemiteOrGreater;
79 | }
80 |
81 | /** All we do is to swap the class implementation at runtime. */
82 | + (instancetype)alloc {
83 | id instance = [super alloc];
84 | object_setClass(instance, ([self isYosemiteOrGreater]) ? [WAYDefensiveWindow class] : [INAppStoreWindow class]);
85 | return instance;
86 | }
87 |
88 | + (instancetype) allocWithZone:(struct _NSZone *)zone {
89 | id instance = [super allocWithZone:zone];
90 | object_setClass(instance, ([self isYosemiteOrGreater]) ? [WAYDefensiveWindow class] : [INAppStoreWindow class]);
91 | return instance;
92 | }
93 |
94 | @end
95 |
--------------------------------------------------------------------------------
/Inbox for Mac/WAYWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // WAYWindow.m
3 | // WAYWindow
4 | //
5 | // Created by Raffael Hannemann on 15.11.14.
6 | // Copyright (c) 2014 Raffael Hannemann. All rights reserved.
7 | // Visit weAreYeah.com or follow @weareYeah for updates.
8 | //
9 | // Licensed under the BSD License
10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
11 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
12 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
13 | // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
15 | // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
16 | // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
17 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
18 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19 | //
20 |
21 | #import
22 |
23 | /** 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.
24 | Whenever it makes sense, the properties of your WAYWindow instance in Interface Builder are inspectable.
25 |
26 | Tips:
27 | - 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.
28 | - Also check out the new APIs in NSScrollView to make use of contentInsets, scrollInsets, and more.
29 | */
30 | @interface WAYWindow : NSWindow
31 |
32 | /// Returns YES, if the class supports vibrant appearances. Can be used to determine if running on OS X 10.10+
33 | + (BOOL) supportsVibrantAppearances;
34 |
35 | /// Defines the window's titlebar height. Defaut: OS X default value.
36 | @property (nonatomic) IBInspectable CGFloat titleBarHeight;
37 |
38 | //// Returns the titlebar view of the window, which you can add arbitrary subviews to.
39 | @property (strong,readonly) IBOutlet NSView *titleBarView;
40 |
41 | /// If set to YES, the standard window button will be vertically centered. Default: YES.
42 | @property (nonatomic) IBInspectable BOOL centerTrafficLightButtons;
43 |
44 | /// Defines the left margin of the standard window buttons. Defaut: OS X default value.
45 | @property (nonatomic) IBInspectable CGFloat trafficLightButtonsLeftMargin;
46 |
47 | /// Defines the top margin of the standard window buttons. Used if not centered. Defaut: OS X default value.
48 | @property (nonatomic) IBInspectable CGFloat trafficLightButtonsTopMargin;
49 |
50 | /// If set to YES, the title of the window will be hidden. Default: YES.
51 | @property (nonatomic) IBInspectable BOOL hidesTitle;
52 |
53 | /// 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.
54 | - (void) setContentViewAppearanceVibrantDark;
55 |
56 | /// 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.
57 | - (void) setContentViewAppearanceVibrantLight;
58 |
59 | /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantDark
60 | - (void) setVibrantDarkAppearance;
61 |
62 | /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantLight
63 | - (void) setVibrantLightAppearance;
64 |
65 | /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantAqua
66 | - (void) setAquaAppearance;
67 |
68 | /// 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.
69 | - (void) replaceSubview: (NSView *) aView withView: (NSView *) newView resizing: (BOOL) flag;
70 |
71 | /// 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.
72 | - (NSView *) replaceSubview: (NSView *) aView withViewOfClass: (Class) newViewClass;
73 |
74 | /// Returns YES if the window is currently in full-screen.
75 | - (BOOL) isFullScreen;
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/Inbox for Mac.xcodeproj/xcuserdata/amonk.xcuserdatad/xcschemes/Inbox for Mac.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
75 |
77 |
83 |
84 |
85 |
86 |
87 |
88 |
94 |
96 |
102 |
103 |
104 |
105 |
107 |
108 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/Inbox for Mac/Extensions/INWindowBackgroundView+CoreUIRendering.m:
--------------------------------------------------------------------------------
1 | //
2 | // INWindowBackgroundView+CoreUIRendering.m
3 | //
4 | // Copyright (c) 2014 Petroules Corporation. All rights reserved.
5 | //
6 | // Licensed under the BSD 2-clause License. See LICENSE file distributed in the source
7 | // code of this project.
8 | //
9 |
10 | #import "INAppStoreWindow.h"
11 | #import "INAppStoreWindowCompatibility.h"
12 | #import "INAppStoreWindowSwizzling.h"
13 | #import "INWindowBackgroundView+CoreUIRendering.h"
14 | #import
15 |
16 | #if !defined(INAPPSTOREWINDOW_NO_COREUI) || !INAPPSTOREWINDOW_NO_COREUI
17 |
18 | typedef CFTypeRef CUIRendererRef;
19 | typedef void (*_CUIDraw)(CUIRendererRef renderer, CGRect frame, CGContextRef context, CFDictionaryRef options, CFDictionaryRef *result);
20 | static _CUIDraw CUIDraw = 0;
21 |
22 | static NSString * const kCUIIsFlippedKey = @"is.flipped";
23 | static NSString * const kCUIStateActive = @"normal";
24 | static NSString * const kCUIStateInactive = @"inactive";
25 | static NSString * const kCUIStateKey = @"state";
26 | static NSString * const kCUIWidgetKey = @"widget";
27 | static NSString * const kCUIWidgetWindowBottomBar = @"kCUIWidgetWindowBottomBar";
28 | static NSString * const kCUIWidgetWindowFrame = @"kCUIWidgetWindowFrame";
29 | static NSString * const kCUIWindowFrameBottomBarHeightKey = @"kCUIWindowFrameBottomBarHeightKey";
30 | static NSString * const kCUIWindowFrameDrawBottomBarSeparatorKey = @"kCUIWindowFrameDrawBottomBarSeparatorKey";
31 | static NSString * const kCUIWindowFrameDrawTitleSeparatorKey = @"kCUIWindowFrameDrawTitleSeparatorKey";
32 | static NSString * const kCUIWindowFrameRoundedBottomCornersKey = @"kCUIWindowFrameRoundedBottomCornersKey";
33 | static NSString * const kCUIWindowFrameRoundedTopCornersKey = @"kCUIWindowFrameRoundedTopCornersKey";
34 | static NSString * const kCUIWindowFrameUnifiedTitleBarHeightKey = @"kCUIWindowFrameUnifiedTitleBarHeightKey";
35 | static NSString * const kCUIWindowTypeDocument = @"regularwin";
36 | static NSString * const kCUIWindowTypeKey = @"windowtype";
37 |
38 | @interface NSWindow (NSWindowPrivate)
39 |
40 | + (CUIRendererRef)coreUIRenderer;
41 |
42 | @end
43 |
44 | @interface /* NSAppearance */ NSObject (NSAppearancePrivate)
45 |
46 | - (void)_drawInRect:(CGRect)rect context:(CGContextRef)cgContext options:(CFDictionaryRef)options;
47 |
48 | @end
49 |
50 | @interface INWindowBackgroundView ()
51 |
52 | - (void)drawWindowBackgroundLayersInRect:(NSRect)drawingRect forEdge:(NSRectEdge)drawingEdge showsSeparator:(BOOL)showsSeparator clippingPath:(CGPathRef)clippingPath;
53 |
54 | @end
55 |
56 | #endif // !defined(INAPPSTOREWINDOW_NO_COREUI) || !INAPPSTOREWINDOW_NO_COREUI
57 |
58 | @implementation INWindowBackgroundView (CoreUIRendering)
59 |
60 | #if !defined(INAPPSTOREWINDOW_NO_COREUI) || !INAPPSTOREWINDOW_NO_COREUI
61 |
62 | + (void)load
63 | {
64 | CFBundleRef bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.coreui"));
65 | if ((CUIDraw = CFBundleGetFunctionPointerForName(bundle, CFSTR("CUIDraw"))) &&
66 | [NSWindow respondsToSelector:@selector(coreUIRenderer)]) {
67 | INAppStoreWindowSwizzle(self,
68 | @selector(drawWindowBackgroundLayersInRect:forEdge:showsSeparator:clippingPath:),
69 | @selector(drawCUIWindowBackgroundLayersInRect:forEdge:showsSeparator:clippingPath:));
70 |
71 | [self loadConstant:&kCUIIsFlippedKey named:@"kCUIIsFlippedKey" fromBundle:bundle];
72 | [self loadConstant:&kCUIStateActive named:@"kCUIStateActive" fromBundle:bundle];
73 | [self loadConstant:&kCUIStateInactive named:@"kCUIStateInactive" fromBundle:bundle];
74 | [self loadConstant:&kCUIStateKey named:@"kCUIStateKey" fromBundle:bundle];
75 | [self loadConstant:&kCUIWidgetKey named:@"kCUIWidgetKey" fromBundle:bundle];
76 | [self loadConstant:&kCUIWidgetWindowBottomBar named:@"kCUIWidgetWindowBottomBar" fromBundle:bundle];
77 | [self loadConstant:&kCUIWidgetWindowFrame named:@"kCUIWidgetWindowFrame" fromBundle:bundle];
78 | [self loadConstant:&kCUIWindowFrameBottomBarHeightKey named:@"kCUIWindowFrameBottomBarHeightKey" fromBundle:bundle];
79 | [self loadConstant:&kCUIWindowFrameDrawBottomBarSeparatorKey named:@"kCUIWindowFrameDrawBottomBarSeparatorKey" fromBundle:bundle];
80 | [self loadConstant:&kCUIWindowFrameDrawTitleSeparatorKey named:@"kCUIWindowFrameDrawTitleSeparatorKey" fromBundle:bundle];
81 | [self loadConstant:&kCUIWindowFrameRoundedBottomCornersKey named:@"kCUIWindowFrameRoundedBottomCornersKey" fromBundle:bundle];
82 | [self loadConstant:&kCUIWindowFrameRoundedTopCornersKey named:@"kCUIWindowFrameRoundedTopCornersKey" fromBundle:bundle];
83 | [self loadConstant:&kCUIWindowFrameUnifiedTitleBarHeightKey named:@"kCUIWindowFrameUnifiedTitleBarHeightKey" fromBundle:bundle];
84 | [self loadConstant:&kCUIWindowTypeDocument named:@"kCUIWindowTypeDocument" fromBundle:bundle];
85 | [self loadConstant:&kCUIWindowTypeKey named:@"kCUIWindowTypeKey" fromBundle:bundle];
86 | } else {
87 | NSLog(@"Failed to load CoreUI, falling back to custom drawing");
88 | }
89 | }
90 |
91 | + (void)loadConstant:(NSString * const *)constant named:(NSString *)constantName fromBundle:(CFBundleRef)bundle
92 | {
93 | NSString * const *_constant = (NSString * const *)(CFBundleGetDataPointerForName(bundle, (__bridge CFStringRef)(constantName)));
94 | if (_constant) {
95 | *((NSString **)constant) = *_constant;
96 | } else {
97 | NSLog(@"Failed to load %@, using fallback value %@", constantName, *constant);
98 | }
99 | }
100 |
101 | - (void)drawCUIWindowBackgroundLayersInRect:(CGRect)drawingRect forEdge:(CGRectEdge)edge showsSeparator:(BOOL)showsSeparator clippingPath:(CGPathRef)clippingPath
102 | {
103 | INAppStoreWindow *window = (INAppStoreWindow *)self.window;
104 | NSMutableDictionary *options = [NSMutableDictionary dictionaryWithDictionary:
105 | @{kCUIStateKey: (window.isMainWindow ? kCUIStateActive : kCUIStateInactive),
106 | kCUIWidgetKey: kCUIWidgetWindowFrame,
107 | kCUIWindowTypeKey: kCUIWindowTypeDocument,
108 | kCUIIsFlippedKey: @(self.isFlipped)}];
109 | if (edge == CGRectMaxYEdge) {
110 | options[kCUIWindowFrameUnifiedTitleBarHeightKey] = @(window.titleBarHeight + window.toolbarHeight);
111 | options[kCUIWindowFrameDrawTitleSeparatorKey] = @(showsSeparator);
112 | options[kCUIWindowFrameRoundedBottomCornersKey] = @(NO);
113 | options[kCUIWindowFrameRoundedTopCornersKey] = @(YES);
114 | } else if (edge == CGRectMinYEdge) {
115 | // NOTE: While kCUIWidgetWindowBottomBar can be used to draw a bottom bar, this only allows
116 | // it to be drawn with the separator shown as kCUIWindowFrameDrawBottomBarSeparatorKey only
117 | // applies to the kCUIWidgetWindowFrame widget. So we use that instead; it produces
118 | // identical results... except in Yosemite where the other options work correctly.
119 | if (INRunningYosemite()) {
120 | options[kCUIWidgetKey] = kCUIWidgetWindowBottomBar;
121 | }
122 | options[kCUIWindowFrameBottomBarHeightKey] = @(window.bottomBarHeight);
123 | options[kCUIWindowFrameDrawBottomBarSeparatorKey] = @(showsSeparator);
124 | options[kCUIWindowFrameRoundedBottomCornersKey] = @(YES);
125 | options[kCUIWindowFrameRoundedTopCornersKey] = @(NO);
126 | }
127 |
128 | id appearance = nil;
129 | if (INRunningMavericks()) {
130 | Class clazz = NSClassFromString(@"NSAppearance");
131 | if ([clazz respondsToSelector:@selector(currentAppearance)]) {
132 | appearance = [clazz performSelector:@selector(currentAppearance)];
133 | }
134 | }
135 |
136 | if ([appearance respondsToSelector:@selector(_drawInRect:context:options:)]) {
137 | [appearance _drawInRect:drawingRect context:[[NSGraphicsContext currentContext] graphicsPort] options:(__bridge CFDictionaryRef)options];
138 | } else {
139 | CUIDraw([NSWindow coreUIRenderer], drawingRect, [[NSGraphicsContext currentContext] graphicsPort], (__bridge CFDictionaryRef) options, nil);
140 | }
141 | }
142 |
143 | #endif // !defined(INAPPSTOREWINDOW_NO_COREUI) || !INAPPSTOREWINDOW_NO_COREUI
144 |
145 | @end
146 |
--------------------------------------------------------------------------------
/Inbox for Mac/INWindowButton.m:
--------------------------------------------------------------------------------
1 | //
2 | // INWindowButton.m
3 | //
4 | // Copyright 2013-2014 Vladislav Alexeev. All rights reserved.
5 | //
6 | // Licensed under the BSD 2-clause License. See LICENSE file distributed in the source
7 | // code of this project.
8 | //
9 |
10 | #import "INAppStoreWindowCompatibility.h"
11 | #import "INWindowButton.h"
12 |
13 | #pragma mark - Window Button Group
14 |
15 | NSString *const INWindowButtonGroupDidUpdateRolloverStateNotification = @"INWindowButtonGroupDidUpdateRolloverStateNotification";
16 | NSString *const kINWindowButtonGroupDefault = @"com.indragie.inappstorewindow.defaultWindowButtonGroup";
17 |
18 | @interface INWindowButtonGroup : NSObject
19 |
20 | + (instancetype)groupWithIdentifier:(NSString *)identifier;
21 | @property (nonatomic, copy, readonly) NSString *identifier;
22 |
23 | - (void)didCaptureMousePointer;
24 | - (void)didReleaseMousePointer;
25 | - (BOOL)shouldDisplayRollOver;
26 |
27 | - (void)resetMouseCaptures;
28 |
29 | @end
30 |
31 | @interface INWindowButtonGroup ()
32 | @property (nonatomic, assign) NSInteger numberOfCaptures;
33 | @end
34 |
35 | @implementation INWindowButtonGroup
36 |
37 | + (instancetype)groupWithIdentifier:(NSString *)identifier
38 | {
39 | static NSMutableDictionary *groups = nil;
40 | if (groups == nil) {
41 | groups = [[NSMutableDictionary alloc] init];
42 | }
43 |
44 | if (identifier == nil) {
45 | identifier = kINWindowButtonGroupDefault;
46 | }
47 |
48 | INWindowButtonGroup *group = groups[identifier];
49 | if (group == nil) {
50 | group = [[[self class] alloc] initWithIdentifier:identifier];
51 | groups[identifier] = group;
52 | }
53 | return group;
54 | }
55 |
56 | - (instancetype)initWithIdentifier:(NSString *)identifier
57 | {
58 | self = [super init];
59 | if (self) {
60 | _identifier = [identifier copy];
61 | }
62 | return self;
63 | }
64 |
65 | - (void)setNumberOfCaptures:(NSInteger)numberOfCaptures
66 | {
67 | if (_numberOfCaptures != numberOfCaptures && numberOfCaptures >= 0) {
68 | _numberOfCaptures = numberOfCaptures;
69 | [[NSNotificationCenter defaultCenter] postNotificationName:INWindowButtonGroupDidUpdateRolloverStateNotification
70 | object:self];
71 | }
72 | }
73 |
74 | - (void)didCaptureMousePointer
75 | {
76 | self.numberOfCaptures++;
77 | }
78 |
79 | - (void)didReleaseMousePointer
80 | {
81 | self.numberOfCaptures--;
82 | }
83 |
84 | - (BOOL)shouldDisplayRollOver
85 | {
86 | return (self.numberOfCaptures > 0);
87 | }
88 |
89 | - (void)resetMouseCaptures
90 | {
91 | self.numberOfCaptures = 0;
92 | }
93 |
94 | @end
95 |
96 | #pragma mark - Window Button
97 |
98 | @interface INWindowButton ()
99 | @property (nonatomic, copy) NSString *groupIdentifier;
100 | @property (nonatomic, strong, readonly) INWindowButtonGroup *group;
101 | @property (nonatomic, strong) NSTrackingArea *mouseTrackingArea;
102 |
103 | @end
104 |
105 | @implementation INWindowButton
106 |
107 | + (instancetype)windowButtonWithSize:(NSSize)size groupIdentifier:(NSString *)groupIdentifier
108 | {
109 | INWindowButton *button = [[self alloc] initWithSize:size groupIdentifier:groupIdentifier];
110 | return button;
111 | }
112 |
113 | #pragma mark - Init and Dealloc
114 |
115 | - (instancetype)initWithSize:(NSSize)size groupIdentifier:(NSString *)groupIdentifier
116 | {
117 | self = [super initWithFrame:NSMakeRect(0, 0, size.width, size.height)];
118 | if (self) {
119 | _groupIdentifier = [groupIdentifier copy];
120 | [self setButtonType:NSMomentaryChangeButton];
121 | [self setBordered:NO];
122 | [self setTitle:@""];
123 | [self.cell setHighlightsBy:NSContentsCellMask];
124 | [self.cell setImageDimsWhenDisabled:NO];
125 |
126 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowButtonGroupDidUpdateRolloverStateNotification:) name:INWindowButtonGroupDidUpdateRolloverStateNotification object:self.group];
127 | }
128 | return self;
129 | }
130 |
131 | - (void)dealloc
132 | {
133 | [[NSNotificationCenter defaultCenter] removeObserver:self];
134 | }
135 |
136 | #pragma mark - Group
137 |
138 | - (INWindowButtonGroup *)group
139 | {
140 | return [INWindowButtonGroup groupWithIdentifier:self.groupIdentifier];
141 | }
142 |
143 | - (void)windowButtonGroupDidUpdateRolloverStateNotification:(NSNotification *)n
144 | {
145 | [self updateRollOverImage];
146 | }
147 |
148 | #pragma mark - Tracking Area
149 |
150 | - (void)updateTrackingAreas
151 | {
152 | [super updateTrackingAreas];
153 |
154 | if (self.mouseTrackingArea) {
155 | [self removeTrackingArea:self.mouseTrackingArea];
156 | }
157 |
158 | NSTrackingArea *mouseTrackingArea = [[NSTrackingArea alloc] initWithRect:NSInsetRect(self.bounds, -4, -4)
159 | options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways
160 | owner:self
161 | userInfo:nil];
162 |
163 | [self addTrackingArea:self.mouseTrackingArea = mouseTrackingArea];
164 | }
165 |
166 | #pragma mark - Window State Handling
167 |
168 | - (void)viewDidMoveToWindow
169 | {
170 | if (self.window) {
171 | [self updateImage];
172 | }
173 | }
174 |
175 | - (void)viewWillMoveToWindow:(NSWindow *)newWindow
176 | {
177 | NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
178 | if (self.window) {
179 | [nc removeObserver:self name:NSWindowDidBecomeKeyNotification object:self.window];
180 | [nc removeObserver:self name:NSWindowDidResignKeyNotification object:self.window];
181 | [nc removeObserver:self name:NSWindowDidMiniaturizeNotification object:self.window];
182 | if ([NSWindow instancesRespondToSelector:@selector(toggleFullScreen:)]) {
183 | [nc removeObserver:self name:NSWindowWillEnterFullScreenNotification object:self.window];
184 | [nc removeObserver:self name:NSWindowWillExitFullScreenNotification object:self.window];
185 | }
186 | }
187 | if (newWindow != nil) {
188 | [nc addObserver:self selector:@selector(windowDidChangeFocus:) name:NSWindowDidBecomeKeyNotification object:newWindow];
189 | [nc addObserver:self selector:@selector(windowDidChangeFocus:) name:NSWindowDidResignKeyNotification object:newWindow];
190 | [nc addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:newWindow];
191 | if ([NSWindow instancesRespondToSelector:@selector(toggleFullScreen:)]) {
192 | [nc addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:newWindow];
193 | [nc addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:newWindow];
194 | }
195 | }
196 | }
197 |
198 | - (void)windowDidChangeFocus:(NSNotification *)n
199 | {
200 | [self updateImage];
201 | }
202 |
203 | - (void)windowWillEnterFullScreen:(NSNotification *)n
204 | {
205 | [self.group resetMouseCaptures];
206 | self.hidden = YES;
207 | }
208 |
209 | - (void)windowWillExitFullScreen:(NSNotification *)n
210 | {
211 | [self.group resetMouseCaptures];
212 | self.hidden = NO;
213 | }
214 |
215 | - (void)windowDidMiniaturize:(NSNotification *)notification
216 | {
217 | [self.group resetMouseCaptures];
218 | }
219 |
220 | #pragma mark - Event Handling
221 |
222 | - (void)viewDidEndLiveResize
223 | {
224 | [super viewDidEndLiveResize];
225 | [self.group resetMouseCaptures];
226 | }
227 |
228 | - (void)mouseEntered:(NSEvent *)theEvent
229 | {
230 | [super mouseEntered:theEvent];
231 | [self.group didCaptureMousePointer];
232 | [self updateRollOverImage];
233 | }
234 |
235 | - (void)mouseExited:(NSEvent *)theEvent
236 | {
237 | [super mouseExited:theEvent];
238 | [self.group didReleaseMousePointer];
239 | [self updateRollOverImage];
240 | }
241 |
242 | #pragma mark - Button Appearance
243 |
244 | - (void)setPressedImage:(NSImage *)pressedImage
245 | {
246 | self.alternateImage = pressedImage;
247 | }
248 |
249 | - (NSImage *)pressedImage
250 | {
251 | return self.alternateImage;
252 | }
253 |
254 | - (void)setEnabled:(BOOL)enabled
255 | {
256 | super.enabled = enabled;
257 | [self updateActiveImage];
258 | }
259 |
260 | - (void)updateRollOverImage
261 | {
262 | if (self.group.shouldDisplayRollOver && self.isEnabled) {
263 | self.image = self.rolloverImage;
264 | } else {
265 | [self updateImage];
266 | }
267 | }
268 |
269 | - (void)updateImage
270 | {
271 | if (self.window.isKeyWindow) {
272 | [self updateActiveImage];
273 | } else {
274 | self.image = self.activeNotKeyWindowImage;
275 | }
276 | }
277 |
278 | - (void)updateActiveImage
279 | {
280 | self.image = self.isEnabled ? self.activeImage : self.inactiveImage;
281 | }
282 |
283 | @end
284 |
--------------------------------------------------------------------------------
/Inbox for Mac/INAppStoreWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // INAppStoreWindow.h
3 | //
4 | // Copyright (c) 2011-2014 Indragie Karunaratne. All rights reserved.
5 | // Copyright (c) 2014 Petroules Corporation. All rights reserved.
6 | //
7 | // Licensed under the BSD 2-clause License. See LICENSE file distributed in the source
8 | // code of this project.
9 | //
10 |
11 | #import
12 |
13 | /**
14 | Height of a small bottom bar of a window. Currently, this is 22 points.
15 | */
16 | APPKIT_EXTERN const NSInteger kINAppStoreWindowSmallBottomBarHeight;
17 |
18 | /**
19 | Height of a large bottom bar of a window. Currently, this is 32 points.
20 | */
21 | APPKIT_EXTERN const NSInteger kINAppStoreWindowLargeBottomBarHeight;
22 |
23 | @class INWindowButton;
24 |
25 | /**
26 | * Draws default style OS X window backgrounds and separators.
27 | */
28 | @interface INWindowBackgroundView : NSView
29 |
30 | @end
31 |
32 | /**
33 | Draws a default style OS X title bar.
34 | */
35 | @interface INTitlebarView : INWindowBackgroundView
36 |
37 | @end
38 |
39 | /**
40 | Draws a default style OS X bottom bar.
41 | */
42 | @interface INBottomBarView : INWindowBackgroundView
43 |
44 | @end
45 |
46 | /**
47 | Creates a window similar to the Mac App Store window, with centered traffic lights and an
48 | enlarged title bar. This does not handle creating the toolbar.
49 | */
50 | @interface INAppStoreWindow : NSWindow
51 |
52 | /**
53 | Prototype for a block used to implement custom drawing code for a window's title bar or bottom bar.
54 | @param drawsAsMainWindow Whether the window should be drawn in main state.
55 | @param drawingRect Drawing area of the window's title bar.
56 | @param edge NSMinYEdge to draw a bottom bar, NSMaxYEdge to draw a title bar.
57 | @param clippingPath Path to clip drawing according to window's rounded corners.
58 | */
59 | typedef void (^INAppStoreWindowBackgroundDrawingBlock)(BOOL drawsAsMainWindow, CGRect drawingRect,
60 | CGRectEdge edge, CGPathRef clippingPath);
61 |
62 | /**
63 | The height of the title bar. By default, this is set to the standard title bar height.
64 | */
65 | @property (nonatomic) CGFloat titleBarHeight;
66 |
67 | /**
68 | Container view for custom views added to the title bar.
69 |
70 | Add subviews to this view that you want to show in the title bar (e.g. buttons, a toolbar, etc.).
71 | This view can also be set if you want to use a different style title bar from the default one
72 | (textured, etc.).
73 | */
74 | @property (nonatomic, strong) NSView *titleBarView;
75 |
76 | /**
77 | The height of the bottom bar. By default, this is set to 0.
78 | */
79 | @property (nonatomic) CGFloat bottomBarHeight;
80 |
81 | /**
82 | Container view for custom views added to the bottom bar.
83 |
84 | Add subviews to this view that you want to show in the bottom bar (e.g. labels, sliders, etc.).
85 | This view can also be set if you want to use a different style bottom bar from the default one
86 | (textured, etc.).
87 | */
88 | @property (nonatomic, strong) NSView *bottomBarView;
89 |
90 | /**
91 | Whether the fullscreen button is vertically centered.
92 | */
93 | @property (nonatomic) BOOL centerFullScreenButton;
94 |
95 | /**
96 | Whether the traffic light buttons are vertically centered.
97 | */
98 | @property (nonatomic) BOOL centerTrafficLightButtons;
99 |
100 | /**
101 | Whether the traffic light buttons are displayed in vertical orientation.
102 | */
103 | @property (nonatomic) BOOL verticalTrafficLightButtons;
104 |
105 | /**
106 | Whether the title is centered vertically.
107 | */
108 | @property (nonatomic) BOOL verticallyCenterTitle;
109 |
110 | /**
111 | Whether to hide the title bar in fullscreen mode.
112 | */
113 | @property (nonatomic) BOOL hideTitleBarInFullScreen;
114 |
115 | /**
116 | Whether to display the baseline separator between the window's title bar and content area.
117 | */
118 | @property (nonatomic) BOOL showsBaselineSeparator;
119 |
120 | /**
121 | Whether to display the bottom separator between the window's bottom bar and content area.
122 | */
123 | @property (nonatomic) BOOL showsBottomBarSeparator;
124 |
125 | /**
126 | Distance between the traffic light buttons and the left edge of the window.
127 | */
128 | @property (nonatomic) CGFloat trafficLightButtonsLeftMargin;
129 |
130 | /**
131 | * Distance between the traffic light buttons and the top edge of the window.
132 | */
133 | @property (nonatomic) CGFloat trafficLightButtonsTopMargin;
134 |
135 | /**
136 | Distance between the fullscreen button and the right edge of the window.
137 | */
138 | @property (nonatomic) CGFloat fullScreenButtonRightMargin;
139 |
140 | /**
141 | Distance between the fullscreen button and the top edge of the window.
142 | */
143 | @property (nonatomic) CGFloat fullScreenButtonTopMargin;
144 |
145 | /**
146 | Spacing between the traffic light buttons.
147 | */
148 | @property (nonatomic) CGFloat trafficLightSeparation;
149 |
150 | /**
151 | Number of points in any direction above which the window will be allowed to reposition.
152 | A Higher value indicates coarser movements but much reduced CPU overhead. Defaults to 1.
153 | */
154 | @property (nonatomic) CGFloat mouseDragDetectionThreshold;
155 |
156 | /**
157 | Whether to show the window's title text. If \c YES, the title will be shown even if
158 | \a titleBarDrawingBlock is set. To draw the title manually, set this property to \c NO
159 | and draw the title using \a titleBarDrawingBlock.
160 | */
161 | @property (nonatomic) BOOL showsTitle;
162 |
163 | /**
164 | Whether to show the window's title text in fullscreen mode.
165 | */
166 | @property (nonatomic) BOOL showsTitleInFullscreen;
167 |
168 | /**
169 | Whether the window displays the document proxy icon (for document-based applications).
170 | */
171 | @property (nonatomic) BOOL showsDocumentProxyIcon;
172 |
173 | /**
174 | The button to use as the window's close button.
175 | If this property is nil, the default button will be used.
176 | */
177 | @property (nonatomic, strong) INWindowButton *closeButton;
178 |
179 | /**
180 | The button to use as the window's minimize button.
181 | If this property is nil, the default button will be used.
182 | */
183 | @property (nonatomic, strong) INWindowButton *minimizeButton;
184 |
185 | /**
186 | The button to use as the window's zoom button.
187 | If this property is nil, the default button will be used.
188 | */
189 | @property (nonatomic, strong) INWindowButton *zoomButton;
190 |
191 | /**
192 | The button to use as the window's fullscreen button.
193 | If this property is nil, the default button will be used.
194 | */
195 | @property (nonatomic, strong) INWindowButton *fullScreenButton;
196 |
197 | /**
198 | The divider line between the window title and document versions button.
199 | */
200 | @property (nonatomic, readonly) NSTextField *titleDivider;
201 |
202 | /**
203 | The font used to draw the window's title text.
204 | */
205 | @property (nonatomic, strong) NSFont *titleFont;
206 |
207 | /**
208 | Gradient used to draw the window's title bar, when the window is main.
209 |
210 | If this property is \c nil, the system gradient will be used.
211 | */
212 | @property (nonatomic, strong) NSGradient *titleBarGradient;
213 |
214 | /**
215 | Gradient used to draw the window's bottom bar, when the window is main.
216 |
217 | If this property is \c nil, the system gradient will be used.
218 | */
219 | @property (nonatomic, strong) NSGradient *bottomBarGradient;
220 |
221 | /**
222 | Color of the separator line between a window's title bar and content area,
223 | when the window is main.
224 |
225 | If this property is \c nil, the default color will be used.
226 | */
227 | @property (nonatomic, strong) NSColor *baselineSeparatorColor;
228 |
229 | /**
230 | Color of the window's title text, when the window is main.
231 |
232 | If this property is \c nil, the default color will be used.
233 | */
234 | @property (nonatomic, strong) NSColor *titleTextColor;
235 |
236 | /**
237 | Drop shadow under the window's title text, when the window is main.
238 |
239 | If this property is \c nil, the default shadow will be used.
240 | */
241 | @property (nonatomic, strong) NSShadow *titleTextShadow;
242 |
243 | /**
244 | Gradient used to draw the window's title bar, when the window is not main.
245 |
246 | If this property is \c nil, the system gradient will be used.
247 | */
248 | @property (nonatomic, strong) NSGradient *inactiveTitleBarGradient;
249 |
250 | /**
251 | Gradient used to draw the window's bottom bar, when the window is not main.
252 |
253 | If this property is \c nil, the system gradient will be used.
254 | */
255 | @property (nonatomic, strong) NSGradient *inactiveBottomBarGradient;
256 |
257 | /**
258 | Color of the separator line between a window's title bar and content area,
259 | when the window is not main.
260 |
261 | If this property is \c nil, the default color will be used.
262 | */
263 | @property (nonatomic, strong) NSColor *inactiveBaselineSeparatorColor;
264 |
265 | /**
266 | Color of the window's title text, when the window is not main.
267 |
268 | If this property is \c nil, the default color will be used.
269 | */
270 | @property (nonatomic, strong) NSColor *inactiveTitleTextColor;
271 |
272 | /**
273 | Drop shadow under the window's title text, when the window is not main.
274 |
275 | If this property is \c nil, the default shadow will be used.
276 | */
277 | @property (nonatomic, strong) NSShadow *inactiveTitleTextShadow;
278 |
279 | /**
280 | Block to override the drawing of the window title bar with a custom implementation.
281 | */
282 | @property (nonatomic, copy) INAppStoreWindowBackgroundDrawingBlock titleBarDrawingBlock;
283 |
284 | /**
285 | Block to override the drawing of the window bottom bar with a custom implementation.
286 | */
287 | @property (nonatomic, copy) INAppStoreWindowBackgroundDrawingBlock bottomBarDrawingBlock;
288 |
289 | /**
290 | Whether to draw a noise pattern overlay on the title bar on OS X 10.7-10.9. This
291 | property has no effect when running on OS X 10.10 or higher.
292 | */
293 | @property (nonatomic) BOOL drawsTitlePatternOverlay;
294 |
295 | /*!
296 | Default system gradient used to draw a window's title bar.
297 | @param drawsAsMainWindow \c YES to return the gradient used when the window is drawn in its main
298 | state, \c NO to return the color used when the window is inactive.
299 |
300 | @note This gradient is identical to the one used by AppKit in OS X versions 10.7 through 10.9.
301 | For OS X 10.6 it is currently an approximation.
302 | */
303 | + (NSGradient *)defaultTitleBarGradient:(BOOL)drawsAsMainWindow;
304 |
305 | /*!
306 | Default system gradient used to draw a window's bottom bar.
307 | @param drawsAsMainWindow \c YES to return the gradient used when the window is drawn in its main
308 | state, \c NO to return the color used when the window is inactive.
309 | */
310 | + (NSGradient *)defaultBottomBarGradient:(BOOL)drawsAsMainWindow;
311 |
312 | /*!
313 | Default system color of the separator line between a window's title bar and content area.
314 | @param drawsAsMainWindow \c YES to return the color used when the window is drawn in its main
315 | state, \c NO to return the color used when the window is inactive.
316 |
317 | @note This color may be an approximation and is subject to change at any time.
318 | */
319 | + (NSColor *)defaultBaselineSeparatorColor:(BOOL)drawsAsMainWindow;
320 |
321 | /*!
322 | Default system color of a window's title text.
323 | @param drawsAsMainWindow \c YES to return the color used when the window is drawn in its main
324 | state, \c NO to return the color used when the window is inactive.
325 |
326 | @note This color may be an approximation and is subject to change at any time.
327 | */
328 | + (NSColor *)defaultTitleTextColor:(BOOL)drawsAsMainWindow;
329 |
330 | /**
331 | Sets the height of the title bar. By default, this is set to the standard title bar height.
332 |
333 | @param adjustWindowFrame Whether to adjust the window frame in response to the change in
334 | the title bar height. By default, the window frame is adjusted when the title bar height
335 | is changed.
336 | */
337 | - (void)setTitleBarHeight:(CGFloat)titleBarHeight adjustWindowFrame:(BOOL)adjustWindowFrame;
338 |
339 | /**
340 | Returns the height of the window's NSToolbar. If the window has no NSToolbar, or if it's not visible, returns 0.
341 | */
342 | - (CGFloat)toolbarHeight;
343 |
344 | @end
345 |
--------------------------------------------------------------------------------
/Inbox for Mac/WAYAppStoreWindow.h:
--------------------------------------------------------------------------------
1 | //
2 | // WAYAppStoreWindow.h
3 | // WAYAppStoreWindow
4 | //
5 | // Created by Raffael Hannemann on 15.11.14.
6 | // Copyright (c) 2014 Raffael Hannemann. All rights reserved.
7 | // Visit weAreYeah.com or follow @weareYeah for updates.
8 | //
9 | // Licensed under the BSD License
10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
11 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
12 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
13 | // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
15 | // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
16 | // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
17 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
18 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19 | //
20 |
21 | // Please note: lots of the following code is copied from INAppStoreWindow by Indragie Karunaratne, et al.
22 |
23 | #import
24 |
25 | @class INWindowButton;
26 |
27 | /** This NSWindow subclass allows you to use create NSWindow that provide INAppStoreWindow like capabilities. The class switches between either WAYWindow or INAppStoreWindow at runtime based on the OS version. The way it is done is kind of experimental and currently only basic functionality of the original INAppStoreWindow is supported. Lots of INAppStoreWindow's properties probably do not work. Basically, only the functions that WAYWindow is implementing, are currently supported.
28 | */
29 | @interface WAYAppStoreWindow : NSWindow
30 |
31 | /** Note: The following properties are shamelessly copied from INAppStoreWindow. All credits to the author. We need to copy these properties here in order to get the same ivar layout in the class façade class. Please note that not all of the listed properties have an effect on OS X Yosemite, where WAYWindow will be used internally. */
32 |
33 | /**
34 | Prototype for a block used to implement custom drawing code for a window's title bar or bottom bar.
35 | @param drawsAsMainWindow Whether the window should be drawn in main state.
36 | @param drawingRect Drawing area of the window's title bar.
37 | @param edge NSMinYEdge to draw a bottom bar, NSMaxYEdge to draw a title bar.
38 | @param clippingPath Path to clip drawing according to window's rounded corners.
39 | */
40 | typedef void (^INAppStoreWindowBackgroundDrawingBlock)(BOOL drawsAsMainWindow, CGRect drawingRect,
41 | CGRectEdge edge, CGPathRef clippingPath);
42 |
43 | /**
44 | The height of the title bar. By default, this is set to the standard title bar height.
45 | */
46 | @property (nonatomic) CGFloat titleBarHeight;
47 |
48 | /**
49 | Container view for custom views added to the title bar.
50 |
51 | Add subviews to this view that you want to show in the title bar (e.g. buttons, a toolbar, etc.).
52 | This view can also be set if you want to use a different style title bar from the default one
53 | (textured, etc.).
54 | */
55 | @property (nonatomic, strong) NSView *titleBarView;
56 |
57 | /**
58 | The height of the bottom bar. By default, this is set to 0.
59 | */
60 | @property (nonatomic) CGFloat bottomBarHeight;
61 |
62 | /**
63 | Container view for custom views added to the bottom bar.
64 |
65 | Add subviews to this view that you want to show in the bottom bar (e.g. labels, sliders, etc.).
66 | This view can also be set if you want to use a different style bottom bar from the default one
67 | (textured, etc.).
68 | */
69 | @property (nonatomic, strong) NSView *bottomBarView;
70 |
71 | /**
72 | Whether the fullscreen button is vertically centered.
73 | */
74 | @property (nonatomic) BOOL centerFullScreenButton;
75 |
76 | /**
77 | Whether the traffic light buttons are vertically centered.
78 | */
79 | @property (nonatomic) BOOL centerTrafficLightButtons;
80 |
81 | /**
82 | Whether the traffic light buttons are displayed in vertical orientation.
83 | */
84 | @property (nonatomic) BOOL verticalTrafficLightButtons;
85 |
86 | /**
87 | Whether the title is centered vertically.
88 | */
89 | @property (nonatomic) BOOL verticallyCenterTitle;
90 |
91 | /**
92 | Whether to hide the title bar in fullscreen mode.
93 | */
94 | @property (nonatomic) BOOL hideTitleBarInFullScreen;
95 |
96 | /**
97 | Whether to display the baseline separator between the window's title bar and content area.
98 | */
99 | @property (nonatomic) BOOL showsBaselineSeparator;
100 |
101 | /**
102 | Whether to display the bottom separator between the window's bottom bar and content area.
103 | */
104 | @property (nonatomic) BOOL showsBottomBarSeparator;
105 |
106 | /**
107 | Distance between the traffic light buttons and the left edge of the window.
108 | */
109 | @property (nonatomic) CGFloat trafficLightButtonsLeftMargin;
110 |
111 | /**
112 | * Distance between the traffic light buttons and the top edge of the window.
113 | */
114 | @property (nonatomic) CGFloat trafficLightButtonsTopMargin;
115 |
116 | /**
117 | Distance between the fullscreen button and the right edge of the window.
118 | */
119 | @property (nonatomic) CGFloat fullScreenButtonRightMargin;
120 |
121 | /**
122 | Distance between the fullscreen button and the top edge of the window.
123 | */
124 | @property (nonatomic) CGFloat fullScreenButtonTopMargin;
125 |
126 | /**
127 | Spacing between the traffic light buttons.
128 | */
129 | @property (nonatomic) CGFloat trafficLightSeparation;
130 |
131 | /**
132 | Number of points in any direction above which the window will be allowed to reposition.
133 | A Higher value indicates coarser movements but much reduced CPU overhead. Defaults to 1.
134 | */
135 | @property (nonatomic) CGFloat mouseDragDetectionThreshold;
136 |
137 | /**
138 | Whether to show the window's title text. If \c YES, the title will be shown even if
139 | \a titleBarDrawingBlock is set. To draw the title manually, set this property to \c NO
140 | and draw the title using \a titleBarDrawingBlock.
141 | */
142 | @property (nonatomic) BOOL showsTitle;
143 |
144 | /**
145 | Whether to show the window's title text in fullscreen mode.
146 | */
147 | @property (nonatomic) BOOL showsTitleInFullscreen;
148 |
149 | /**
150 | Whether the window displays the document proxy icon (for document-based applications).
151 | */
152 | @property (nonatomic) BOOL showsDocumentProxyIcon;
153 |
154 | /**
155 | The button to use as the window's close button.
156 | If this property is nil, the default button will be used.
157 | */
158 | @property (nonatomic, strong) INWindowButton *closeButton;
159 |
160 | /**
161 | The button to use as the window's minimize button.
162 | If this property is nil, the default button will be used.
163 | */
164 | @property (nonatomic, strong) INWindowButton *minimizeButton;
165 |
166 | /**
167 | The button to use as the window's zoom button.
168 | If this property is nil, the default button will be used.
169 | */
170 | @property (nonatomic, strong) INWindowButton *zoomButton;
171 |
172 | /**
173 | The button to use as the window's fullscreen button.
174 | If this property is nil, the default button will be used.
175 | */
176 | @property (nonatomic, strong) INWindowButton *fullScreenButton;
177 |
178 | /**
179 | The divider line between the window title and document versions button.
180 | */
181 | @property (nonatomic, readonly) NSTextField *titleDivider;
182 |
183 | /**
184 | The font used to draw the window's title text.
185 | */
186 | @property (nonatomic, strong) NSFont *titleFont;
187 |
188 | /**
189 | Gradient used to draw the window's title bar, when the window is main.
190 |
191 | If this property is \c nil, the system gradient will be used.
192 | */
193 | @property (nonatomic, strong) NSGradient *titleBarGradient;
194 |
195 | /**
196 | Gradient used to draw the window's bottom bar, when the window is main.
197 |
198 | If this property is \c nil, the system gradient will be used.
199 | */
200 | @property (nonatomic, strong) NSGradient *bottomBarGradient;
201 |
202 | /**
203 | Color of the separator line between a window's title bar and content area,
204 | when the window is main.
205 |
206 | If this property is \c nil, the default color will be used.
207 | */
208 | @property (nonatomic, strong) NSColor *baselineSeparatorColor;
209 |
210 | /**
211 | Color of the window's title text, when the window is main.
212 |
213 | If this property is \c nil, the default color will be used.
214 | */
215 | @property (nonatomic, strong) NSColor *titleTextColor;
216 |
217 | /**
218 | Drop shadow under the window's title text, when the window is main.
219 |
220 | If this property is \c nil, the default shadow will be used.
221 | */
222 | @property (nonatomic, strong) NSShadow *titleTextShadow;
223 |
224 | /**
225 | Gradient used to draw the window's title bar, when the window is not main.
226 |
227 | If this property is \c nil, the system gradient will be used.
228 | */
229 | @property (nonatomic, strong) NSGradient *inactiveTitleBarGradient;
230 |
231 | /**
232 | Gradient used to draw the window's bottom bar, when the window is not main.
233 |
234 | If this property is \c nil, the system gradient will be used.
235 | */
236 | @property (nonatomic, strong) NSGradient *inactiveBottomBarGradient;
237 |
238 | /**
239 | Color of the separator line between a window's title bar and content area,
240 | when the window is not main.
241 |
242 | If this property is \c nil, the default color will be used.
243 | */
244 | @property (nonatomic, strong) NSColor *inactiveBaselineSeparatorColor;
245 |
246 | /**
247 | Color of the window's title text, when the window is not main.
248 |
249 | If this property is \c nil, the default color will be used.
250 | */
251 | @property (nonatomic, strong) NSColor *inactiveTitleTextColor;
252 |
253 | /**
254 | Drop shadow under the window's title text, when the window is not main.
255 |
256 | If this property is \c nil, the default shadow will be used.
257 | */
258 | @property (nonatomic, strong) NSShadow *inactiveTitleTextShadow;
259 |
260 | /**
261 | Block to override the drawing of the window title bar with a custom implementation.
262 | */
263 | @property (nonatomic, copy) INAppStoreWindowBackgroundDrawingBlock titleBarDrawingBlock;
264 |
265 | /**
266 | Block to override the drawing of the window bottom bar with a custom implementation.
267 | */
268 | @property (nonatomic, copy) INAppStoreWindowBackgroundDrawingBlock bottomBarDrawingBlock;
269 |
270 | /**
271 | Whether to draw a noise pattern overlay on the title bar on OS X 10.7-10.9. This
272 | property has no effect when running on OS X 10.10 or higher.
273 | */
274 | @property (nonatomic) BOOL drawsTitlePatternOverlay;
275 |
276 | @end
277 |
278 |
279 | @interface WAYAppStoreWindow (WAYWindowAdditionalInterfaces)
280 |
281 | /// Returns YES, if the class supports vibrant appearances. Can be used to determine if running on OS X 10.10+
282 | + (BOOL) supportsVibrantAppearances;
283 | /// If set to YES, the title of the window will be hidden.
284 | @property (nonatomic) IBInspectable BOOL hidesTitle;
285 |
286 | /// 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.
287 | - (void) setContentViewAppearanceVibrantDark;
288 |
289 | /// 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.
290 | - (void) setContentViewAppearanceVibrantLight;
291 |
292 | /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantDark
293 | - (void) setVibrantDarkAppearance;
294 |
295 | /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantLight
296 | - (void) setVibrantLightAppearance;
297 |
298 | /// Convenient method to set the NSAppearance of the window to NSAppearanceNameVibrantAqua
299 | - (void) setAquaAppearance;
300 |
301 | /// 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.
302 | - (void) replaceSubview: (NSView *) aView withView: (NSView *) newView resizing: (BOOL) flag;
303 |
304 | /// 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.
305 | - (NSView *) replaceSubview: (NSView *) aView withViewOfClass: (Class) newViewClass;
306 |
307 | /// Returns YES if the window is currently in full-screen.
308 | - (BOOL) isFullScreen;
309 |
310 | @end
--------------------------------------------------------------------------------
/Inbox for Mac/WAYWindow.m:
--------------------------------------------------------------------------------
1 | //
2 | // WAYWindow.m
3 | // WAYWindow
4 | //
5 | // Created by Raffael Hannemann on 15.11.14.
6 | // Copyright (c) 2014 Raffael Hannemann. All rights reserved.
7 | // Visit weAreYeah.com or follow @weareYeah for updates.
8 | //
9 | // Licensed under the BSD License
10 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
11 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
12 | // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
13 | // SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
15 | // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
16 | // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
17 | // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
18 | // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19 | //
20 |
21 | #import "WAYWindow.h"
22 |
23 | /**
24 | Convenience methods to make NSPointerArray act like a stack of selectors. It would be a subclass, but NSPointerArray
25 | is a class cluster and doesn't really like being subclassed.
26 | */
27 | #pragma mark - WAY_SelectorStack
28 | @interface NSPointerArray (WAY_SelectorStack)
29 | - (instancetype)initWAYSelectorStack;
30 | - (BOOL)way_containsSelector:(SEL)aSelector;
31 | - (void)way_pushSelector:(SEL)aSelector;
32 | - (SEL)way_pop;
33 | @end
34 |
35 | @implementation NSPointerArray (WAY_SelectorStack)
36 | - (instancetype)initWAYSelectorStack {
37 | NSPointerFunctions *pointerFunctions = [NSPointerFunctions pointerFunctionsWithOptions:(NSPointerFunctionsOpaqueMemory |
38 | NSPointerFunctionsOpaquePersonality)];
39 | self = [self initWithPointerFunctions:pointerFunctions];
40 | return self;
41 | }
42 |
43 | - (BOOL)way_containsSelector:(SEL)aSelector {
44 | NSInteger count = self.count;
45 | for (NSInteger i=0; i
71 | @property (nonatomic, weak) id secondaryDelegate;
72 | @property (nonatomic, weak) id firstDelegate;
73 | @end
74 |
75 | /** 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. */
76 | #pragma mark - WAYWindowDelegateProxy
77 | @implementation WAYWindowDelegateProxy {
78 | NSPointerArray *_selectorStack;
79 | }
80 |
81 | - (instancetype)init {
82 | _selectorStack = [[NSPointerArray alloc] initWAYSelectorStack];
83 | return self;
84 | }
85 |
86 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
87 | NSMethodSignature *signature = [[self.firstDelegate class] instanceMethodSignatureForSelector:selector];
88 | if (!signature) {
89 | signature = [[self.secondaryDelegate class] instanceMethodSignatureForSelector:selector];
90 | if (!signature) {
91 | signature = [super methodSignatureForSelector:selector];
92 | }
93 | }
94 | return signature;
95 | }
96 |
97 | - (BOOL)respondsToSelector:(SEL)aSelector {
98 | if (aSelector==@selector(windowDidResize:)) {
99 | return YES;
100 | } else if ([self.secondaryDelegate respondsToSelector:aSelector]) {
101 | return YES;
102 | } else {
103 | return NO;
104 | }
105 | }
106 |
107 | - (void)forwardInvocation:(NSInvocation *)anInvocation {
108 | SEL selector = anInvocation.selector;
109 | if ([_selectorStack way_containsSelector:selector]) {
110 | // We're already in the middle of forwarding this selector; stop the infinite recursion right here.
111 | return;
112 | }
113 |
114 | [_selectorStack way_pushSelector:selector];
115 | {
116 | if ([self.firstDelegate respondsToSelector:selector]) {
117 | [anInvocation invokeWithTarget:self.firstDelegate];
118 | }
119 | if ([self.secondaryDelegate respondsToSelector:selector]) {
120 | [anInvocation invokeWithTarget:self.secondaryDelegate];
121 | }
122 | }
123 | [_selectorStack way_pop];
124 | }
125 |
126 | - (BOOL)isKindOfClass:(Class)aClass {
127 | if (self.secondaryDelegate) {
128 | return [self.secondaryDelegate isKindOfClass:aClass];
129 | }
130 | return NO;
131 | }
132 | @end
133 |
134 |
135 | #pragma mark - WAYWindow
136 | @interface WAYWindow ()
137 | @property (strong) WAYWindowDelegateProxy* delegateProxy;
138 | @property (strong) NSArray* standardButtons;
139 | @property (strong) NSTitlebarAccessoryViewController *dummyTitlebarAccessoryViewController;
140 |
141 | @end
142 |
143 | static float kWAYWindowDefaultTrafficLightButtonsLeftMargin = 0;
144 | static float kWAYWindowDefaultTrafficLightButtonsTopMargin = 0;
145 |
146 | @implementation WAYWindow
147 |
148 | + (BOOL) supportsVibrantAppearances {
149 | return (NSClassFromString(@"NSVisualEffectView")!=nil);
150 | }
151 |
152 | + (float) defaultTitleBarHeight {
153 | NSRect frame = NSMakeRect(0, 0, 800, 600);
154 | NSRect contentRect = [NSWindow contentRectForFrameRect:frame styleMask: NSTitledWindowMask];
155 | return NSHeight(frame) - NSHeight(contentRect);
156 | }
157 |
158 | #pragma mark - NSWindow Overwritings
159 |
160 | - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {
161 | if ((self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag])) {
162 | [self _setUp];
163 | }
164 | return self;
165 | }
166 |
167 | - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)screen {
168 | if ((self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag screen:screen])) {
169 | [self _setUp];
170 | }
171 | return self;
172 | }
173 |
174 | - (void) setDelegate:(id)delegate {
175 | [_delegateProxy setSecondaryDelegate:delegate];
176 | [super setDelegate:nil];
177 | [super setDelegate:_delegateProxy];
178 | }
179 |
180 | - (id) delegate {
181 | return [_delegateProxy secondaryDelegate];
182 | }
183 |
184 | - (void) setFrame:(NSRect)frameRect display:(BOOL)flag {
185 | [super setFrame:frameRect display:flag];
186 | [self _setNeedsLayout];
187 | }
188 |
189 | - (void) restoreStateWithCoder:(NSCoder *)coder {
190 | [super restoreStateWithCoder:coder];
191 | [self _setNeedsLayout];
192 | }
193 |
194 | - (void) orderFront:(id)sender {
195 | [super orderFront:sender];
196 | [self _setNeedsLayout];
197 | }
198 |
199 | #pragma mark - Public
200 |
201 | - (NSView *) titleBarView {
202 | return [_standardButtons[0] superview];
203 | }
204 |
205 | - (void) setCenterTrafficLightButtons:(BOOL)centerTrafficLightButtons {
206 | _centerTrafficLightButtons = centerTrafficLightButtons;
207 | [self _setNeedsLayout];
208 | }
209 |
210 | - (void) setTitleBarHeight:(CGFloat)titleBarHeight {
211 |
212 | titleBarHeight = MAX(titleBarHeight,[[self class] defaultTitleBarHeight]);
213 | CGFloat delta = titleBarHeight - _titleBarHeight;
214 | _titleBarHeight = titleBarHeight;
215 |
216 | if (_dummyTitlebarAccessoryViewController) {
217 | [self removeTitlebarAccessoryViewControllerAtIndex:0];
218 | }
219 |
220 | NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 10, titleBarHeight-[WAYWindow defaultTitleBarHeight])];
221 | _dummyTitlebarAccessoryViewController = [NSTitlebarAccessoryViewController new];
222 | _dummyTitlebarAccessoryViewController.view = view;
223 | _dummyTitlebarAccessoryViewController.fullScreenMinHeight = titleBarHeight;
224 | [self addTitlebarAccessoryViewController:_dummyTitlebarAccessoryViewController];
225 |
226 | NSRect frame = self.frame;
227 | frame.size.height += delta;
228 | frame.origin.y -= delta;
229 |
230 | [self _setNeedsLayout];
231 | [self setFrame:frame display:NO]; // NO is important.
232 | }
233 |
234 | - (void) setHidesTitle:(BOOL)hidesTitle {
235 | _hidesTitle = hidesTitle;
236 | [self setTitleVisibility:hidesTitle ? NSWindowTitleHidden : NSWindowTitleVisible];
237 | }
238 |
239 | - (void) setContentViewAppearanceVibrantDark {
240 | [self setContentViewAppearance:NSVisualEffectMaterialDark];
241 | }
242 |
243 | - (void) setContentViewAppearanceVibrantLight {
244 | [self setContentViewAppearance:NSVisualEffectMaterialLight];
245 | }
246 |
247 | - (void) setContentViewAppearance: (int) material {
248 | if (![WAYWindow supportsVibrantAppearances])
249 | return;
250 |
251 | NSVisualEffectView *newContentView = (NSVisualEffectView *)[self replaceSubview:self.contentView withViewOfClass:[NSVisualEffectView class]];
252 | [newContentView setMaterial:material];
253 | [self setContentView:newContentView];
254 | }
255 |
256 | - (void) setVibrantDarkAppearance {
257 | [self setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]];
258 | }
259 |
260 | - (void) setVibrantLightAppearance {
261 | [self setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantLight]];
262 | }
263 |
264 | - (void) setAquaAppearance {
265 | [self setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameAqua]];
266 | }
267 |
268 | - (BOOL) isFullScreen {
269 | return (([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask);
270 | }
271 |
272 | - (void) replaceSubview: (NSView *) aView withView: (NSView *) newView resizing:(BOOL)flag {
273 | if (flag) {
274 | [newView setFrame:aView.frame];
275 | }
276 |
277 | [newView setAutoresizesSubviews:aView.autoresizesSubviews];
278 | [aView.subviews.copy enumerateObjectsUsingBlock:^(NSView *subview, NSUInteger idx, BOOL *stop) {
279 | NSRect frame = subview.frame;
280 | if (subview.constraints.count>0) {
281 | // Note: so far, constraint based contentView subviews are not supported yet
282 | NSLog(@"WARNING: [%@ %@] does not work yet with NSView instances, that use auto-layout.",
283 | NSStringFromClass([self class]),
284 | NSStringFromSelector(_cmd));
285 | }
286 | [subview removeFromSuperview];
287 | [newView addSubview:subview];
288 | [subview setFrame:frame];
289 | }];
290 |
291 | if (aView==self.contentView) {
292 | [self setContentView: newView];
293 | } else {
294 | [aView.superview replaceSubview:aView with:newView];
295 | }
296 | [self _setNeedsLayout];
297 | }
298 |
299 | - (NSView *) replaceSubview:(NSView *)aView withViewOfClass:(Class)newViewClass {
300 | NSView *view = [[newViewClass alloc] initWithFrame:aView.frame];
301 | [self replaceSubview:aView withView:view resizing:YES];
302 | return view;
303 | }
304 |
305 | #pragma mark - Private
306 |
307 | - (void) _setUp {
308 | _delegateProxy = [[WAYWindowDelegateProxy alloc] init];
309 | _delegateProxy.firstDelegate = self;
310 | super.delegate = _delegateProxy;
311 |
312 | _standardButtons = @[[self standardWindowButton:NSWindowCloseButton],
313 | [self standardWindowButton:NSWindowMiniaturizeButton],
314 | [self standardWindowButton:NSWindowZoomButton]];
315 | _centerTrafficLightButtons = YES;
316 |
317 | NSButton *closeButton = [self standardWindowButton:NSWindowCloseButton];
318 | kWAYWindowDefaultTrafficLightButtonsLeftMargin = NSMinX(closeButton.frame);
319 | kWAYWindowDefaultTrafficLightButtonsTopMargin = NSHeight(closeButton.superview.frame)-NSMaxY(closeButton.frame);
320 |
321 | self.styleMask |= NSFullSizeContentViewWindowMask;
322 | _trafficLightButtonsLeftMargin = kWAYWindowDefaultTrafficLightButtonsLeftMargin;
323 | _trafficLightButtonsTopMargin = kWAYWindowDefaultTrafficLightButtonsTopMargin;
324 |
325 | self.hidesTitle = YES;
326 |
327 | [super setDelegate:self];
328 | [self _setNeedsLayout];
329 | }
330 |
331 | - (void) _setNeedsLayout {
332 | [_standardButtons enumerateObjectsUsingBlock:^(NSButton *standardButton, NSUInteger idx, BOOL *stop) {
333 | NSRect frame = standardButton.frame;
334 | if (_centerTrafficLightButtons)
335 | frame.origin.y = NSHeight(standardButton.superview.frame)/2-NSHeight(standardButton.frame)/2;
336 | else
337 | frame.origin.y = NSHeight(standardButton.superview.frame)-NSHeight(standardButton.frame)-_trafficLightButtonsTopMargin;
338 |
339 | frame.origin.x = _trafficLightButtonsLeftMargin +idx*(NSWidth(frame) + 6);
340 | [standardButton setFrame:frame];
341 | }];
342 | }
343 |
344 | #pragma mark - NSWindow Delegate
345 |
346 | - (void) windowDidResize:(NSNotification *)notification {
347 | [self _setNeedsLayout];
348 | }
349 |
350 | @end
351 |
--------------------------------------------------------------------------------
/Inbox for Mac.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 9F836A311BA9C09B00DE4D39 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F836A301BA9C09B00DE4D39 /* AppDelegate.m */; };
11 | 9F836A331BA9C09C00DE4D39 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F836A321BA9C09C00DE4D39 /* main.m */; };
12 | 9F836A361BA9C09C00DE4D39 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F836A351BA9C09C00DE4D39 /* ViewController.m */; };
13 | 9F836A381BA9C09C00DE4D39 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F836A371BA9C09C00DE4D39 /* Images.xcassets */; };
14 | 9F836A3B1BA9C09C00DE4D39 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9F836A391BA9C09C00DE4D39 /* Main.storyboard */; };
15 | 9F836A471BA9C09C00DE4D39 /* Inbox_for_MacTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F836A461BA9C09C00DE4D39 /* Inbox_for_MacTests.m */; };
16 | 9F836A511BA9C0ED00DE4D39 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F836A501BA9C0ED00DE4D39 /* WebKit.framework */; };
17 | 9F836A541BA9CA5500DE4D39 /* WAYAppStoreWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F836A531BA9CA5500DE4D39 /* WAYAppStoreWindow.m */; };
18 | 9F836A571BA9CB1200DE4D39 /* WAYWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F836A561BA9CB1200DE4D39 /* WAYWindow.m */; };
19 | 9F836A5E1BA9CB2D00DE4D39 /* Extensions in Resources */ = {isa = PBXBuildFile; fileRef = 9F836A581BA9CB2D00DE4D39 /* Extensions */; };
20 | 9F836A5F1BA9CB2D00DE4D39 /* INAppStoreWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F836A5A1BA9CB2D00DE4D39 /* INAppStoreWindow.m */; };
21 | 9F836A601BA9CB2D00DE4D39 /* INWindowButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F836A5D1BA9CB2D00DE4D39 /* INWindowButton.m */; };
22 | 9FA5291C1BAA1EFE003BB8CF /* appicon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 9FA5291B1BAA1EFE003BB8CF /* appicon.icns */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXContainerItemProxy section */
26 | 9F836A411BA9C09C00DE4D39 /* PBXContainerItemProxy */ = {
27 | isa = PBXContainerItemProxy;
28 | containerPortal = 9F836A221BA9C09B00DE4D39 /* Project object */;
29 | proxyType = 1;
30 | remoteGlobalIDString = 9F836A291BA9C09B00DE4D39;
31 | remoteInfo = "Inbox for Mac";
32 | };
33 | /* End PBXContainerItemProxy section */
34 |
35 | /* Begin PBXFileReference section */
36 | 9F836A2A1BA9C09B00DE4D39 /* Inbox for Mac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Inbox for Mac.app"; sourceTree = BUILT_PRODUCTS_DIR; };
37 | 9F836A2E1BA9C09B00DE4D39 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
38 | 9F836A2F1BA9C09B00DE4D39 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
39 | 9F836A301BA9C09B00DE4D39 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
40 | 9F836A321BA9C09C00DE4D39 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
41 | 9F836A341BA9C09C00DE4D39 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
42 | 9F836A351BA9C09C00DE4D39 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
43 | 9F836A371BA9C09C00DE4D39 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
44 | 9F836A3A1BA9C09C00DE4D39 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
45 | 9F836A401BA9C09C00DE4D39 /* Inbox for MacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Inbox for MacTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
46 | 9F836A451BA9C09C00DE4D39 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
47 | 9F836A461BA9C09C00DE4D39 /* Inbox_for_MacTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Inbox_for_MacTests.m; sourceTree = ""; };
48 | 9F836A501BA9C0ED00DE4D39 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
49 | 9F836A521BA9CA5500DE4D39 /* WAYAppStoreWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WAYAppStoreWindow.h; sourceTree = ""; };
50 | 9F836A531BA9CA5500DE4D39 /* WAYAppStoreWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WAYAppStoreWindow.m; sourceTree = ""; };
51 | 9F836A551BA9CB1200DE4D39 /* WAYWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WAYWindow.h; sourceTree = ""; };
52 | 9F836A561BA9CB1200DE4D39 /* WAYWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WAYWindow.m; sourceTree = ""; };
53 | 9F836A581BA9CB2D00DE4D39 /* Extensions */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Extensions; sourceTree = ""; };
54 | 9F836A591BA9CB2D00DE4D39 /* INAppStoreWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INAppStoreWindow.h; sourceTree = ""; };
55 | 9F836A5A1BA9CB2D00DE4D39 /* INAppStoreWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = INAppStoreWindow.m; sourceTree = ""; };
56 | 9F836A5B1BA9CB2D00DE4D39 /* INAppStoreWindowCompatibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INAppStoreWindowCompatibility.h; sourceTree = ""; };
57 | 9F836A5C1BA9CB2D00DE4D39 /* INWindowButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INWindowButton.h; sourceTree = ""; };
58 | 9F836A5D1BA9CB2D00DE4D39 /* INWindowButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = INWindowButton.m; sourceTree = ""; };
59 | 9FA5291B1BAA1EFE003BB8CF /* appicon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = appicon.icns; sourceTree = ""; };
60 | /* End PBXFileReference section */
61 |
62 | /* Begin PBXFrameworksBuildPhase section */
63 | 9F836A271BA9C09B00DE4D39 /* Frameworks */ = {
64 | isa = PBXFrameworksBuildPhase;
65 | buildActionMask = 2147483647;
66 | files = (
67 | 9F836A511BA9C0ED00DE4D39 /* WebKit.framework in Frameworks */,
68 | );
69 | runOnlyForDeploymentPostprocessing = 0;
70 | };
71 | 9F836A3D1BA9C09C00DE4D39 /* Frameworks */ = {
72 | isa = PBXFrameworksBuildPhase;
73 | buildActionMask = 2147483647;
74 | files = (
75 | );
76 | runOnlyForDeploymentPostprocessing = 0;
77 | };
78 | /* End PBXFrameworksBuildPhase section */
79 |
80 | /* Begin PBXGroup section */
81 | 9F836A211BA9C09B00DE4D39 = {
82 | isa = PBXGroup;
83 | children = (
84 | 9F836A501BA9C0ED00DE4D39 /* WebKit.framework */,
85 | 9F836A2C1BA9C09B00DE4D39 /* Inbox for Mac */,
86 | 9F836A431BA9C09C00DE4D39 /* Inbox for MacTests */,
87 | 9F836A2B1BA9C09B00DE4D39 /* Products */,
88 | );
89 | sourceTree = "";
90 | };
91 | 9F836A2B1BA9C09B00DE4D39 /* Products */ = {
92 | isa = PBXGroup;
93 | children = (
94 | 9F836A2A1BA9C09B00DE4D39 /* Inbox for Mac.app */,
95 | 9F836A401BA9C09C00DE4D39 /* Inbox for MacTests.xctest */,
96 | );
97 | name = Products;
98 | sourceTree = "";
99 | };
100 | 9F836A2C1BA9C09B00DE4D39 /* Inbox for Mac */ = {
101 | isa = PBXGroup;
102 | children = (
103 | 9FA5291B1BAA1EFE003BB8CF /* appicon.icns */,
104 | 9F836A2F1BA9C09B00DE4D39 /* AppDelegate.h */,
105 | 9F836A301BA9C09B00DE4D39 /* AppDelegate.m */,
106 | 9F836A341BA9C09C00DE4D39 /* ViewController.h */,
107 | 9F836A351BA9C09C00DE4D39 /* ViewController.m */,
108 | 9F836A521BA9CA5500DE4D39 /* WAYAppStoreWindow.h */,
109 | 9F836A551BA9CB1200DE4D39 /* WAYWindow.h */,
110 | 9F836A561BA9CB1200DE4D39 /* WAYWindow.m */,
111 | 9F836A531BA9CA5500DE4D39 /* WAYAppStoreWindow.m */,
112 | 9F836A581BA9CB2D00DE4D39 /* Extensions */,
113 | 9F836A591BA9CB2D00DE4D39 /* INAppStoreWindow.h */,
114 | 9F836A5A1BA9CB2D00DE4D39 /* INAppStoreWindow.m */,
115 | 9F836A5B1BA9CB2D00DE4D39 /* INAppStoreWindowCompatibility.h */,
116 | 9F836A5C1BA9CB2D00DE4D39 /* INWindowButton.h */,
117 | 9F836A5D1BA9CB2D00DE4D39 /* INWindowButton.m */,
118 | 9F836A371BA9C09C00DE4D39 /* Images.xcassets */,
119 | 9F836A391BA9C09C00DE4D39 /* Main.storyboard */,
120 | 9F836A2D1BA9C09B00DE4D39 /* Supporting Files */,
121 | );
122 | path = "Inbox for Mac";
123 | sourceTree = "";
124 | };
125 | 9F836A2D1BA9C09B00DE4D39 /* Supporting Files */ = {
126 | isa = PBXGroup;
127 | children = (
128 | 9F836A2E1BA9C09B00DE4D39 /* Info.plist */,
129 | 9F836A321BA9C09C00DE4D39 /* main.m */,
130 | );
131 | name = "Supporting Files";
132 | sourceTree = "";
133 | };
134 | 9F836A431BA9C09C00DE4D39 /* Inbox for MacTests */ = {
135 | isa = PBXGroup;
136 | children = (
137 | 9F836A461BA9C09C00DE4D39 /* Inbox_for_MacTests.m */,
138 | 9F836A441BA9C09C00DE4D39 /* Supporting Files */,
139 | );
140 | path = "Inbox for MacTests";
141 | sourceTree = "";
142 | };
143 | 9F836A441BA9C09C00DE4D39 /* Supporting Files */ = {
144 | isa = PBXGroup;
145 | children = (
146 | 9F836A451BA9C09C00DE4D39 /* Info.plist */,
147 | );
148 | name = "Supporting Files";
149 | sourceTree = "";
150 | };
151 | /* End PBXGroup section */
152 |
153 | /* Begin PBXNativeTarget section */
154 | 9F836A291BA9C09B00DE4D39 /* Inbox for Mac */ = {
155 | isa = PBXNativeTarget;
156 | buildConfigurationList = 9F836A4A1BA9C09C00DE4D39 /* Build configuration list for PBXNativeTarget "Inbox for Mac" */;
157 | buildPhases = (
158 | 9F836A261BA9C09B00DE4D39 /* Sources */,
159 | 9F836A271BA9C09B00DE4D39 /* Frameworks */,
160 | 9F836A281BA9C09B00DE4D39 /* Resources */,
161 | );
162 | buildRules = (
163 | );
164 | dependencies = (
165 | );
166 | name = "Inbox for Mac";
167 | productName = "Inbox for Mac";
168 | productReference = 9F836A2A1BA9C09B00DE4D39 /* Inbox for Mac.app */;
169 | productType = "com.apple.product-type.application";
170 | };
171 | 9F836A3F1BA9C09C00DE4D39 /* Inbox for MacTests */ = {
172 | isa = PBXNativeTarget;
173 | buildConfigurationList = 9F836A4D1BA9C09C00DE4D39 /* Build configuration list for PBXNativeTarget "Inbox for MacTests" */;
174 | buildPhases = (
175 | 9F836A3C1BA9C09C00DE4D39 /* Sources */,
176 | 9F836A3D1BA9C09C00DE4D39 /* Frameworks */,
177 | 9F836A3E1BA9C09C00DE4D39 /* Resources */,
178 | );
179 | buildRules = (
180 | );
181 | dependencies = (
182 | 9F836A421BA9C09C00DE4D39 /* PBXTargetDependency */,
183 | );
184 | name = "Inbox for MacTests";
185 | productName = "Inbox for MacTests";
186 | productReference = 9F836A401BA9C09C00DE4D39 /* Inbox for MacTests.xctest */;
187 | productType = "com.apple.product-type.bundle.unit-test";
188 | };
189 | /* End PBXNativeTarget section */
190 |
191 | /* Begin PBXProject section */
192 | 9F836A221BA9C09B00DE4D39 /* Project object */ = {
193 | isa = PBXProject;
194 | attributes = {
195 | LastUpgradeCheck = 0640;
196 | ORGANIZATIONNAME = "Alasdair Lampon-Monk";
197 | TargetAttributes = {
198 | 9F836A291BA9C09B00DE4D39 = {
199 | CreatedOnToolsVersion = 6.4;
200 | };
201 | 9F836A3F1BA9C09C00DE4D39 = {
202 | CreatedOnToolsVersion = 6.4;
203 | TestTargetID = 9F836A291BA9C09B00DE4D39;
204 | };
205 | };
206 | };
207 | buildConfigurationList = 9F836A251BA9C09B00DE4D39 /* Build configuration list for PBXProject "Inbox for Mac" */;
208 | compatibilityVersion = "Xcode 3.2";
209 | developmentRegion = English;
210 | hasScannedForEncodings = 0;
211 | knownRegions = (
212 | en,
213 | Base,
214 | );
215 | mainGroup = 9F836A211BA9C09B00DE4D39;
216 | productRefGroup = 9F836A2B1BA9C09B00DE4D39 /* Products */;
217 | projectDirPath = "";
218 | projectRoot = "";
219 | targets = (
220 | 9F836A291BA9C09B00DE4D39 /* Inbox for Mac */,
221 | 9F836A3F1BA9C09C00DE4D39 /* Inbox for MacTests */,
222 | );
223 | };
224 | /* End PBXProject section */
225 |
226 | /* Begin PBXResourcesBuildPhase section */
227 | 9F836A281BA9C09B00DE4D39 /* Resources */ = {
228 | isa = PBXResourcesBuildPhase;
229 | buildActionMask = 2147483647;
230 | files = (
231 | 9F836A5E1BA9CB2D00DE4D39 /* Extensions in Resources */,
232 | 9FA5291C1BAA1EFE003BB8CF /* appicon.icns in Resources */,
233 | 9F836A381BA9C09C00DE4D39 /* Images.xcassets in Resources */,
234 | 9F836A3B1BA9C09C00DE4D39 /* Main.storyboard in Resources */,
235 | );
236 | runOnlyForDeploymentPostprocessing = 0;
237 | };
238 | 9F836A3E1BA9C09C00DE4D39 /* Resources */ = {
239 | isa = PBXResourcesBuildPhase;
240 | buildActionMask = 2147483647;
241 | files = (
242 | );
243 | runOnlyForDeploymentPostprocessing = 0;
244 | };
245 | /* End PBXResourcesBuildPhase section */
246 |
247 | /* Begin PBXSourcesBuildPhase section */
248 | 9F836A261BA9C09B00DE4D39 /* Sources */ = {
249 | isa = PBXSourcesBuildPhase;
250 | buildActionMask = 2147483647;
251 | files = (
252 | 9F836A5F1BA9CB2D00DE4D39 /* INAppStoreWindow.m in Sources */,
253 | 9F836A361BA9C09C00DE4D39 /* ViewController.m in Sources */,
254 | 9F836A541BA9CA5500DE4D39 /* WAYAppStoreWindow.m in Sources */,
255 | 9F836A601BA9CB2D00DE4D39 /* INWindowButton.m in Sources */,
256 | 9F836A331BA9C09C00DE4D39 /* main.m in Sources */,
257 | 9F836A311BA9C09B00DE4D39 /* AppDelegate.m in Sources */,
258 | 9F836A571BA9CB1200DE4D39 /* WAYWindow.m in Sources */,
259 | );
260 | runOnlyForDeploymentPostprocessing = 0;
261 | };
262 | 9F836A3C1BA9C09C00DE4D39 /* Sources */ = {
263 | isa = PBXSourcesBuildPhase;
264 | buildActionMask = 2147483647;
265 | files = (
266 | 9F836A471BA9C09C00DE4D39 /* Inbox_for_MacTests.m in Sources */,
267 | );
268 | runOnlyForDeploymentPostprocessing = 0;
269 | };
270 | /* End PBXSourcesBuildPhase section */
271 |
272 | /* Begin PBXTargetDependency section */
273 | 9F836A421BA9C09C00DE4D39 /* PBXTargetDependency */ = {
274 | isa = PBXTargetDependency;
275 | target = 9F836A291BA9C09B00DE4D39 /* Inbox for Mac */;
276 | targetProxy = 9F836A411BA9C09C00DE4D39 /* PBXContainerItemProxy */;
277 | };
278 | /* End PBXTargetDependency section */
279 |
280 | /* Begin PBXVariantGroup section */
281 | 9F836A391BA9C09C00DE4D39 /* Main.storyboard */ = {
282 | isa = PBXVariantGroup;
283 | children = (
284 | 9F836A3A1BA9C09C00DE4D39 /* Base */,
285 | );
286 | name = Main.storyboard;
287 | sourceTree = "";
288 | };
289 | /* End PBXVariantGroup section */
290 |
291 | /* Begin XCBuildConfiguration section */
292 | 9F836A481BA9C09C00DE4D39 /* Debug */ = {
293 | isa = XCBuildConfiguration;
294 | buildSettings = {
295 | ALWAYS_SEARCH_USER_PATHS = NO;
296 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
297 | CLANG_CXX_LIBRARY = "libc++";
298 | CLANG_ENABLE_MODULES = YES;
299 | CLANG_ENABLE_OBJC_ARC = YES;
300 | CLANG_WARN_BOOL_CONVERSION = YES;
301 | CLANG_WARN_CONSTANT_CONVERSION = YES;
302 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
303 | CLANG_WARN_EMPTY_BODY = YES;
304 | CLANG_WARN_ENUM_CONVERSION = YES;
305 | CLANG_WARN_INT_CONVERSION = YES;
306 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
307 | CLANG_WARN_UNREACHABLE_CODE = YES;
308 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
309 | CODE_SIGN_IDENTITY = "-";
310 | COPY_PHASE_STRIP = NO;
311 | DEBUG_INFORMATION_FORMAT = dwarf;
312 | ENABLE_STRICT_OBJC_MSGSEND = YES;
313 | GCC_C_LANGUAGE_STANDARD = gnu99;
314 | GCC_DYNAMIC_NO_PIC = NO;
315 | GCC_NO_COMMON_BLOCKS = YES;
316 | GCC_OPTIMIZATION_LEVEL = 0;
317 | GCC_PREPROCESSOR_DEFINITIONS = (
318 | "DEBUG=1",
319 | "$(inherited)",
320 | );
321 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
322 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
323 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
324 | GCC_WARN_UNDECLARED_SELECTOR = YES;
325 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
326 | GCC_WARN_UNUSED_FUNCTION = YES;
327 | GCC_WARN_UNUSED_VARIABLE = YES;
328 | MACOSX_DEPLOYMENT_TARGET = 10.10;
329 | MTL_ENABLE_DEBUG_INFO = YES;
330 | ONLY_ACTIVE_ARCH = YES;
331 | SDKROOT = macosx;
332 | };
333 | name = Debug;
334 | };
335 | 9F836A491BA9C09C00DE4D39 /* Release */ = {
336 | isa = XCBuildConfiguration;
337 | buildSettings = {
338 | ALWAYS_SEARCH_USER_PATHS = NO;
339 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
340 | CLANG_CXX_LIBRARY = "libc++";
341 | CLANG_ENABLE_MODULES = YES;
342 | CLANG_ENABLE_OBJC_ARC = YES;
343 | CLANG_WARN_BOOL_CONVERSION = YES;
344 | CLANG_WARN_CONSTANT_CONVERSION = YES;
345 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
346 | CLANG_WARN_EMPTY_BODY = YES;
347 | CLANG_WARN_ENUM_CONVERSION = YES;
348 | CLANG_WARN_INT_CONVERSION = YES;
349 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
350 | CLANG_WARN_UNREACHABLE_CODE = YES;
351 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
352 | CODE_SIGN_IDENTITY = "-";
353 | COPY_PHASE_STRIP = NO;
354 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
355 | ENABLE_NS_ASSERTIONS = NO;
356 | ENABLE_STRICT_OBJC_MSGSEND = YES;
357 | GCC_C_LANGUAGE_STANDARD = gnu99;
358 | GCC_NO_COMMON_BLOCKS = YES;
359 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
360 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
361 | GCC_WARN_UNDECLARED_SELECTOR = YES;
362 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
363 | GCC_WARN_UNUSED_FUNCTION = YES;
364 | GCC_WARN_UNUSED_VARIABLE = YES;
365 | MACOSX_DEPLOYMENT_TARGET = 10.10;
366 | MTL_ENABLE_DEBUG_INFO = NO;
367 | SDKROOT = macosx;
368 | };
369 | name = Release;
370 | };
371 | 9F836A4B1BA9C09C00DE4D39 /* Debug */ = {
372 | isa = XCBuildConfiguration;
373 | buildSettings = {
374 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
375 | COMBINE_HIDPI_IMAGES = YES;
376 | INFOPLIST_FILE = "Inbox for Mac/Info.plist";
377 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
378 | PRODUCT_NAME = "$(TARGET_NAME)";
379 | };
380 | name = Debug;
381 | };
382 | 9F836A4C1BA9C09C00DE4D39 /* Release */ = {
383 | isa = XCBuildConfiguration;
384 | buildSettings = {
385 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
386 | COMBINE_HIDPI_IMAGES = YES;
387 | INFOPLIST_FILE = "Inbox for Mac/Info.plist";
388 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
389 | PRODUCT_NAME = "$(TARGET_NAME)";
390 | };
391 | name = Release;
392 | };
393 | 9F836A4E1BA9C09C00DE4D39 /* Debug */ = {
394 | isa = XCBuildConfiguration;
395 | buildSettings = {
396 | BUNDLE_LOADER = "$(TEST_HOST)";
397 | COMBINE_HIDPI_IMAGES = YES;
398 | FRAMEWORK_SEARCH_PATHS = (
399 | "$(DEVELOPER_FRAMEWORKS_DIR)",
400 | "$(inherited)",
401 | );
402 | GCC_PREPROCESSOR_DEFINITIONS = (
403 | "DEBUG=1",
404 | "$(inherited)",
405 | );
406 | INFOPLIST_FILE = "Inbox for MacTests/Info.plist";
407 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
408 | PRODUCT_NAME = "$(TARGET_NAME)";
409 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Inbox for Mac.app/Contents/MacOS/Inbox for Mac";
410 | };
411 | name = Debug;
412 | };
413 | 9F836A4F1BA9C09C00DE4D39 /* Release */ = {
414 | isa = XCBuildConfiguration;
415 | buildSettings = {
416 | BUNDLE_LOADER = "$(TEST_HOST)";
417 | COMBINE_HIDPI_IMAGES = YES;
418 | FRAMEWORK_SEARCH_PATHS = (
419 | "$(DEVELOPER_FRAMEWORKS_DIR)",
420 | "$(inherited)",
421 | );
422 | INFOPLIST_FILE = "Inbox for MacTests/Info.plist";
423 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks";
424 | PRODUCT_NAME = "$(TARGET_NAME)";
425 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Inbox for Mac.app/Contents/MacOS/Inbox for Mac";
426 | };
427 | name = Release;
428 | };
429 | /* End XCBuildConfiguration section */
430 |
431 | /* Begin XCConfigurationList section */
432 | 9F836A251BA9C09B00DE4D39 /* Build configuration list for PBXProject "Inbox for Mac" */ = {
433 | isa = XCConfigurationList;
434 | buildConfigurations = (
435 | 9F836A481BA9C09C00DE4D39 /* Debug */,
436 | 9F836A491BA9C09C00DE4D39 /* Release */,
437 | );
438 | defaultConfigurationIsVisible = 0;
439 | defaultConfigurationName = Release;
440 | };
441 | 9F836A4A1BA9C09C00DE4D39 /* Build configuration list for PBXNativeTarget "Inbox for Mac" */ = {
442 | isa = XCConfigurationList;
443 | buildConfigurations = (
444 | 9F836A4B1BA9C09C00DE4D39 /* Debug */,
445 | 9F836A4C1BA9C09C00DE4D39 /* Release */,
446 | );
447 | defaultConfigurationIsVisible = 0;
448 | defaultConfigurationName = Release;
449 | };
450 | 9F836A4D1BA9C09C00DE4D39 /* Build configuration list for PBXNativeTarget "Inbox for MacTests" */ = {
451 | isa = XCConfigurationList;
452 | buildConfigurations = (
453 | 9F836A4E1BA9C09C00DE4D39 /* Debug */,
454 | 9F836A4F1BA9C09C00DE4D39 /* Release */,
455 | );
456 | defaultConfigurationIsVisible = 0;
457 | defaultConfigurationName = Release;
458 | };
459 | /* End XCConfigurationList section */
460 | };
461 | rootObject = 9F836A221BA9C09B00DE4D39 /* Project object */;
462 | }
463 |
--------------------------------------------------------------------------------
/Inbox for Mac/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
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 |
--------------------------------------------------------------------------------