Installation with Ctrl+I, fixes #77

This commit is contained in:
Simon Robertshaw 2012-08-10 15:41:39 +01:00
parent 643128ac5f
commit cd051924d9
8 changed files with 308 additions and 1 deletions

View File

@ -8,7 +8,15 @@
#include <stdio.h>
#include <deque>
#ifdef MACOSX
#include <mach-o/dyld.h>
#include <ApplicationServices/ApplicationServices.h>
#endif
#ifdef WIN
#include <shlobj.h>
#include <shlwapi.h>
#include <windows.h>
#include <direct.h>
#else
#include <sys/stat.h>
@ -124,6 +132,185 @@ void Client::Initialise(std::string proxyString)
versionCheckRequest = http_async_req_start(NULL, SERVER "/Download/Version.json", NULL, 0, 1);
}
bool Client::DoInstallation()
{
#if defined(WIN)
int returnval;
LONG rresult;
HKEY newkey;
char *currentfilename = exe_name();
char *iconname = NULL;
char *opencommand = NULL;
//char AppDataPath[MAX_PATH];
char *AppDataPath = NULL;
iconname = (char*)malloc(strlen(currentfilename)+6);
sprintf(iconname, "%s,-102", currentfilename);
//Create Roaming application data folder
/*if(!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, AppDataPath)))
{
returnval = 0;
goto finalise;
}*/
//AppDataPath = _getcwd(NULL, 0);
//Move Game executable into application data folder
//TODO: Implement
opencommand = (char*)malloc(strlen(currentfilename)+53+strlen(AppDataPath));
/*if((strlen(AppDataPath)+strlen(APPDATA_SUBDIR "\\Powder Toy"))<MAX_PATH)
{
strappend(AppDataPath, APPDATA_SUBDIR);
_mkdir(AppDataPath);
strappend(AppDataPath, "\\Powder Toy");
_mkdir(AppDataPath);
} else {
returnval = 0;
goto finalise;
}*/
sprintf(opencommand, "\"%s\" open \"%%1\" ddir \"%s\"", currentfilename, AppDataPath);
//Create extension entry
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.cps", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
if (rresult != ERROR_SUCCESS) {
returnval = 0;
goto finalise;
}
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
returnval = 0;
goto finalise;
}
RegCloseKey(newkey);
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\.stm", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
if (rresult != ERROR_SUCCESS) {
returnval = 0;
goto finalise;
}
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"PowderToySave", strlen("PowderToySave")+1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
returnval = 0;
goto finalise;
}
RegCloseKey(newkey);
//Create program entry
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
if (rresult != ERROR_SUCCESS) {
returnval = 0;
goto finalise;
}
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)"Powder Toy Save", strlen("Powder Toy Save")+1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
returnval = 0;
goto finalise;
}
RegCloseKey(newkey);
//Set DefaultIcon
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\DefaultIcon", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
if (rresult != ERROR_SUCCESS) {
returnval = 0;
goto finalise;
}
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)iconname, strlen(iconname)+1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
returnval = 0;
goto finalise;
}
RegCloseKey(newkey);
//Set Launch command
rresult = RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\PowderToySave\\shell\\open\\command", 0, 0, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, NULL);
if (rresult != ERROR_SUCCESS) {
returnval = 0;
goto finalise;
}
rresult = RegSetValueEx(newkey, 0, 0, REG_SZ, (LPBYTE)opencommand, strlen(opencommand)+1);
if (rresult != ERROR_SUCCESS) {
RegCloseKey(newkey);
returnval = 0;
goto finalise;
}
RegCloseKey(newkey);
returnval = 1;
finalise:
if(iconname) free(iconname);
if(opencommand) free(opencommand);
if(currentfilename) free(currentfilename);
return returnval;
#elif defined(LIN)
#include "icondoc.h"
char *currentfilename = exe_name();
FILE *f;
char *mimedata =
"<?xml version=\"1.0\"?>\n"
" <mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>\n"
" <mime-type type=\"application/vnd.powdertoy.save\">\n"
" <comment>Powder Toy save</comment>\n"
" <glob pattern=\"*.cps\"/>\n"
" <glob pattern=\"*.stm\"/>\n"
" </mime-type>\n"
"</mime-info>\n";
f = fopen("powdertoy-save.xml", "wb");
if (!f)
return 0;
fwrite(mimedata, 1, strlen(mimedata), f);
fclose(f);
char *desktopfiledata_tmp =
"[Desktop Entry]\n"
"Type=Application\n"
"Name=Powder Toy\n"
"Comment=Physics sandbox game\n"
"MimeType=application/vnd.powdertoy.save;\n"
"NoDisplay=true\n";
char *desktopfiledata = (char *)malloc(strlen(desktopfiledata_tmp)+strlen(currentfilename)+100);
strcpy(desktopfiledata, desktopfiledata_tmp);
strappend(desktopfiledata, "Exec=");
strappend(desktopfiledata, currentfilename);
strappend(desktopfiledata, " open %f\n");
f = fopen("powdertoy-tpt.desktop", "wb");
if (!f)
return 0;
fwrite(desktopfiledata, 1, strlen(desktopfiledata), f);
fclose(f);
system("xdg-mime install powdertoy-save.xml");
system("xdg-desktop-menu install powdertoy-tpt.desktop");
f = fopen("powdertoy-save-32.png", "wb");
if (!f)
return 0;
fwrite(icon_doc_32_png, 1, sizeof(icon_doc_32_png), f);
fclose(f);
f = fopen("powdertoy-save-16.png", "wb");
if (!f)
return 0;
fwrite(icon_doc_16_png, 1, sizeof(icon_doc_16_png), f);
fclose(f);
system("xdg-icon-resource install --noupdate --context mimetypes --size 32 powdertoy-save-32.png application-vnd.powdertoy.save");
system("xdg-icon-resource install --noupdate --context mimetypes --size 16 powdertoy-save-16.png application-vnd.powdertoy.save");
system("xdg-icon-resource forceupdate");
system("xdg-mime default powdertoy-tpt.desktop application/vnd.powdertoy.save");
unlink("powdertoy-save-32.png");
unlink("powdertoy-save-16.png");
unlink("powdertoy-save.xml");
unlink("powdertoy-tpt.desktop");
return true;
#elif defined MACOSX
return false;
#endif
}
void Client::SetProxy(std::string proxy)
{
http_done();

View File

@ -86,6 +86,8 @@ public:
std::vector<std::string> DirectorySearch(std::string directory, std::string search, std::vector<std::string> extensions);
std::vector<std::string> DirectorySearch(std::string directory, std::string search, std::string extension);
bool DoInstallation();
std::vector<unsigned char> ReadFile(std::string filename);
void Initialise(std::string proxyString);

View File

@ -46,7 +46,7 @@ ConfirmPrompt::ConfirmPrompt(std::string title, std::string message, ConfirmDial
};
ui::Button * cancelButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X-50, 16), "Cancel");
ui::Button * cancelButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X-75, 16), "Cancel");
cancelButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
cancelButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
cancelButton->Appearance.BorderInactive = ui::Colour(200, 200, 200);

View File

@ -0,0 +1,61 @@
/*
* InformationMessage.cpp
*
* Created on: Jan 29, 2012
* Author: Simon
*/
#include "Style.h"
#include "InformationMessage.h"
#include "interface/Button.h"
#include "interface/Label.h"
InformationMessage::InformationMessage(std::string title, std::string message):
ui::Window(ui::Point(-1, -1), ui::Point(200, 75))
{
ui::Label * titleLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 16), title);
titleLabel->SetTextColour(style::Colour::InformationTitle);
titleLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
titleLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
AddComponent(titleLabel);
ui::Label * messageLabel = new ui::Label(ui::Point(4, 24), ui::Point(Size.X-8, 60), message);
messageLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
messageLabel->Appearance.VerticalAlign = ui::Appearance::AlignTop;
AddComponent(messageLabel);
class DismissAction: public ui::ButtonAction
{
InformationMessage * message;
public:
DismissAction(InformationMessage * message_) { message = message_; }
void ActionCallback(ui::Button * sender)
{
ui::Engine::Ref().CloseWindow();
message->SelfDestruct(); //TODO: Fix component disposal
}
};
ui::Button * okayButton = new ui::Button(ui::Point(0, Size.Y-16), ui::Point(Size.X, 16), "Dismiss");
okayButton->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
okayButton->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
okayButton->Appearance.BorderInactive = ui::Colour(200, 200, 200);
okayButton->SetActionCallback(new DismissAction(this));
AddComponent(okayButton);
SetOkayButton(okayButton);
SetCancelButton(okayButton);
ui::Engine::Ref().ShowWindow(this);
}
void InformationMessage::OnDraw()
{
Graphics * g = ui::Engine::Ref().g;
g->clearrect(Position.X-2, Position.Y-2, Size.X+4, Size.Y+4);
g->drawrect(Position.X, Position.Y, Size.X, Size.Y, 200, 200, 200, 255);
}
InformationMessage::~InformationMessage() {
}

View File

@ -0,0 +1,20 @@
/*
* InformationMessage.h
*
* Created on: Jan 29, 2012
* Author: Simon
*/
#ifndef INFORMATIONMESSAGE_H_
#define INFORMATIONMESSAGE_H_
#include "interface/Window.h"
class InformationMessage: public ui::Window {
public:
InformationMessage(std::string title, std::string message);
virtual void OnDraw();
virtual ~InformationMessage();
};
#endif /* INFORMATIONMESSAGE_H_ */

View File

@ -10,6 +10,7 @@
#include "login/LoginController.h"
#include "interface/Point.h"
#include "dialogues/ErrorMessage.h"
#include "dialogues/InformationMessage.h"
#include "dialogues/ConfirmPrompt.h"
#include "GameModelException.h"
#include "simulation/Air.h"
@ -172,6 +173,36 @@ void GameController::PlaceSave(ui::Point position)
}
}
void GameController::Install()
{
#if defined(MACOSX)
new InformationMessage("No Installation necessary", "You don't need to install The Powder Toy on Mac OS X");
#elif defined(WIN) || defined(LIN)
class InstallConfirmation: public ConfirmDialogueCallback {
public:
GameController * c;
InstallConfirmation(GameController * c_) { c = c_; }
virtual void ConfirmCallback(ConfirmPrompt::DialogueResult result) {
if (result == ConfirmPrompt::ResultOkay)
{
if(Client::Ref().DoInstallation())
{
new InformationMessage("Install Success", "The installation completed without error");
}
else
{
new ErrorMessage("Could not install", "The installation did not complete due to an error");
}
}
}
virtual ~InstallConfirmation() { }
};
new ConfirmPrompt("Install The Powder Toy", "You are about to install The Powder Toy onto this computer", new InstallConfirmation(this));
#else
new ErrorMessage("Cannot install", "You cannot install The Powder Toy on this platform");
#endif
}
void GameController::AdjustBrushSize(int direction, bool logarithmic, bool xAxis, bool yAxis)
{
if(xAxis && yAxis)

View File

@ -63,6 +63,8 @@ public:
void Tick();
void Exit();
void Install();
void LoadRenderPreset(RenderPreset preset);
void SetZoomEnabled(bool zoomEnable);
void SetZoomPosition(ui::Point position);

View File

@ -1267,6 +1267,10 @@ void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool
case '[':
c->AdjustBrushSize(-1, !alt, shiftBehaviour, ctrlBehaviour);
break;
case 'i':
if(ctrl)
c->Install();
break;
}
if(key >= '0' && key <= '9')