mirror of
https://github.com/etlegacy/Update-Installer.git
synced 2024-11-10 06:31:49 +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)
|
||||
set(SOURCES ${SOURCES} UpdateDialogGtk.cpp)
|
||||
endif()
|
||||
if (APPLE)
|
||||
set(SOURCES ${SOURCES} UpdateDialogCocoa.mm)
|
||||
endif()
|
||||
|
||||
set (HEADERS
|
||||
Dir.h
|
||||
|
@ -43,6 +46,9 @@ set (HEADERS
|
|||
if (ENABLE_GTK)
|
||||
set(HEADERS ${HEADERS} UpdateDialogGtk.h)
|
||||
endif()
|
||||
if (APPLE)
|
||||
set(SOURCES ${SOURCES} UpdateDialogCocoa.h)
|
||||
endif()
|
||||
|
||||
add_library(updatershared
|
||||
${SOURCES}
|
||||
|
@ -73,7 +79,7 @@ add_executable(updater
|
|||
if(APPLE)
|
||||
set_target_properties(
|
||||
updater
|
||||
PROPERTIES LINK_FLAGS "-framework Security"
|
||||
PROPERTIES LINK_FLAGS "-framework Security -framework Cocoa"
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -1,7 +1,25 @@
|
|||
#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"
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_MAC)
|
||||
#include "UpdateDialogCocoa.h"
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void runWithUi(int argc, char** argv, UpdateInstaller* installer);
|
||||
|
@ -91,8 +95,13 @@ void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
|||
#ifdef PLATFORM_MAC
|
||||
void runWithUi(int argc, char** argv, UpdateInstaller* installer)
|
||||
{
|
||||
// TODO - Cocoa UI
|
||||
installer->run();
|
||||
UpdateDialogCocoa dialog;
|
||||
installer->setObserver(&dialog);
|
||||
dialog.init();
|
||||
tthread::thread updaterThread(runUpdaterThread,installer);
|
||||
dialog.exec();
|
||||
updaterThread.join();
|
||||
installer->restartMainApp();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue