Updater support
This commit is contained in:
parent
ea05a0c765
commit
1d0366052d
@ -1,16 +1,25 @@
|
|||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <WebKit/WebKit.h>
|
||||||
|
|
||||||
@interface AppDelegate : NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate, NSMenuDelegate>
|
@interface AppDelegate : NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate, NSMenuDelegate, WebUIDelegate, WebPolicyDelegate, WebFrameLoadDelegate>
|
||||||
|
|
||||||
@property (nonatomic, strong) IBOutlet NSWindow *preferencesWindow;
|
@property (nonatomic, strong) IBOutlet NSWindow *preferencesWindow;
|
||||||
@property (nonatomic, strong) IBOutlet NSView *graphicsTab;
|
@property (nonatomic, strong) IBOutlet NSView *graphicsTab;
|
||||||
@property (nonatomic, strong) IBOutlet NSView *emulationTab;
|
@property (nonatomic, strong) IBOutlet NSView *emulationTab;
|
||||||
@property (nonatomic, strong) IBOutlet NSView *audioTab;
|
@property (nonatomic, strong) IBOutlet NSView *audioTab;
|
||||||
@property (nonatomic, strong) IBOutlet NSView *controlsTab;
|
@property (nonatomic, strong) IBOutlet NSView *controlsTab;
|
||||||
|
@property (nonatomic, strong) IBOutlet NSView *updatesTab;
|
||||||
- (IBAction)showPreferences: (id) sender;
|
- (IBAction)showPreferences: (id) sender;
|
||||||
- (IBAction)toggleDeveloperMode:(id)sender;
|
- (IBAction)toggleDeveloperMode:(id)sender;
|
||||||
- (IBAction)switchPreferencesTab:(id)sender;
|
- (IBAction)switchPreferencesTab:(id)sender;
|
||||||
@property (nonatomic, weak) IBOutlet NSMenuItem *linkCableMenuItem;
|
@property (nonatomic, weak) IBOutlet NSMenuItem *linkCableMenuItem;
|
||||||
|
@property (nonatomic, strong) IBOutlet NSWindow *updateWindow;
|
||||||
|
@property (nonatomic, strong) IBOutlet WebView *updateChanges;
|
||||||
|
@property (nonatomic, strong) IBOutlet NSProgressIndicator *updatesSpinner;
|
||||||
|
@property (strong) IBOutlet NSButton *updatesButton;
|
||||||
|
@property (strong) IBOutlet NSTextField *updateProgressLabel;
|
||||||
|
@property (strong) IBOutlet NSButton *updateProgressButton;
|
||||||
|
@property (strong) IBOutlet NSWindow *updateProgressWindow;
|
||||||
|
@property (strong) IBOutlet NSProgressIndicator *updateProgressSpinner;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -4,11 +4,35 @@
|
|||||||
#include <Core/gb.h>
|
#include <Core/gb.h>
|
||||||
#import <Carbon/Carbon.h>
|
#import <Carbon/Carbon.h>
|
||||||
#import <JoyKit/JoyKit.h>
|
#import <JoyKit/JoyKit.h>
|
||||||
|
#import <WebKit/WebKit.h>
|
||||||
|
|
||||||
|
#define UPDATE_SERVER "https://sameboy.github.io"
|
||||||
|
#define str(x) #x
|
||||||
|
#define xstr(x) str(x)
|
||||||
|
|
||||||
|
static uint32_t color_to_int(NSColor *color)
|
||||||
|
{
|
||||||
|
color = [color colorUsingColorSpace:[NSColorSpace deviceRGBColorSpace]];
|
||||||
|
return (((unsigned)(color.redComponent * 0xFF)) << 16) |
|
||||||
|
(((unsigned)(color.greenComponent * 0xFF)) << 8) |
|
||||||
|
((unsigned)(color.blueComponent * 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
{
|
{
|
||||||
NSWindow *preferences_window;
|
NSWindow *preferences_window;
|
||||||
NSArray<NSView *> *preferences_tabs;
|
NSArray<NSView *> *preferences_tabs;
|
||||||
|
NSString *_lastVersion;
|
||||||
|
NSString *_updateURL;
|
||||||
|
NSURLSessionDownloadTask *_updateTask;
|
||||||
|
enum {
|
||||||
|
UPDATE_DOWNLOADING,
|
||||||
|
UPDATE_EXTRACTING,
|
||||||
|
UPDATE_WAIT_INSTALL,
|
||||||
|
UPDATE_INSTALLING,
|
||||||
|
UPDATE_FAILED,
|
||||||
|
} _updateState;
|
||||||
|
NSString *_downloadDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) applicationDidFinishLaunching:(NSNotification *)notification
|
- (void) applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
@ -54,6 +78,16 @@
|
|||||||
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"GBNotificationsUsed"]) {
|
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"GBNotificationsUsed"]) {
|
||||||
[NSUserNotificationCenter defaultUserNotificationCenter].delegate = self;
|
[NSUserNotificationCenter defaultUserNotificationCenter].delegate = self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[self askAutoUpdates];
|
||||||
|
|
||||||
|
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"GBAutoUpdatesEnabled"]) {
|
||||||
|
[self checkForUpdates];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([[NSProcessInfo processInfo].arguments containsObject:@"--update-launch"]) {
|
||||||
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)toggleDeveloperMode:(id)sender
|
- (IBAction)toggleDeveloperMode:(id)sender
|
||||||
@ -111,15 +145,19 @@
|
|||||||
[[NSBundle mainBundle] loadNibNamed:@"Preferences" owner:self topLevelObjects:&objects];
|
[[NSBundle mainBundle] loadNibNamed:@"Preferences" owner:self topLevelObjects:&objects];
|
||||||
NSToolbarItem *first_toolbar_item = [_preferencesWindow.toolbar.items firstObject];
|
NSToolbarItem *first_toolbar_item = [_preferencesWindow.toolbar.items firstObject];
|
||||||
_preferencesWindow.toolbar.selectedItemIdentifier = [first_toolbar_item itemIdentifier];
|
_preferencesWindow.toolbar.selectedItemIdentifier = [first_toolbar_item itemIdentifier];
|
||||||
preferences_tabs = @[self.emulationTab, self.graphicsTab, self.audioTab, self.controlsTab];
|
preferences_tabs = @[self.emulationTab, self.graphicsTab, self.audioTab, self.controlsTab, self.updatesTab];
|
||||||
[self switchPreferencesTab:first_toolbar_item];
|
[self switchPreferencesTab:first_toolbar_item];
|
||||||
[_preferencesWindow center];
|
[_preferencesWindow center];
|
||||||
|
#ifndef UPDATE_SUPPORT
|
||||||
|
[_preferencesWindow.toolbar removeItemAtIndex:4];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
[_preferencesWindow makeKeyAndOrderFront:self];
|
[_preferencesWindow makeKeyAndOrderFront:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender
|
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender
|
||||||
{
|
{
|
||||||
|
[self askAutoUpdates];
|
||||||
/* Bring an existing panel to the foreground */
|
/* Bring an existing panel to the foreground */
|
||||||
for (NSWindow *window in [[NSApplication sharedApplication] windows]) {
|
for (NSWindow *window in [[NSApplication sharedApplication] windows]) {
|
||||||
if ([window isKindOfClass:[NSOpenPanel class]]) {
|
if ([window isKindOfClass:[NSOpenPanel class]]) {
|
||||||
@ -136,6 +174,275 @@
|
|||||||
[[NSDocumentController sharedDocumentController] openDocumentWithContentsOfFile:notification.identifier display:YES];
|
[[NSDocumentController sharedDocumentController] openDocumentWithContentsOfFile:notification.identifier display:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)updateFound
|
||||||
|
{
|
||||||
|
[[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@UPDATE_SERVER "/raw_changes"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||||
|
|
||||||
|
NSColor *linkColor = [NSColor colorWithRed:0.125 green:0.325 blue:1.0 alpha:1.0];
|
||||||
|
if (@available(macOS 10.10, *)) {
|
||||||
|
linkColor = [NSColor linkColor];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString *changes = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||||
|
NSRange cutoffRange = [changes rangeOfString:@"<!--(" xstr(VERSION) ")-->"];
|
||||||
|
if (cutoffRange.location != NSNotFound) {
|
||||||
|
changes = [changes substringToIndex:cutoffRange.location];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString *html = [NSString stringWithFormat:@"<!DOCTYPE html><html><head><title></title>"
|
||||||
|
"<style>html {background-color:transparent; color: #%06x; line-height:1.5} a:link, a:visited{color:#%06x; text-decoration:none}</style>"
|
||||||
|
"</head><body>%@</body></html>",
|
||||||
|
color_to_int([NSColor textColor]),
|
||||||
|
color_to_int(linkColor),
|
||||||
|
changes];
|
||||||
|
|
||||||
|
if ([(NSHTTPURLResponse *)response statusCode] == 200) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
NSArray *objects;
|
||||||
|
[[NSBundle mainBundle] loadNibNamed:@"UpdateWindow" owner:self topLevelObjects:&objects];
|
||||||
|
self.updateChanges.preferences.standardFontFamily = [NSFont systemFontOfSize:0].familyName;
|
||||||
|
self.updateChanges.preferences.fixedFontFamily = @"Menlo";
|
||||||
|
self.updateChanges.drawsBackground = false;
|
||||||
|
[self.updateChanges.mainFrame loadHTMLString:html baseURL:nil];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}] resume];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems
|
||||||
|
{
|
||||||
|
// Disable reload context menu
|
||||||
|
if ([defaultMenuItems count] <= 2) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return defaultMenuItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
|
||||||
|
{
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
sender.mainFrame.frameView.documentView.enclosingScrollView.drawsBackground = true;
|
||||||
|
sender.mainFrame.frameView.documentView.enclosingScrollView.backgroundColor = [NSColor textBackgroundColor];
|
||||||
|
sender.policyDelegate = self;
|
||||||
|
[self.updateWindow center];
|
||||||
|
[self.updateWindow makeKeyAndOrderFront:nil];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener
|
||||||
|
{
|
||||||
|
[listener ignore];
|
||||||
|
[[NSWorkspace sharedWorkspace] openURL:[request URL]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)checkForUpdates
|
||||||
|
{
|
||||||
|
#ifdef UPDATE_SUPPORT
|
||||||
|
[[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@UPDATE_SERVER "/latest_version"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[self.updatesSpinner stopAnimation:nil];
|
||||||
|
[self.updatesButton setEnabled:YES];
|
||||||
|
});
|
||||||
|
if ([(NSHTTPURLResponse *)response statusCode] == 200) {
|
||||||
|
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
||||||
|
NSArray <NSString *> *components = [string componentsSeparatedByString:@"|"];
|
||||||
|
if (components.count != 2) return;
|
||||||
|
_lastVersion = components[0];
|
||||||
|
_updateURL = components[1];
|
||||||
|
if (![@xstr(VERSION) isEqualToString:_lastVersion] &&
|
||||||
|
![[[NSUserDefaults standardUserDefaults] stringForKey:@"GBSkippedVersion"] isEqualToString:_lastVersion]) {
|
||||||
|
[self updateFound];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}] resume];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)userCheckForUpdates:(id)sender
|
||||||
|
{
|
||||||
|
if (self.updateWindow) {
|
||||||
|
[self.updateWindow makeKeyAndOrderFront:sender];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:nil forKey:@"GBSkippedVersion"];
|
||||||
|
[self checkForUpdates];
|
||||||
|
[sender setEnabled:false];
|
||||||
|
[self.updatesSpinner startAnimation:sender];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)askAutoUpdates
|
||||||
|
{
|
||||||
|
#ifdef UPDATE_SUPPORT
|
||||||
|
if (![[NSUserDefaults standardUserDefaults] boolForKey:@"GBAskedAutoUpdates"]) {
|
||||||
|
NSAlert *alert = [[NSAlert alloc] init];
|
||||||
|
alert.messageText = @"Should SameBoy check for updates when launched?";
|
||||||
|
alert.informativeText = @"SameBoy is frequently updated with new features, accuracy improvements, and bug fixes. This setting can always be changed in the preferences window.";
|
||||||
|
[alert addButtonWithTitle:@"Check on Launch"];
|
||||||
|
[alert addButtonWithTitle:@"Don't Check on Launch"];
|
||||||
|
|
||||||
|
[[NSUserDefaults standardUserDefaults] setBool:[alert runModal] == NSAlertFirstButtonReturn forKey:@"GBAutoUpdatesEnabled"];
|
||||||
|
[[NSUserDefaults standardUserDefaults] setBool:true forKey:@"GBAskedAutoUpdates"];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)skipVersion:(id)sender
|
||||||
|
{
|
||||||
|
[[NSUserDefaults standardUserDefaults] setObject:_lastVersion forKey:@"GBSkippedVersion"];
|
||||||
|
[self.updateWindow performClose:sender];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)installUpdate:(id)sender
|
||||||
|
{
|
||||||
|
[self.updateProgressSpinner startAnimation:nil];
|
||||||
|
self.updateProgressButton.title = @"Cancel";
|
||||||
|
self.updateProgressButton.enabled = true;
|
||||||
|
self.updateProgressLabel.stringValue = @"Downloading update...";
|
||||||
|
_updateState = UPDATE_DOWNLOADING;
|
||||||
|
_updateTask = [[NSURLSession sharedSession] downloadTaskWithURL: [NSURL URLWithString:_updateURL] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
|
||||||
|
_updateTask = nil;
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
self.updateProgressButton.enabled = false;
|
||||||
|
self.updateProgressLabel.stringValue = @"Extracting update...";
|
||||||
|
_updateState = UPDATE_EXTRACTING;
|
||||||
|
});
|
||||||
|
|
||||||
|
_downloadDirectory = [[[NSFileManager defaultManager] URLForDirectory:NSItemReplacementDirectory
|
||||||
|
inDomain:NSUserDomainMask
|
||||||
|
appropriateForURL:[[NSBundle mainBundle] bundleURL]
|
||||||
|
create:YES
|
||||||
|
error:nil] path];
|
||||||
|
NSTask *unzipTask;
|
||||||
|
if (!_downloadDirectory) {
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
self.updateProgressButton.enabled = false;
|
||||||
|
self.updateProgressLabel.stringValue = @"Failed to extract update.";
|
||||||
|
_updateState = UPDATE_FAILED;
|
||||||
|
self.updateProgressButton.title = @"Close";
|
||||||
|
self.updateProgressButton.enabled = true;
|
||||||
|
[self.updateProgressSpinner stopAnimation:nil];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
unzipTask = [[NSTask alloc] init];
|
||||||
|
unzipTask.launchPath = @"/usr/bin/unzip";
|
||||||
|
unzipTask.arguments = @[location.path, @"-d", _downloadDirectory];
|
||||||
|
[unzipTask launch];
|
||||||
|
[unzipTask waitUntilExit];
|
||||||
|
if (unzipTask.terminationStatus != 0 || unzipTask.terminationReason != NSTaskTerminationReasonExit) {
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
self.updateProgressButton.enabled = false;
|
||||||
|
self.updateProgressLabel.stringValue = @"Failed to extract update.";
|
||||||
|
_updateState = UPDATE_FAILED;
|
||||||
|
self.updateProgressButton.title = @"Close";
|
||||||
|
self.updateProgressButton.enabled = true;
|
||||||
|
[self.updateProgressSpinner stopAnimation:nil];
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
self.updateProgressButton.enabled = false;
|
||||||
|
self.updateProgressLabel.stringValue = @"Update ready, save your game progress and click Install.";
|
||||||
|
_updateState = UPDATE_WAIT_INSTALL;
|
||||||
|
self.updateProgressButton.title = @"Install";
|
||||||
|
self.updateProgressButton.enabled = true;
|
||||||
|
[self.updateProgressSpinner stopAnimation:nil];
|
||||||
|
});
|
||||||
|
}];
|
||||||
|
[_updateTask resume];
|
||||||
|
|
||||||
|
self.updateProgressWindow.preventsApplicationTerminationWhenModal = false;
|
||||||
|
[self.updateWindow beginSheet:self.updateProgressWindow completionHandler:^(NSModalResponse returnCode) {
|
||||||
|
[self.updateWindow close];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)performUpgrade
|
||||||
|
{
|
||||||
|
self.updateProgressButton.enabled = false;
|
||||||
|
self.updateProgressLabel.stringValue = @"Instaling update...";
|
||||||
|
_updateState = UPDATE_INSTALLING;
|
||||||
|
self.updateProgressButton.enabled = false;
|
||||||
|
[self.updateProgressSpinner startAnimation:nil];
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
NSString *executablePath = [[NSBundle mainBundle] executablePath];
|
||||||
|
NSString *contentsPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"Contents"];
|
||||||
|
NSString *contentsTempPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"TempContents"];
|
||||||
|
NSString *updateContentsPath = [_downloadDirectory stringByAppendingPathComponent:@"SameBoy.app/Contents"];
|
||||||
|
NSError *error = nil;
|
||||||
|
[[NSFileManager defaultManager] moveItemAtPath:contentsPath toPath:contentsTempPath error:&error];
|
||||||
|
if (error) {
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
||||||
|
_downloadDirectory = nil;
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
self.updateProgressButton.enabled = false;
|
||||||
|
self.updateProgressLabel.stringValue = @"Failed to install update.";
|
||||||
|
_updateState = UPDATE_FAILED;
|
||||||
|
self.updateProgressButton.title = @"Close";
|
||||||
|
self.updateProgressButton.enabled = true;
|
||||||
|
[self.updateProgressSpinner stopAnimation:nil];
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[[NSFileManager defaultManager] moveItemAtPath:updateContentsPath toPath:contentsPath error:&error];
|
||||||
|
if (error) {
|
||||||
|
[[NSFileManager defaultManager] moveItemAtPath:contentsTempPath toPath:contentsPath error:nil];
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
||||||
|
_downloadDirectory = nil;
|
||||||
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
self.updateProgressButton.enabled = false;
|
||||||
|
self.updateProgressLabel.stringValue = @"Failed to install update.";
|
||||||
|
_updateState = UPDATE_FAILED;
|
||||||
|
self.updateProgressButton.title = @"Close";
|
||||||
|
self.updateProgressButton.enabled = true;
|
||||||
|
[self.updateProgressSpinner stopAnimation:nil];
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:contentsTempPath error:nil];
|
||||||
|
_downloadDirectory = nil;
|
||||||
|
atexit_b(^{
|
||||||
|
execl(executablePath.UTF8String, executablePath.UTF8String, "--update-launch", NULL);
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[NSApp terminate:nil];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)updateAction:(id)sender
|
||||||
|
{
|
||||||
|
switch (_updateState) {
|
||||||
|
case UPDATE_DOWNLOADING:
|
||||||
|
[_updateTask cancelByProducingResumeData:nil];
|
||||||
|
_updateTask = nil;
|
||||||
|
[self.updateProgressWindow close];
|
||||||
|
break;
|
||||||
|
case UPDATE_WAIT_INSTALL:
|
||||||
|
[self performUpgrade];
|
||||||
|
break;
|
||||||
|
case UPDATE_EXTRACTING:
|
||||||
|
case UPDATE_INSTALLING:
|
||||||
|
break;
|
||||||
|
case UPDATE_FAILED:
|
||||||
|
[self.updateProgressWindow close];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
if (_downloadDirectory) {
|
||||||
|
[[NSFileManager defaultManager] removeItemAtPath:_downloadDirectory error:nil];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction)nop:(id)sender
|
- (IBAction)nop:(id)sender
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -25,5 +25,6 @@
|
|||||||
@property (nonatomic, weak) IBOutlet NSPopUpButton *cgbPopupButton;
|
@property (nonatomic, weak) IBOutlet NSPopUpButton *cgbPopupButton;
|
||||||
@property (nonatomic, weak) IBOutlet NSPopUpButton *preferredJoypadButton;
|
@property (nonatomic, weak) IBOutlet NSPopUpButton *preferredJoypadButton;
|
||||||
@property (nonatomic, weak) IBOutlet NSPopUpButton *playerListButton;
|
@property (nonatomic, weak) IBOutlet NSPopUpButton *playerListButton;
|
||||||
|
@property (nonatomic, weak) IBOutlet NSButton *autoUpdatesCheckbox;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
NSPopUpButton *_rumbleModePopupButton;
|
NSPopUpButton *_rumbleModePopupButton;
|
||||||
NSSlider *_temperatureSlider;
|
NSSlider *_temperatureSlider;
|
||||||
NSSlider *_interferenceSlider;
|
NSSlider *_interferenceSlider;
|
||||||
|
NSButton *_autoUpdatesCheckbox;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)filterList
|
+ (NSArray *)filterList
|
||||||
@ -381,6 +383,12 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)changeAutoUpdates:(id)sender
|
||||||
|
{
|
||||||
|
[[NSUserDefaults standardUserDefaults] setBool: [(NSButton *)sender state] == NSOnState
|
||||||
|
forKey:@"GBAutoUpdatesEnabled"];
|
||||||
|
}
|
||||||
|
|
||||||
- (IBAction) configureJoypad:(id)sender
|
- (IBAction) configureJoypad:(id)sender
|
||||||
{
|
{
|
||||||
[self.configureJoypadButton setEnabled:NO];
|
[self.configureJoypadButton setEnabled:NO];
|
||||||
@ -705,4 +713,15 @@
|
|||||||
}
|
}
|
||||||
[[NSUserDefaults standardUserDefaults] setObject:default_joypads forKey:@"JoyKitDefaultControllers"];
|
[[NSUserDefaults standardUserDefaults] setObject:default_joypads forKey:@"JoyKitDefaultControllers"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSButton *)autoUpdatesCheckbox
|
||||||
|
{
|
||||||
|
return _autoUpdatesCheckbox;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAutoUpdatesCheckbox:(NSButton *)autoUpdatesCheckbox
|
||||||
|
{
|
||||||
|
_autoUpdatesCheckbox = autoUpdatesCheckbox;
|
||||||
|
[_autoUpdatesCheckbox setState: [[NSUserDefaults standardUserDefaults] boolForKey:@"GBAutoUpdatesEnabled"]];
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
<outlet property="emulationTab" destination="ymk-46-SX7" id="ofG-ca-a5C"/>
|
<outlet property="emulationTab" destination="ymk-46-SX7" id="ofG-ca-a5C"/>
|
||||||
<outlet property="graphicsTab" destination="sRK-wO-K6R" id="pfP-Di-i0Q"/>
|
<outlet property="graphicsTab" destination="sRK-wO-K6R" id="pfP-Di-i0Q"/>
|
||||||
<outlet property="preferencesWindow" destination="QvC-M9-y7g" id="kBg-fq-rZh"/>
|
<outlet property="preferencesWindow" destination="QvC-M9-y7g" id="kBg-fq-rZh"/>
|
||||||
|
<outlet property="updatesButton" destination="KnI-UA-Nlj" id="9Lw-d7-Qoj"/>
|
||||||
|
<outlet property="updatesSpinner" destination="fB8-sd-zrh" id="HbX-JT-8Su"/>
|
||||||
|
<outlet property="updatesTab" destination="ffn-ie-9C3" id="rti-eV-pIV"/>
|
||||||
</connections>
|
</connections>
|
||||||
</customObject>
|
</customObject>
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
@ -49,17 +52,24 @@
|
|||||||
<action selector="switchPreferencesTab:" target="-2" id="Tio-D7-PaA"/>
|
<action selector="switchPreferencesTab:" target="-2" id="Tio-D7-PaA"/>
|
||||||
</connections>
|
</connections>
|
||||||
</toolbarItem>
|
</toolbarItem>
|
||||||
|
<toolbarItem implicitItemIdentifier="EB7AB5BC-57B0-4639-A037-E28226866C80" label="Updates" paletteLabel="Updates" tag="4" image="AppIcon" autovalidates="NO" selectable="YES" id="lMV-68-ntz">
|
||||||
|
<connections>
|
||||||
|
<action selector="switchPreferencesTab:" target="-2" id="bfU-hc-FnN"/>
|
||||||
|
</connections>
|
||||||
|
</toolbarItem>
|
||||||
</allowedToolbarItems>
|
</allowedToolbarItems>
|
||||||
<defaultToolbarItems>
|
<defaultToolbarItems>
|
||||||
<toolbarItem reference="zdp-Z7-yZM"/>
|
<toolbarItem reference="zdp-Z7-yZM"/>
|
||||||
<toolbarItem reference="fCd-4a-SKR"/>
|
<toolbarItem reference="fCd-4a-SKR"/>
|
||||||
<toolbarItem reference="EMp-g1-eKu"/>
|
<toolbarItem reference="EMp-g1-eKu"/>
|
||||||
<toolbarItem reference="uNZ-j1-Dfx"/>
|
<toolbarItem reference="uNZ-j1-Dfx"/>
|
||||||
|
<toolbarItem reference="lMV-68-ntz"/>
|
||||||
</defaultToolbarItems>
|
</defaultToolbarItems>
|
||||||
</toolbar>
|
</toolbar>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="analogControlsCheckbox" destination="RuW-Db-dzW" id="FRE-hI-mnU"/>
|
<outlet property="analogControlsCheckbox" destination="RuW-Db-dzW" id="FRE-hI-mnU"/>
|
||||||
<outlet property="aspectRatioCheckbox" destination="Vfj-tg-7OP" id="Yw0-xS-DBr"/>
|
<outlet property="aspectRatioCheckbox" destination="Vfj-tg-7OP" id="Yw0-xS-DBr"/>
|
||||||
|
<outlet property="autoUpdatesCheckbox" destination="ZVh-ob-6wl" id="qPS-53-3aW"/>
|
||||||
<outlet property="bootROMsButton" destination="T3Y-Ln-Onl" id="tdL-Yv-E2K"/>
|
<outlet property="bootROMsButton" destination="T3Y-Ln-Onl" id="tdL-Yv-E2K"/>
|
||||||
<outlet property="bootROMsFolderItem" destination="Dzv-Gc-zoL" id="yhV-ZI-avD"/>
|
<outlet property="bootROMsFolderItem" destination="Dzv-Gc-zoL" id="yhV-ZI-avD"/>
|
||||||
<outlet property="cgbPopupButton" destination="dlD-sk-SHO" id="4tg-SR-e17"/>
|
<outlet property="cgbPopupButton" destination="dlD-sk-SHO" id="4tg-SR-e17"/>
|
||||||
@ -694,17 +704,6 @@
|
|||||||
<action selector="changeAnalogControls:" target="QvC-M9-y7g" id="1xR-gY-WKo"/>
|
<action selector="changeAnalogControls:" target="QvC-M9-y7g" id="1xR-gY-WKo"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qa7-Z7-yfO">
|
|
||||||
<rect key="frame" x="26" y="13" width="169" height="32"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<buttonCell key="cell" type="push" title="Configure a Controller" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="GdK-tQ-Wim">
|
|
||||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
|
||||||
<font key="font" metaFont="system"/>
|
|
||||||
</buttonCell>
|
|
||||||
<connections>
|
|
||||||
<action selector="configureJoypad:" target="QvC-M9-y7g" id="IfY-Kc-PKU"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d2I-jU-sLb">
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d2I-jU-sLb">
|
||||||
<rect key="frame" x="195" y="13" width="72" height="32"/>
|
<rect key="frame" x="195" y="13" width="72" height="32"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
@ -716,11 +715,56 @@
|
|||||||
<action selector="skipButton:" target="QvC-M9-y7g" id="aw8-sw-yJw"/>
|
<action selector="skipButton:" target="QvC-M9-y7g" id="aw8-sw-yJw"/>
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qa7-Z7-yfO">
|
||||||
|
<rect key="frame" x="27" y="13" width="172" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Configure a controller" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="GdK-tQ-Wim">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="configureJoypad:" target="QvC-M9-y7g" id="IfY-Kc-PKU"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
<point key="canvasLocation" x="-159" y="1161.5"/>
|
<point key="canvasLocation" x="-159" y="1161.5"/>
|
||||||
</customView>
|
</customView>
|
||||||
|
<customView id="ffn-ie-9C3">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="292" height="95"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZVh-ob-6wl">
|
||||||
|
<rect key="frame" x="18" y="59" width="256" height="18"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="check" title="Check for updates on launch" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="euw-4z-Urd">
|
||||||
|
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="changeAutoUpdates:" target="QvC-M9-y7g" id="MrL-Zh-0Cc"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<progressIndicator wantsLayer="YES" fixedFrame="YES" maxValue="100" displayedWhenStopped="NO" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="fB8-sd-zrh">
|
||||||
|
<rect key="frame" x="257" y="23" width="16" height="16"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
</progressIndicator>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="KnI-UA-Nlj">
|
||||||
|
<rect key="frame" x="14" y="13" width="240" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Check for updates now" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="j8a-EZ-Ef5">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="userCheckForUpdates:" target="-2" id="ACZ-SI-yTQ"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
</subviews>
|
||||||
|
<point key="canvasLocation" x="-825" y="699.5"/>
|
||||||
|
</customView>
|
||||||
</objects>
|
</objects>
|
||||||
<resources>
|
<resources>
|
||||||
|
<image name="AppIcon" width="128" height="128"/>
|
||||||
<image name="CPU" width="32" height="32"/>
|
<image name="CPU" width="32" height="32"/>
|
||||||
<image name="Display" width="32" height="32"/>
|
<image name="Display" width="32" height="32"/>
|
||||||
<image name="Joypad" width="32" height="32"/>
|
<image name="Joypad" width="32" height="32"/>
|
||||||
|
139
Cocoa/UpdateWindow.xib
Normal file
139
Cocoa/UpdateWindow.xib
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="macosx"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
|
||||||
|
<plugIn identifier="com.apple.WebKitIBPlugin" version="14868"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<customObject id="-2" userLabel="File's Owner" customClass="AppDelegate">
|
||||||
|
<connections>
|
||||||
|
<outlet property="updateChanges" destination="ATt-VM-cb5" id="hJj-Nd-FBv"/>
|
||||||
|
<outlet property="updateProgressButton" destination="7nO-AA-WmG" id="wTa-9l-cOG"/>
|
||||||
|
<outlet property="updateProgressLabel" destination="wIm-GX-c6B" id="URp-JG-6wR"/>
|
||||||
|
<outlet property="updateProgressSpinner" destination="fqq-Nb-THz" id="4vC-m5-ysO"/>
|
||||||
|
<outlet property="updateProgressWindow" destination="2Gy-QG-FoA" id="RXw-50-DQh"/>
|
||||||
|
<outlet property="updateWindow" destination="QvC-M9-y7g" id="iwP-kC-tmG"/>
|
||||||
|
</connections>
|
||||||
|
</customObject>
|
||||||
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
|
<window title="Update Available" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||||
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" resizable="YES"/>
|
||||||
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
|
<rect key="contentRect" x="196" y="240" width="480" height="360"/>
|
||||||
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||||
|
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xZt-UI-Wl2">
|
||||||
|
<rect key="frame" x="338" y="13" width="128" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Install Update" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Mav-rY-sJo">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<string key="keyEquivalent" base64-UTF8="YES">
|
||||||
|
DQ
|
||||||
|
</string>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="installUpdate:" target="-2" id="jJc-CY-4vz"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" id="b3S-YN-iDZ">
|
||||||
|
<rect key="frame" x="242" y="13" width="96" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Not Now" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="QsJ-cv-hwF">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="performClose:" target="QvC-M9-y7g" id="8qO-ac-k7U"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<button verticalHuggingPriority="750" id="uOb-4Q-S8o">
|
||||||
|
<rect key="frame" x="14" y="13" width="128" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Skip Version" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Ai5-6n-dvH">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="skipVersion:" target="-2" id="Jf8-Qe-6X0"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Swh-S6-6XA">
|
||||||
|
<rect key="frame" x="18" y="313" width="444" height="27"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="clipping" title="A new version of SameBoy is available with the following changes:" id="WsO-pC-VO7">
|
||||||
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="9Tu-Q3-l40">
|
||||||
|
<rect key="frame" x="0.0" y="302" width="480" height="5"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
|
</box>
|
||||||
|
<box verticalHuggingPriority="750" fixedFrame="YES" boxType="separator" translatesAutoresizingMaskIntoConstraints="NO" id="dva-Ay-nnl">
|
||||||
|
<rect key="frame" x="0.0" y="58" width="480" height="4"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
|
||||||
|
</box>
|
||||||
|
<webView maintainsBackForwardList="NO" id="ATt-VM-cb5">
|
||||||
|
<rect key="frame" x="0.0" y="61" width="480" height="243"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<webPreferences key="preferences" defaultFontSize="13" defaultFixedFontSize="13" minimumFontSize="0" plugInsEnabled="NO" javaEnabled="NO" javaScriptEnabled="NO" javaScriptCanOpenWindowsAutomatically="NO" loadsImagesAutomatically="NO" allowsAnimatedImages="NO" allowsAnimatedImageLooping="NO">
|
||||||
|
<nil key="identifier"/>
|
||||||
|
</webPreferences>
|
||||||
|
<connections>
|
||||||
|
<outlet property="UIDelegate" destination="-2" id="xQ1-eY-1hu"/>
|
||||||
|
<outlet property="frameLoadDelegate" destination="-2" id="BOf-df-5LR"/>
|
||||||
|
</connections>
|
||||||
|
</webView>
|
||||||
|
</subviews>
|
||||||
|
</view>
|
||||||
|
<point key="canvasLocation" x="217" y="267"/>
|
||||||
|
</window>
|
||||||
|
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" restorable="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="" animationBehavior="default" id="2Gy-QG-FoA">
|
||||||
|
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||||
|
<rect key="contentRect" x="283" y="305" width="512" height="61"/>
|
||||||
|
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
|
||||||
|
<view key="contentView" id="jjT-Z5-15Q">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="512" height="61"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<progressIndicator wantsLayer="YES" fixedFrame="YES" maxValue="100" displayedWhenStopped="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="fqq-Nb-THz">
|
||||||
|
<rect key="frame" x="20" y="15" width="32" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||||
|
</progressIndicator>
|
||||||
|
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="7nO-AA-WmG">
|
||||||
|
<rect key="frame" x="417" y="13" width="82" height="32"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMinY="YES"/>
|
||||||
|
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="6l6-qX-gsr">
|
||||||
|
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||||
|
<font key="font" metaFont="system"/>
|
||||||
|
<string key="keyEquivalent" base64-UTF8="YES">
|
||||||
|
Gw
|
||||||
|
</string>
|
||||||
|
</buttonCell>
|
||||||
|
<connections>
|
||||||
|
<action selector="updateAction:" target="-2" id="geO-Gk-xrs"/>
|
||||||
|
</connections>
|
||||||
|
</button>
|
||||||
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wIm-GX-c6B">
|
||||||
|
<rect key="frame" x="58" y="15" width="359" height="24"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
|
||||||
|
<textFieldCell key="cell" lineBreakMode="clipping" title="Downloading update..." id="qmF-X1-v5B">
|
||||||
|
<font key="font" usesAppearanceFont="YES"/>
|
||||||
|
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||||
|
</textFieldCell>
|
||||||
|
</textField>
|
||||||
|
</subviews>
|
||||||
|
</view>
|
||||||
|
<point key="canvasLocation" x="11" y="-203.5"/>
|
||||||
|
</window>
|
||||||
|
</objects>
|
||||||
|
</document>
|
3
Makefile
3
Makefile
@ -122,6 +122,9 @@ endif
|
|||||||
CFLAGS += $(WARNINGS)
|
CFLAGS += $(WARNINGS)
|
||||||
|
|
||||||
CFLAGS += -std=gnu11 -D_GNU_SOURCE -DVERSION="$(VERSION)" -I. -D_USE_MATH_DEFINES
|
CFLAGS += -std=gnu11 -D_GNU_SOURCE -DVERSION="$(VERSION)" -I. -D_USE_MATH_DEFINES
|
||||||
|
ifneq (,$(UPDATE_SUPPORT))
|
||||||
|
CFLAGS += -DUPDATE_SUPPORT
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq (,$(PKG_CONFIG))
|
ifeq (,$(PKG_CONFIG))
|
||||||
SDL_CFLAGS := $(shell sdl2-config --cflags)
|
SDL_CFLAGS := $(shell sdl2-config --cflags)
|
||||||
|
Loading…
Reference in New Issue
Block a user