]> git.saurik.com Git - winterboard.git/blob - Application.mm
Apple's cruelty knows no bound: icky iOS 7 icons.
[winterboard.git] / Application.mm
1 /* WinterBoard - Theme Manager for the iPhone
2 * Copyright (C) 2008-2014 Jay Freeman (saurik)
3 */
4
5 /* GNU Lesser General Public License, Version 3 {{{ */
6 /*
7 * WinterBoard is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * WinterBoard is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with WinterBoard. If not, see <http://www.gnu.org/licenses/>.
19 **/
20 /* }}} */
21
22 #import <Foundation/Foundation.h>
23 #import <CoreGraphics/CGGeometry.h>
24 #import <UIKit/UIKit.h>
25
26 #include <objc/objc-runtime.h>
27
28 #import <Preferences/PSRootController.h>
29 #import <Preferences/PSViewController.h>
30 #import <Preferences/PSListController.h>
31 #import <Preferences/PSSpecifier.h>
32
33 #include <mach-o/dyld.h>
34
35 static NSBundle *wbSettingsBundle;
36 static Class $WBSettingsController;
37
38 @interface UIApplication (Private)
39 - (void) terminateWithSuccess;
40 @end
41
42 @interface UIDevice (Private)
43 - (BOOL) isWildcat;
44 @end
45
46 @interface PSRootController (Compatibility)
47 - (id) _popController; // < 3.2
48 - (id) contentView; // < 3.2
49 - (id) lastController; // < 3.2
50 - (id) topViewController; // >= 3.2
51 @end
52
53 @interface PSListController (Compatibility)
54 - (void) viewWillBecomeVisible:(void *)specifier; // < 3.2
55 - (void) viewWillAppear:(BOOL)a; // >= 3.2
56 - (void) setSpecifier:(PSSpecifier *)spec; // >= 3.2
57 @end
58
59 @interface WBRootController : PSRootController {
60 PSListController *_rootListController;
61 }
62
63 @property (readonly) PSListController *rootListController;
64
65 - (void) setupRootListForSize:(CGSize)size;
66 - (id) topViewController;
67 @end
68
69 @implementation WBRootController
70
71 @synthesize rootListController = _rootListController;
72
73 // < 3.2
74 - (void) setupRootListForSize:(CGSize)size {
75 PSSpecifier *spec([[PSSpecifier alloc] init]);
76 [spec setTarget:self];
77 spec.name = @"WinterBoard";
78
79 _rootListController = [[$WBSettingsController alloc] initForContentSize:size];
80 _rootListController.rootController = self;
81 _rootListController.parentController = self;
82 [_rootListController viewWillBecomeVisible:spec];
83
84 [spec release];
85
86 [self pushController:_rootListController];
87 }
88
89 // >= 3.2
90 - (void) loadView {
91 [super loadView];
92 [self pushViewController:[self rootListController] animated:NO];
93 }
94
95 - (PSListController *) rootListController {
96 if(!_rootListController) {
97 PSSpecifier *spec([[PSSpecifier alloc] init]);
98 [spec setTarget:self];
99 spec.name = @"WinterBoard";
100 _rootListController = [[$WBSettingsController alloc] initForContentSize:CGSizeZero];
101 _rootListController.rootController = self;
102 _rootListController.parentController = self;
103 [_rootListController setSpecifier:spec];
104 [spec release];
105 }
106 return _rootListController;
107 }
108
109 - (id) contentView {
110 if ([[PSRootController class] instancesRespondToSelector:@selector(contentView)]) {
111 return [super contentView];
112 } else {
113 return [super view];
114 }
115 }
116
117 - (id) topViewController {
118 if ([[PSRootController class] instancesRespondToSelector:@selector(topViewController)]) {
119 return [super topViewController];
120 } else {
121 return [super lastController];
122 }
123 }
124
125 - (void) _popController {
126 // Pop the last controller = exit the application.
127 // The only time the last controller should pop is when the user taps Respring/Cancel.
128 // Which only gets displayed if the user has made changes.
129 if ([self topViewController] == _rootListController)
130 [[UIApplication sharedApplication] terminateWithSuccess];
131 [super _popController];
132 }
133
134 @end
135
136 @interface WBApplication : UIApplication {
137 WBRootController *_rootController;
138 }
139
140 @end
141
142 @implementation WBApplication
143
144 - (void) dealloc {
145 [_rootController release];
146 [super dealloc];
147 }
148
149 - (void) applicationWillTerminate:(UIApplication *)application {
150 [_rootController.rootListController suspend];
151 }
152
153 - (void) applicationDidFinishLaunching:(id)unused {
154 wbSettingsBundle = [NSBundle bundleWithPath:@"/System/Library/PreferenceBundles/WinterBoardSettings.bundle"];
155 [wbSettingsBundle load];
156 $WBSettingsController = [wbSettingsBundle principalClass];
157
158 CGRect applicationFrame(([UIDevice instancesRespondToSelector:@selector(isWildcat)]
159 && [[UIDevice currentDevice] isWildcat]) || objc_getClass("UIStatusBar") != nil
160 ? [UIScreen mainScreen].bounds
161 : [UIScreen mainScreen].applicationFrame);
162 UIWindow *window([[UIWindow alloc] initWithFrame:applicationFrame]);
163 _rootController = [[WBRootController alloc] initWithTitle:@"WinterBoard" identifier:[[NSBundle mainBundle] bundleIdentifier]];
164 [window addSubview:[_rootController contentView]];
165 [window makeKeyAndVisible];
166 }
167
168 @end
169
170 int main(int argc, char *argv[]) {
171 NSAutoreleasePool *pool( [[NSAutoreleasePool alloc] init]);
172
173 int value = UIApplicationMain(argc, argv, @"WBApplication", @"WBApplication");
174
175 [pool release];
176 return value;
177 }