| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| set(STORYBOARDS Main.storyboard) | ||
|
|
||
| set(SOURCES | ||
| main.m | ||
| AppDelegate.h | ||
| AppDelegate.mm | ||
| ViewController.h | ||
| ViewController.m | ||
| UI.h | ||
| UI.mm | ||
| ${STORYBOARDS} | ||
| ) | ||
|
|
||
| add_executable(MacUpdater ${SOURCES}) | ||
|
|
||
| set(MacUpdater_NAME "Dolphin Updater") | ||
|
|
||
| set_target_properties(MacUpdater PROPERTIES | ||
| MACOSX_BUNDLE true | ||
| MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in | ||
| OUTPUT_NAME ${MacUpdater_NAME}) | ||
|
|
||
| target_compile_options(MacUpdater PRIVATE -x objective-c++) | ||
|
|
||
| # Copy icon into the bundle | ||
| target_sources(MacUpdater PRIVATE "${CMAKE_SOURCE_DIR}/Data/Dolphin.icns") | ||
| set_source_files_properties("${CMAKE_SOURCE_DIR}/Data/Dolphin.icns" PROPERTIES MACOSX_PACKAGE_LOCATION Resources) | ||
|
|
||
| target_link_libraries(MacUpdater PRIVATE | ||
| "-framework Cocoa" | ||
| "-framework AppKit" | ||
| "-framework CoreData" | ||
| "-framework Foundation" | ||
| uicommon | ||
| mbedtls | ||
| z | ||
| ed25519 | ||
| ) | ||
|
|
||
| # Compile storyboards (Adapted from https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/OSX-InterfaceBuilderFiles) | ||
|
|
||
| # Make sure we can find the 'ibtool' program. If we can NOT find it we | ||
| # skip generation of this project | ||
| find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin") | ||
| if (${IBTOOL} STREQUAL "IBTOOL-NOTFOUND") | ||
| message(SEND_ERROR "ibtool can not be found and is needed to compile the .storyboard files. It should have been installed with | ||
| the Apple developer tools. The default system paths were searched in addition to ${OSX_DEVELOPER_ROOT}/usr/bin") | ||
| endif() | ||
|
|
||
| foreach(sb ${STORYBOARDS}) | ||
| set(MacUpdater_BIN_DIR ${CMAKE_BINARY_DIR}/Binaries) | ||
|
|
||
| if (CMAKE_GENERATOR STREQUAL Xcode) | ||
| string(APPEND MacUpdater_BIN_DIR "/\${CONFIGURATION}") | ||
| endif() | ||
|
|
||
| add_custom_command(TARGET MacUpdater POST_BUILD | ||
| COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text | ||
| --compile ${MacUpdater_BIN_DIR}/${MacUpdater_NAME}.app/Contents/Resources/${sb}c | ||
| ${CMAKE_CURRENT_SOURCE_DIR}/${sb} | ||
| COMMENT "Compiling Storyboard ${sb}...") | ||
| endforeach() | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| <plist version="1.0"> | ||
| <dict> | ||
| <key>CFBundleDevelopmentRegion</key> | ||
| <string>English</string> | ||
| <key>CFBundleExecutable</key> | ||
| <string>${MacUpdater_NAME}</string> | ||
| <key>CFBundleIconFile</key> | ||
| <string>Dolphin.icns</string> | ||
| <key>CFBundleIdentifier</key> | ||
| <string>com.dolphinteam.dolphin-updater</string> | ||
| <key>CFBundleInfoDictionaryVersion</key> | ||
| <string>6.0</string> | ||
| <key>CFBundleName</key> | ||
| <string>Updater</string> | ||
| <key>CFBundlePackageType</key> | ||
| <string>APPL</string> | ||
| <key>CFBundleShortVersionString</key> | ||
| <string>1.0</string> | ||
| <key>CFBundleVersion</key> | ||
| <string>1</string> | ||
| <key>LSMinimumSystemVersion</key> | ||
| <string>10.9</string> | ||
| <key>NSHumanReadableCopyright</key> | ||
| <string>Licensed under GPL version 2 or later (GPLv2+)</string> | ||
| <key>NSMainStoryboardFile</key> | ||
| <string>Main</string> | ||
| <key>NSPrincipalClass</key> | ||
| <string>NSApplication</string> | ||
| </dict> | ||
| </plist> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS"> | ||
| <dependencies> | ||
| <deployment version="101000" identifier="macosx"/> | ||
| <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/> | ||
| <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
| </dependencies> | ||
| <scenes> | ||
| <!--Application--> | ||
| <scene sceneID="JPo-4y-FX3"> | ||
| <objects> | ||
| <application id="hnw-xV-0zn" sceneMemberID="viewController"> | ||
| <menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6"> | ||
| <items> | ||
| <menuItem title="Updater" id="1Xt-HY-uBw"> | ||
| <modifierMask key="keyEquivalentModifierMask"/> | ||
| <menu key="submenu" title="Updater" systemMenu="apple" id="uQy-DD-JDr"> | ||
| <items> | ||
| <menuItem title="About Updater" id="5kV-Vb-QxS"> | ||
| <modifierMask key="keyEquivalentModifierMask"/> | ||
| <connections> | ||
| <action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/> | ||
| </connections> | ||
| </menuItem> | ||
| <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/> | ||
| <menuItem title="Quit Updater" keyEquivalent="q" id="4sb-4s-VLi"> | ||
| <connections> | ||
| <action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/> | ||
| </connections> | ||
| </menuItem> | ||
| </items> | ||
| </menu> | ||
| </menuItem> | ||
| </items> | ||
| </menu> | ||
| <connections> | ||
| <outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/> | ||
| </connections> | ||
| </application> | ||
| <customObject id="Voe-Tx-rLC" customClass="AppDelegate"/> | ||
| <customObject id="YLy-65-1bz" customClass="NSFontManager"/> | ||
| <customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> | ||
| </objects> | ||
| <point key="canvasLocation" x="75" y="0.0"/> | ||
| </scene> | ||
| <!--Window Controller--> | ||
| <scene sceneID="R2V-B0-nI4"> | ||
| <objects> | ||
| <windowController id="B8D-0N-5wS" sceneMemberID="viewController"> | ||
| <window key="window" title="Dolphin Updater" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" titlebarAppearsTransparent="YES" id="IQv-IB-iLA"> | ||
| <windowStyleMask key="styleMask" titled="YES"/> | ||
| <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> | ||
| <rect key="contentRect" x="196" y="240" width="480" height="270"/> | ||
| <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/> | ||
| <connections> | ||
| <outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/> | ||
| </connections> | ||
| </window> | ||
| <connections> | ||
| <segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/> | ||
| </connections> | ||
| </windowController> | ||
| <customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> | ||
| </objects> | ||
| <point key="canvasLocation" x="75" y="250"/> | ||
| </scene> | ||
| <!--View Controller--> | ||
| <scene sceneID="hIz-AP-VOD"> | ||
| <objects> | ||
| <viewController id="XfG-lQ-9wD" customClass="ViewController" sceneMemberID="viewController"> | ||
| <view key="view" wantsLayer="YES" id="m2S-Jp-Qdl"> | ||
| <rect key="frame" x="0.0" y="0.0" width="480" height="120"/> | ||
| <autoresizingMask key="autoresizingMask"/> | ||
| <subviews> | ||
| <progressIndicator identifier="progressTotal" wantsLayer="YES" fixedFrame="YES" maxValue="100" style="bar" translatesAutoresizingMaskIntoConstraints="NO" id="oLS-AW-V72"> | ||
| <rect key="frame" x="20" y="81" width="440" height="20"/> | ||
| <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> | ||
| </progressIndicator> | ||
| <progressIndicator identifier="progressCurrent" wantsLayer="YES" fixedFrame="YES" maxValue="100" indeterminate="YES" style="bar" translatesAutoresizingMaskIntoConstraints="NO" id="mni-rL-166"> | ||
| <rect key="frame" x="20" y="39" width="440" height="20"/> | ||
| <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> | ||
| </progressIndicator> | ||
| <textField identifier="labelProgress" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r87-pn-Exw" userLabel="Label"> | ||
| <rect key="frame" x="18" y="15" width="444" height="17"/> | ||
| <autoresizingMask key="autoresizingMask"/> | ||
| <textFieldCell key="cell" lineBreakMode="clipping" title="Initializing..." id="FBK-Tz-5cA"> | ||
| <font key="font" usesAppearanceFont="YES"/> | ||
| <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> | ||
| <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> | ||
| </textFieldCell> | ||
| <connections> | ||
| <action selector="progressLabel:" target="XfG-lQ-9wD" id="PDs-H5-idS"/> | ||
| </connections> | ||
| </textField> | ||
| </subviews> | ||
| </view> | ||
| <connections> | ||
| <outlet property="foo" destination="r87-pn-Exw" id="i76-Sg-K3o"/> | ||
| <outlet property="labelProgress" destination="r87-pn-Exw" id="v6b-r7-3lR"/> | ||
| <outlet property="progressCurrent" destination="mni-rL-166" id="A3C-wp-83j"/> | ||
| <outlet property="progressTotal" destination="oLS-AW-V72" id="pwo-CZ-XyN"/> | ||
| </connections> | ||
| </viewController> | ||
| <customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> | ||
| </objects> | ||
| <point key="canvasLocation" x="75" y="647"/> | ||
| </scene> | ||
| </scenes> | ||
| </document> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| // Copyright 2019 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <string> | ||
|
|
||
| namespace UI | ||
| { | ||
| void Error(const std::string& text); | ||
|
|
||
| void SetVisible(bool visible); | ||
|
|
||
| void SetDescription(const std::string& text); | ||
|
|
||
| void SetTotalMarquee(bool marquee); | ||
| void ResetTotalProgress(); | ||
| void SetTotalProgress(int current, int total); | ||
|
|
||
| void SetCurrentMarquee(bool marquee); | ||
| void ResetCurrentProgress(); | ||
| void SetCurrentProgress(int current, int total); | ||
| } // namespace UI |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| // Copyright 2019 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #include "MacUpdater/UI.h" | ||
| #include "MacUpdater/ViewController.h" | ||
|
|
||
| #include <Cocoa/Cocoa.h> | ||
|
|
||
| #include <functional> | ||
|
|
||
| // When we call from the main thread, we are not allowed to use | ||
| // dispatch_sync(dispatch_get_main_queue() as it will cause crashes) To prevent this check if we're | ||
| // already on the main thread first | ||
| void run_on_main(std::function<void()> fnc) | ||
| { | ||
| if (![NSThread isMainThread]) | ||
| { | ||
| dispatch_sync(dispatch_get_main_queue(), ^{ | ||
| fnc(); | ||
| }); | ||
| } | ||
| else | ||
| { | ||
| fnc(); | ||
| } | ||
| } | ||
|
|
||
| NSWindow* GetWindow() | ||
| { | ||
| return [[[NSApplication sharedApplication] windows] objectAtIndex:0]; | ||
| } | ||
|
|
||
| ViewController* GetView() | ||
| { | ||
| return (ViewController*)GetWindow().contentViewController; | ||
| } | ||
|
|
||
| void UI::Error(const std::string& text) | ||
| { | ||
| run_on_main([&] { | ||
| NSAlert* alert = [[[NSAlert alloc] init] autorelease]; | ||
|
|
||
| [alert setMessageText:@"Fatal error"]; | ||
| [alert | ||
| setInformativeText:[NSString stringWithCString:text.c_str() encoding:NSUTF8StringEncoding]]; | ||
| [alert setAlertStyle:NSAlertStyleCritical]; | ||
|
|
||
| [alert beginSheetModalForWindow:GetWindow() | ||
| completionHandler:^(NSModalResponse) { | ||
| [NSApp performSelector:@selector(terminate:) withObject:nil afterDelay:0.0]; | ||
| }]; | ||
| }); | ||
| } | ||
|
|
||
| void UI::SetVisible(bool visible) | ||
| { | ||
| run_on_main([&] { | ||
| if (visible) | ||
| { | ||
| [NSApp unhide:nil]; | ||
| [NSApp activateIgnoringOtherApps:YES]; | ||
| } | ||
| else | ||
| { | ||
| [NSApp hide:nil]; | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| void UI::SetDescription(const std::string& text) | ||
| { | ||
| run_on_main([&] { | ||
| [GetView() | ||
| SetDescription:[NSString stringWithCString:text.c_str() encoding:NSUTF8StringEncoding]]; | ||
| }); | ||
| } | ||
|
|
||
| void UI::SetTotalMarquee(bool marquee) | ||
| { | ||
| run_on_main([marquee] { [GetView() SetTotalMarquee:marquee]; }); | ||
| } | ||
|
|
||
| void UI::SetCurrentMarquee(bool marquee) | ||
| { | ||
| run_on_main([&] { [GetView() SetCurrentMarquee:marquee]; }); | ||
| } | ||
|
|
||
| void UI::ResetTotalProgress() | ||
| { | ||
| run_on_main([] { SetTotalProgress(0, 1); }); | ||
| } | ||
|
|
||
| void UI::ResetCurrentProgress() | ||
| { | ||
| run_on_main([] { SetCurrentProgress(0, 1); }); | ||
| } | ||
|
|
||
| void UI::SetCurrentProgress(int current, int total) | ||
| { | ||
| run_on_main([&] { [GetView() SetCurrentProgress:(double)current total:(double)total]; }); | ||
| } | ||
|
|
||
| void UI::SetTotalProgress(int current, int total) | ||
| { | ||
| run_on_main([&] { [GetView() SetTotalProgress:(double)current total:(double)total]; }); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // Copyright 2019 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #import <Cocoa/Cocoa.h> | ||
|
|
||
| @interface ViewController : NSViewController | ||
|
|
||
| @property(assign) IBOutlet NSProgressIndicator* progressCurrent; | ||
| @property(assign) IBOutlet NSProgressIndicator* progressTotal; | ||
| @property(assign) IBOutlet NSTextField* labelProgress; | ||
|
|
||
| - (void)SetDescription:(NSString*)string; | ||
|
|
||
| - (void)SetTotalMarquee:(bool)marquee; | ||
| - (void)SetCurrentMarquee:(bool)marquee; | ||
|
|
||
| - (void)SetTotalProgress:(double)current total:(double)total; | ||
| - (void)SetCurrentProgress:(double)current total:(double)total; | ||
|
|
||
| @end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| // Copyright 2019 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #import "ViewController.h" | ||
|
|
||
| @implementation ViewController | ||
|
|
||
| - (void)viewDidLoad | ||
| { | ||
| [super viewDidLoad]; | ||
| NSWindow* window = [[self view] window]; | ||
|
|
||
| [window setLevel:kCGMainMenuWindowLevel - 1]; | ||
| [window setCollectionBehavior:NSWindowCollectionBehaviorStationary | | ||
| NSWindowCollectionBehaviorCanJoinAllSpaces | | ||
| NSWindowCollectionBehaviorFullScreenAuxiliary]; | ||
| } | ||
|
|
||
| - (void)SetDescription:(NSString*)string | ||
| { | ||
| [_labelProgress setStringValue:string]; | ||
| } | ||
|
|
||
| - (void)SetTotalMarquee:(bool)marquee | ||
| { | ||
| [_progressTotal setIndeterminate:marquee]; | ||
| } | ||
|
|
||
| - (void)SetCurrentMarquee:(bool)marquee | ||
| { | ||
| [_progressCurrent setIndeterminate:marquee]; | ||
| } | ||
|
|
||
| - (void)SetTotalProgress:(double)current total:(double)total | ||
| { | ||
| [_progressTotal setMaxValue:total]; | ||
| [_progressTotal setDoubleValue:current]; | ||
| } | ||
|
|
||
| - (void)SetCurrentProgress:(double)current total:(double)total | ||
| { | ||
| [_progressCurrent setMaxValue:total]; | ||
| [_progressCurrent setDoubleValue:current]; | ||
| } | ||
|
|
||
| - (void)setRepresentedObject:(id)representedObject | ||
| { | ||
| [super setRepresentedObject:representedObject]; | ||
| } | ||
|
|
||
| @end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // Copyright 2019 Dolphin Emulator Project | ||
| // Licensed under GPLv2+ | ||
| // Refer to the license.txt file included. | ||
|
|
||
| #include <Cocoa/Cocoa.h> | ||
|
|
||
| int main(int argc, const char** argv) | ||
| { | ||
| if (argc == 1) | ||
| { | ||
| NSAlert* alert = [[[NSAlert alloc] init] autorelease]; | ||
|
|
||
| [alert setMessageText:@"This updater is not meant to be launched directly."]; | ||
| [alert setAlertStyle:NSAlertStyleWarning]; | ||
| [alert setInformativeText:@"Configure Auto-Update in Dolphin's settings instead."]; | ||
| [alert runModal]; | ||
|
|
||
| return 1; | ||
| } | ||
|
|
||
| return NSApplicationMain(argc, argv); | ||
| } |