mirror of
https://github.com/etlegacy/Update-Installer.git
synced 2025-02-25 04:11:02 +00:00
Add a Cocoa UI for the updater on Mac
* Link the updater application with the Cocoa framework on Mac * Construct a UI in code and display it when running the main install process. Usually UIs on Mac are contained in a .nib file created with Interface Builder but in this case the UI is created directly in code to meet the single-binary requirement, although it may be possible to bundle the .nib into the binary itself.
This commit is contained in:
parent
eeeafb2c1a
commit
ff21b77ec1
4 changed files with 178 additions and 5 deletions
|
@ -29,6 +29,9 @@ set (SOURCES
|
||||||
if (ENABLE_GTK)
|
if (ENABLE_GTK)
|
||||||
set(SOURCES ${SOURCES} UpdateDialogGtk.cpp)
|
set(SOURCES ${SOURCES} UpdateDialogGtk.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
if (APPLE)
|
||||||
|
set(SOURCES ${SOURCES} UpdateDialogCocoa.mm)
|
||||||
|
endif()
|
||||||
|
|
||||||
set (HEADERS
|
set (HEADERS
|
||||||
Dir.h
|
Dir.h
|
||||||
|
@ -43,6 +46,9 @@ set (HEADERS
|
||||||
if (ENABLE_GTK)
|
if (ENABLE_GTK)
|
||||||
set(HEADERS ${HEADERS} UpdateDialogGtk.h)
|
set(HEADERS ${HEADERS} UpdateDialogGtk.h)
|
||||||
endif()
|
endif()
|
||||||
|
if (APPLE)
|
||||||
|
set(SOURCES ${SOURCES} UpdateDialogCocoa.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(updatershared
|
add_library(updatershared
|
||||||
${SOURCES}
|
${SOURCES}
|
||||||
|
@ -73,7 +79,7 @@ add_executable(updater
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set_target_properties(
|
set_target_properties(
|
||||||
updater
|
updater
|
||||||
PROPERTIES LINK_FLAGS "-framework Security"
|
PROPERTIES LINK_FLAGS "-framework Security -framework Cocoa"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,25 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
class UpdateDialogCocoa
|
#include "UpdateObserver.h"
|
||||||
|
|
||||||
|
class UpdateDialogPrivate;
|
||||||
|
|
||||||
|
class UpdateDialogCocoa : public UpdateObserver
|
||||||
{
|
{
|
||||||
// TODO - Update dialog using Cocoa on Mac
|
public:
|
||||||
|
UpdateDialogCocoa();
|
||||||
|
~UpdateDialogCocoa();
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void exec();
|
||||||
|
|
||||||
|
// implements UpdateObserver
|
||||||
|
virtual void updateError(const std::string& errorMessage);
|
||||||
|
virtual bool updateRetryCancel(const std::string& message);
|
||||||
|
virtual void updateProgress(int percentage);
|
||||||
|
virtual void updateFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
UpdateDialogPrivate* d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
140
src/UpdateDialogCocoa.mm
Normal file
140
src/UpdateDialogCocoa.mm
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
#include "UpdateDialogCocoa.h"
|
||||||
|
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
#include "Log.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
@interface UpdateDialogDelegate : NSObject
|
||||||
|
{
|
||||||
|
@public UpdateDialogPrivate* dialog;
|
||||||
|
}
|
||||||
|
- (void) finishClicked;
|
||||||
|
- (void) reportUpdateError:(id)arg;
|
||||||
|
- (void) reportUpdateProgress:(id)arg;
|
||||||
|
- (void) reportUpdateFinished:(id)arg;
|
||||||
|
@end
|
||||||
|
|
||||||
|
class UpdateDialogPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UpdateDialogDelegate* delegate;
|
||||||
|
NSAutoreleasePool* pool;
|
||||||
|
NSWindow* window;
|
||||||
|
NSButton* finishButton;
|
||||||
|
NSTextField* progressLabel;
|
||||||
|
NSProgressIndicator* progressBar;
|
||||||
|
};
|
||||||
|
|
||||||
|
@implementation UpdateDialogDelegate
|
||||||
|
- (void) finishClicked
|
||||||
|
{
|
||||||
|
[NSApp stop:self];
|
||||||
|
}
|
||||||
|
- (void) reportUpdateError: (id)arg
|
||||||
|
{
|
||||||
|
NSMutableString* message;
|
||||||
|
[message appendString:@"There was a problem installing the update: "];
|
||||||
|
[message appendString:arg];
|
||||||
|
[dialog->progressLabel setTitleWithMnemonic: message];
|
||||||
|
}
|
||||||
|
- (void) reportUpdateProgress: (id)arg
|
||||||
|
{
|
||||||
|
int percentage = [arg intValue];
|
||||||
|
[dialog->progressBar setDoubleValue:(percentage/100.0)];
|
||||||
|
}
|
||||||
|
- (void) reportUpdateFinished: (id)arg
|
||||||
|
{
|
||||||
|
[dialog->progressLabel setTitleWithMnemonic:@"Updates installed. Click 'Finish' to restart the application."];
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
UpdateDialogCocoa::UpdateDialogCocoa()
|
||||||
|
: d(new UpdateDialogPrivate)
|
||||||
|
{
|
||||||
|
[NSApplication sharedApplication];
|
||||||
|
d->pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateDialogCocoa::~UpdateDialogCocoa()
|
||||||
|
{
|
||||||
|
[d->pool release];
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDialogCocoa::init()
|
||||||
|
{
|
||||||
|
d->delegate = [[UpdateDialogDelegate alloc] init];
|
||||||
|
d->delegate->dialog = d;
|
||||||
|
|
||||||
|
int width = 370;
|
||||||
|
int height = 100;
|
||||||
|
|
||||||
|
d->window = [[NSWindow alloc] initWithContentRect:NSMakeRect(200, 200, width, height)
|
||||||
|
styleMask:NSTitledWindowMask | NSClosableWindowMask |
|
||||||
|
NSMiniaturizableWindowMask
|
||||||
|
backing:NSBackingStoreBuffered defer:NO];
|
||||||
|
[d->window setTitle:@"Mendeley Updater"];
|
||||||
|
|
||||||
|
d->finishButton = [[NSButton alloc] init];
|
||||||
|
[d->finishButton setTitle:@"Finish"];
|
||||||
|
[d->finishButton setButtonType:NSMomentaryLightButton];
|
||||||
|
[d->finishButton setBezelStyle:NSRoundedBezelStyle];
|
||||||
|
[d->finishButton setTarget:d->delegate];
|
||||||
|
[d->finishButton setAction:@selector(finishClicked)];
|
||||||
|
|
||||||
|
d->progressBar = [[NSProgressIndicator alloc] init];
|
||||||
|
[d->progressBar setIndeterminate:false];
|
||||||
|
[d->progressBar setMinValue:0.0];
|
||||||
|
[d->progressBar setMaxValue:1.0];
|
||||||
|
|
||||||
|
d->progressLabel = [[NSTextField alloc] init];
|
||||||
|
[d->progressLabel setEditable:false];
|
||||||
|
[d->progressLabel setSelectable:false];
|
||||||
|
[d->progressLabel setTitleWithMnemonic:@"Installing Updates"];
|
||||||
|
[d->progressLabel setBezeled:false];
|
||||||
|
[d->progressLabel setDrawsBackground:false];
|
||||||
|
|
||||||
|
NSView* windowContent = [d->window contentView];
|
||||||
|
[windowContent addSubview:d->progressLabel];
|
||||||
|
[windowContent addSubview:d->progressBar];
|
||||||
|
[windowContent addSubview:d->finishButton];
|
||||||
|
|
||||||
|
[d->progressLabel setFrame:NSMakeRect(10,70,width - 10,20)];
|
||||||
|
[d->progressBar setFrame:NSMakeRect(10,40,width - 20,20)];
|
||||||
|
[d->finishButton setFrame:NSMakeRect(width - 85,5,80,30)];
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDialogCocoa::exec()
|
||||||
|
{
|
||||||
|
[d->window makeKeyAndOrderFront:d->window];
|
||||||
|
[d->window center];
|
||||||
|
[NSApp run];
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDialogCocoa::updateError(const std::string& errorMessage)
|
||||||
|
{
|
||||||
|
[d->delegate performSelectorOnMainThread:@selector(reportUpdateError:)
|
||||||
|
withObject:[NSString stringWithUTF8String:errorMessage.c_str()]
|
||||||
|
waitUntilDone:false];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UpdateDialogCocoa::updateRetryCancel(const std::string& message)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDialogCocoa::updateProgress(int percentage)
|
||||||
|
{
|
||||||
|
[d->delegate performSelectorOnMainThread:@selector(reportUpdateProgress:)
|
||||||
|
withObject:[NSNumber numberWithInt:percentage]
|
||||||
|
waitUntilDone:false];
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateDialogCocoa::updateFinished()
|
||||||
|
{
|
||||||
|
[d->delegate performSelectorOnMainThread:@selector(reportUpdateFinished:)
|
||||||
|
withObject:nil
|
||||||
|
waitUntilDone:false];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
13
src/main.cpp
13
src/main.cpp
|
@ -10,6 +10,10 @@
|
||||||
#include "UpdateDialogGtk.h"
|
#include "UpdateDialogGtk.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(PLATFORM_MAC)
|
||||||
|
#include "UpdateDialogCocoa.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void runWithUi(int argc, char** argv, UpdateInstaller* installer);
|
void runWithUi(int argc, char** argv, UpdateInstaller* installer);
|
||||||
|
@ -91,8 +95,13 @@ void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
||||||
#ifdef PLATFORM_MAC
|
#ifdef PLATFORM_MAC
|
||||||
void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
||||||
{
|
{
|
||||||
// TODO - Cocoa UI
|
UpdateDialogCocoa dialog;
|
||||||
installer->run();
|
installer->setObserver(&dialog);
|
||||||
|
dialog.init();
|
||||||
|
tthread::thread updaterThread(runUpdaterThread,installer);
|
||||||
|
dialog.exec();
|
||||||
|
updaterThread.join();
|
||||||
|
installer->restartMainApp();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue