aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Tkachev2019-07-18 23:10:49 +0700
committerMatan Bareket2019-07-30 14:51:41 -0400
commit99c2418d1a270c4496b21d6d6c8035b6ef73e8a1 (patch)
tree6670b93b28b24080a8ec40286cbf49804cdd91d9
parent31628d642881499f7d6833732b096c028087e14e (diff)
downloadscummvm-rg350-99c2418d1a270c4496b21d6d6c8035b6ef73e8a1.tar.gz
scummvm-rg350-99c2418d1a270c4496b21d6d6c8035b6ef73e8a1.tar.bz2
scummvm-rg350-99c2418d1a270c4496b21d6d6c8035b6ef73e8a1.zip
GUI: Rewrite Cloud tab
- StorageWizardDialog is removed, along with bmps it was using; - EditTextWidget now accepts custom font in constructor; - ScrollContainer scrollbar now jumps to top when content height changes so it's "overscrolled"; - IndexPageHandler now does not awaits for `code` GET-parameter, as local webserver is no longer used to connect Storages; - CloudManager and all corresponding Storages are updated to support disconnecting and to notify about successful connection.
-rw-r--r--backends/cloud/basestorage.cpp21
-rw-r--r--backends/cloud/basestorage.h6
-rw-r--r--backends/cloud/box/boxstorage.cpp9
-rw-r--r--backends/cloud/box/boxstorage.h7
-rw-r--r--backends/cloud/cloudmanager.cpp52
-rw-r--r--backends/cloud/cloudmanager.h10
-rw-r--r--backends/cloud/dropbox/dropboxstorage.cpp8
-rw-r--r--backends/cloud/dropbox/dropboxstorage.h7
-rw-r--r--backends/cloud/googledrive/googledrivestorage.cpp9
-rw-r--r--backends/cloud/googledrive/googledrivestorage.h7
-rw-r--r--backends/cloud/onedrive/onedrivestorage.cpp9
-rw-r--r--backends/cloud/onedrive/onedrivestorage.h7
-rw-r--r--backends/networking/sdl_net/handlers/indexpagehandler.cpp32
-rw-r--r--backends/networking/sdl_net/handlers/indexpagehandler.h2
-rw-r--r--gui/ThemeEngine.cpp4
-rw-r--r--gui/ThemeEngine.h4
-rw-r--r--gui/module.mk3
-rw-r--r--gui/options.cpp397
-rw-r--r--gui/options.h23
-rw-r--r--gui/storagewizarddialog.cpp224
-rw-r--r--gui/storagewizarddialog.h83
-rw-r--r--gui/themes/scummclassic.zipbin131213 -> 135889 bytes
-rw-r--r--gui/themes/scummclassic/classic_layout.stx229
-rw-r--r--gui/themes/scummclassic/classic_layout_lowres.stx233
-rw-r--r--gui/themes/scummmodern.zipbin407826 -> 264656 bytes
-rw-r--r--gui/themes/scummmodern/box.bmpbin35806 -> 0 bytes
-rw-r--r--gui/themes/scummmodern/dropbox.bmpbin35806 -> 0 bytes
-rw-r--r--gui/themes/scummmodern/googledrive.bmpbin35806 -> 0 bytes
-rw-r--r--gui/themes/scummmodern/onedrive.bmpbin35806 -> 0 bytes
-rw-r--r--gui/themes/scummmodern/scummmodern_gfx.stx4
-rw-r--r--gui/themes/scummmodern/scummmodern_layout.stx229
-rw-r--r--gui/themes/scummmodern/scummmodern_layout_lowres.stx233
-rw-r--r--gui/themes/scummremastered.zipbin407763 -> 264593 bytes
-rw-r--r--gui/themes/scummremastered/box.bmpbin35806 -> 0 bytes
-rw-r--r--gui/themes/scummremastered/dropbox.bmpbin35806 -> 0 bytes
-rw-r--r--gui/themes/scummremastered/googledrive.bmpbin35806 -> 0 bytes
-rw-r--r--gui/themes/scummremastered/onedrive.bmpbin35806 -> 0 bytes
-rw-r--r--gui/themes/scummremastered/remastered_gfx.stx4
-rw-r--r--gui/themes/scummremastered/remastered_layout.stx229
-rw-r--r--gui/themes/scummremastered/remastered_layout_lowres.stx233
-rw-r--r--gui/widgets/edittext.cpp8
-rw-r--r--gui/widgets/edittext.h4
-rw-r--r--gui/widgets/scrollcontainer.cpp1
43 files changed, 1142 insertions, 1189 deletions
diff --git a/backends/cloud/basestorage.cpp b/backends/cloud/basestorage.cpp
index 805cb472a2..bb198120ff 100644
--- a/backends/cloud/basestorage.cpp
+++ b/backends/cloud/basestorage.cpp
@@ -37,18 +37,19 @@ BaseStorage::BaseStorage(Common::String token, Common::String refreshToken):
BaseStorage::~BaseStorage() {}
-void BaseStorage::getAccessToken(Common::String code) {
- Networking::JsonCallback callback = new Common::Callback<BaseStorage, Networking::JsonResponse>(this, &BaseStorage::codeFlowComplete);
- Networking::ErrorCallback errorCallback = new Common::Callback<BaseStorage, Networking::ErrorResponse>(this, &BaseStorage::codeFlowFailed);
+void BaseStorage::getAccessToken(Common::String code, Networking::ErrorCallback callback) {
+ Networking::JsonCallback innerCallback = new Common::CallbackBridge<BaseStorage, Networking::ErrorResponse, Networking::JsonResponse>(this, &BaseStorage::codeFlowComplete, callback);
+ Networking::ErrorCallback errorCallback = new Common::CallbackBridge<BaseStorage, Networking::ErrorResponse, Networking::ErrorResponse>(this, &BaseStorage::codeFlowFailed, callback);
Common::String url = Common::String::format("https://cloud.scummvm.org/%s/token/%s", cloudProvider().c_str(), code.c_str());
- Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(callback, errorCallback, url);
+ Networking::CurlJsonRequest *request = new Networking::CurlJsonRequest(innerCallback, errorCallback, url);
addRequest(request);
}
-void BaseStorage::codeFlowComplete(Networking::JsonResponse response) {
+void BaseStorage::codeFlowComplete(Networking::ErrorCallback callback, Networking::JsonResponse response) {
bool success = true;
+ Common::String callbackMessage = "OK";
Common::JSONValue *json = (Common::JSONValue *)response.value;
if (json == nullptr) {
@@ -78,6 +79,7 @@ void BaseStorage::codeFlowComplete(Networking::JsonResponse response) {
}
warning("BaseStorage: response says error occurred: %s", errorMessage.c_str());
success = false;
+ callbackMessage = errorMessage;
}
if (success && !Networking::CurlJsonRequest::jsonContainsObject(result, "oauth", "BaseStorage::codeFlowComplete")) {
@@ -110,13 +112,20 @@ void BaseStorage::codeFlowComplete(Networking::JsonResponse response) {
if (!success)
CloudMan.removeStorage(this);
+ if (callback)
+ (*callback)(Networking::ErrorResponse(nullptr, false, !success, callbackMessage, -1));
delete json;
+ delete callback;
}
-void BaseStorage::codeFlowFailed(Networking::ErrorResponse error) {
+void BaseStorage::codeFlowFailed(Networking::ErrorCallback callback, Networking::ErrorResponse error) {
debug(9, "BaseStorage: code flow failed (%s, %ld):", (error.failed ? "failed" : "interrupted"), error.httpResponseCode);
debug(9, "%s", error.response.c_str());
CloudMan.removeStorage(this);
+
+ if (callback)
+ (*callback)(error);
+ delete callback;
}
void BaseStorage::refreshAccessToken(BoolCallback callback, Networking::ErrorCallback errorCallback) {
diff --git a/backends/cloud/basestorage.h b/backends/cloud/basestorage.h
index 243e7f4bcc..aae1a6ec2f 100644
--- a/backends/cloud/basestorage.h
+++ b/backends/cloud/basestorage.h
@@ -37,19 +37,19 @@ protected:
* Gets token from cloud.scummvm.org using given code.
* Base implementation for storages with common auth procedure.
*/
- virtual void getAccessToken(Common::String code);
+ virtual void getAccessToken(Common::String code, Networking::ErrorCallback callback);
/**
* Handles JSON response which should contain access token requested
* with getAccessToken().
*/
- virtual void codeFlowComplete(Networking::JsonResponse response);
+ virtual void codeFlowComplete(Networking::ErrorCallback callback, Networking::JsonResponse response);
/**
* Handles network errors occurred while getting access token requested
* with getAccessToken().
*/
- virtual void codeFlowFailed(Networking::ErrorResponse error);
+ virtual void codeFlowFailed(Networking::ErrorCallback callback, Networking::ErrorResponse error);
/**
* Return cloud provider name, used in cloud.scummvm.org endpoints.
diff --git a/backends/cloud/box/boxstorage.cpp b/backends/cloud/box/boxstorage.cpp
index f76fa3ac23..13046a08e0 100644
--- a/backends/cloud/box/boxstorage.cpp
+++ b/backends/cloud/box/boxstorage.cpp
@@ -45,8 +45,8 @@ namespace Box {
BoxStorage::BoxStorage(Common::String token, Common::String refreshToken):
IdStorage(token, refreshToken) {}
-BoxStorage::BoxStorage(Common::String code) {
- getAccessToken(code);
+BoxStorage::BoxStorage(Common::String code, Networking::ErrorCallback cb) {
+ getAccessToken(code, cb);
}
BoxStorage::~BoxStorage() {}
@@ -227,6 +227,11 @@ BoxStorage *BoxStorage::loadFromConfig(Common::String keyPrefix) {
return new BoxStorage(accessToken, refreshToken);
}
+void BoxStorage::removeFromConfig(Common::String keyPrefix) {
+ ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain);
+ ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain);
+}
+
Common::String BoxStorage::getRootDirectoryId() {
return "0";
}
diff --git a/backends/cloud/box/boxstorage.h b/backends/cloud/box/boxstorage.h
index a8fd32c404..ce77192bfa 100644
--- a/backends/cloud/box/boxstorage.h
+++ b/backends/cloud/box/boxstorage.h
@@ -55,7 +55,7 @@ protected:
public:
/** This constructor uses OAuth code flow to get tokens. */
- BoxStorage(Common::String code);
+ BoxStorage(Common::String code, Networking::ErrorCallback cb);
virtual ~BoxStorage();
/**
@@ -104,6 +104,11 @@ public:
*/
static BoxStorage *loadFromConfig(Common::String keyPrefix);
+ /**
+ * Remove all BoxStorage-related data from config.
+ */
+ static void removeFromConfig(Common::String keyPrefix);
+
virtual Common::String getRootDirectoryId();
Common::String accessToken() const { return _token; }
diff --git a/backends/cloud/cloudmanager.cpp b/backends/cloud/cloudmanager.cpp
index 20c279323c..432a63b040 100644
--- a/backends/cloud/cloudmanager.cpp
+++ b/backends/cloud/cloudmanager.cpp
@@ -148,6 +148,12 @@ void CloudManager::replaceStorage(Storage *storage, uint32 index) {
}
_activeStorage = storage;
_currentStorageIndex = index;
+ if (_storages[index].username == "") {
+ // options' Cloud tab believes Storage is connected once it has non-empty username
+ _storages[index].username = _("<syncing...>");
+ _storages[index].lastSyncDate = _("<right now>");
+ _storages[index].usedBytes = 0;
+ }
save();
//do what should be done on first Storage connect
@@ -250,21 +256,21 @@ void CloudManager::setStorageLastSync(uint32 index, Common::String date) {
save();
}
-void CloudManager::connectStorage(uint32 index, Common::String code) {
+void CloudManager::connectStorage(uint32 index, Common::String code, Networking::ErrorCallback cb) {
freeStorages();
switch (index) {
case kStorageDropboxId:
- new Dropbox::DropboxStorage(code);
+ new Dropbox::DropboxStorage(code, cb);
break;
case kStorageOneDriveId:
- new OneDrive::OneDriveStorage(code);
+ new OneDrive::OneDriveStorage(code, cb);
break;
case kStorageGoogleDriveId:
- new GoogleDrive::GoogleDriveStorage(code);
+ new GoogleDrive::GoogleDriveStorage(code, cb);
break;
case kStorageBoxId:
- new Box::BoxStorage(code);
+ new Box::BoxStorage(code, cb);
break;
}
// in these constructors Storages request token using the passed code
@@ -273,6 +279,42 @@ void CloudManager::connectStorage(uint32 index, Common::String code) {
// thus, no memory leak happens
}
+void CloudManager::disconnectStorage(uint32 index) {
+ if (index >= kStorageTotal)
+ error("CloudManager::disconnectStorage: invalid index passed");
+
+ Common::String name = getStorageConfigName(index);
+ switch (index) {
+ case kStorageDropboxId:
+ Dropbox::DropboxStorage::removeFromConfig(kStoragePrefix + name + "_");
+ break;
+ case kStorageOneDriveId:
+ OneDrive::OneDriveStorage::removeFromConfig(kStoragePrefix + name + "_");
+ break;
+ case kStorageGoogleDriveId:
+ GoogleDrive::GoogleDriveStorage::removeFromConfig(kStoragePrefix + name + "_");
+ break;
+ case kStorageBoxId:
+ Box::BoxStorage::removeFromConfig(kStoragePrefix + name + "_");
+ break;
+ }
+
+ switchStorage(kStorageNoneId);
+
+ ConfMan.removeKey(kStoragePrefix + name + "_username", ConfMan.kCloudDomain);
+ ConfMan.removeKey(kStoragePrefix + name + "_lastSync", ConfMan.kCloudDomain);
+ ConfMan.removeKey(kStoragePrefix + name + "_usedBytes", ConfMan.kCloudDomain);
+
+ StorageConfig config;
+ config.name = _(name);
+ config.username = "";
+ config.lastSyncDate = "";
+ config.usedBytes = 0;
+
+ _storages[index] = config;
+}
+
+
Networking::Request *CloudManager::listDirectory(Common::String path, Storage::ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive) {
Storage *storage = getCurrentStorage();
if (storage) {
diff --git a/backends/cloud/cloudmanager.h b/backends/cloud/cloudmanager.h
index eb882a63af..131af9bb8f 100644
--- a/backends/cloud/cloudmanager.h
+++ b/backends/cloud/cloudmanager.h
@@ -204,8 +204,16 @@ public:
*
* @param index Storage's index
* @param code OAuth2 code received from user
+ * @param cb callback to notify of success or error
*/
- void connectStorage(uint32 index, Common::String code);
+ void connectStorage(uint32 index, Common::String code, Networking::ErrorCallback cb = nullptr);
+
+ /**
+ * Remove Storage with a given index from config.
+ *
+ * @param index Storage's index
+ */
+ void disconnectStorage(uint32 index);
/** Returns ListDirectoryResponse with list of files. */
Networking::Request *listDirectory(Common::String path, Storage::ListDirectoryCallback callback, Networking::ErrorCallback errorCallback, bool recursive = false);
diff --git a/backends/cloud/dropbox/dropboxstorage.cpp b/backends/cloud/dropbox/dropboxstorage.cpp
index c12dec9968..5d8b9e0425 100644
--- a/backends/cloud/dropbox/dropboxstorage.cpp
+++ b/backends/cloud/dropbox/dropboxstorage.cpp
@@ -42,8 +42,8 @@ namespace Dropbox {
DropboxStorage::DropboxStorage(Common::String accessToken, bool unused): BaseStorage(accessToken, "") {}
-DropboxStorage::DropboxStorage(Common::String code): BaseStorage() {
- getAccessToken(code);
+DropboxStorage::DropboxStorage(Common::String code, Networking::ErrorCallback cb): BaseStorage() {
+ getAccessToken(code, cb);
}
DropboxStorage::~DropboxStorage() {}
@@ -112,5 +112,9 @@ DropboxStorage *DropboxStorage::loadFromConfig(Common::String keyPrefix) {
return new DropboxStorage(accessToken, true);
}
+void DropboxStorage::removeFromConfig(Common::String keyPrefix) {
+ ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain);
+}
+
} // End of namespace Dropbox
} // End of namespace Cloud
diff --git a/backends/cloud/dropbox/dropboxstorage.h b/backends/cloud/dropbox/dropboxstorage.h
index bca83d2b5a..0b76bb5c4a 100644
--- a/backends/cloud/dropbox/dropboxstorage.h
+++ b/backends/cloud/dropbox/dropboxstorage.h
@@ -51,7 +51,7 @@ protected:
public:
/** This constructor uses OAuth code flow to get tokens. */
- DropboxStorage(Common::String code);
+ DropboxStorage(Common::String code, Networking::ErrorCallback cb);
virtual ~DropboxStorage();
/**
@@ -98,6 +98,11 @@ public:
* @return pointer to the newly created DropboxStorage or 0 if some problem occured.
*/
static DropboxStorage *loadFromConfig(Common::String keyPrefix);
+
+ /**
+ * Remove all DropboxStorage-related data from config.
+ */
+ static void removeFromConfig(Common::String keyPrefix);
};
} // End of namespace Dropbox
diff --git a/backends/cloud/googledrive/googledrivestorage.cpp b/backends/cloud/googledrive/googledrivestorage.cpp
index 67d157748a..a6e17e6ad3 100644
--- a/backends/cloud/googledrive/googledrivestorage.cpp
+++ b/backends/cloud/googledrive/googledrivestorage.cpp
@@ -46,8 +46,8 @@ namespace GoogleDrive {
GoogleDriveStorage::GoogleDriveStorage(Common::String token, Common::String refreshToken):
IdStorage(token, refreshToken) {}
-GoogleDriveStorage::GoogleDriveStorage(Common::String code) {
- getAccessToken(code);
+GoogleDriveStorage::GoogleDriveStorage(Common::String code, Networking::ErrorCallback cb) {
+ getAccessToken(code, cb);
}
GoogleDriveStorage::~GoogleDriveStorage() {}
@@ -231,6 +231,11 @@ GoogleDriveStorage *GoogleDriveStorage::loadFromConfig(Common::String keyPrefix)
return new GoogleDriveStorage(accessToken, refreshToken);
}
+void GoogleDriveStorage::removeFromConfig(Common::String keyPrefix) {
+ ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain);
+ ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain);
+}
+
Common::String GoogleDriveStorage::getRootDirectoryId() {
return "root";
}
diff --git a/backends/cloud/googledrive/googledrivestorage.h b/backends/cloud/googledrive/googledrivestorage.h
index 21e027c4a7..db47e7cd3c 100644
--- a/backends/cloud/googledrive/googledrivestorage.h
+++ b/backends/cloud/googledrive/googledrivestorage.h
@@ -58,7 +58,7 @@ protected:
public:
/** This constructor uses OAuth code flow to get tokens. */
- GoogleDriveStorage(Common::String code);
+ GoogleDriveStorage(Common::String code, Networking::ErrorCallback cb);
virtual ~GoogleDriveStorage();
/**
@@ -106,6 +106,11 @@ public:
*/
static GoogleDriveStorage *loadFromConfig(Common::String keyPrefix);
+ /**
+ * Remove all GoogleDriveStorage-related data from config.
+ */
+ static void removeFromConfig(Common::String keyPrefix);
+
virtual Common::String getRootDirectoryId();
Common::String accessToken() const { return _token; }
diff --git a/backends/cloud/onedrive/onedrivestorage.cpp b/backends/cloud/onedrive/onedrivestorage.cpp
index 48c3a10d82..6d05d84c39 100644
--- a/backends/cloud/onedrive/onedrivestorage.cpp
+++ b/backends/cloud/onedrive/onedrivestorage.cpp
@@ -45,8 +45,8 @@ namespace OneDrive {
OneDriveStorage::OneDriveStorage(Common::String token, Common::String refreshToken):
BaseStorage(token, refreshToken) {}
-OneDriveStorage::OneDriveStorage(Common::String code) {
- getAccessToken(code);
+OneDriveStorage::OneDriveStorage(Common::String code, Networking::ErrorCallback cb) {
+ getAccessToken(code, cb);
}
OneDriveStorage::~OneDriveStorage() {}
@@ -209,5 +209,10 @@ OneDriveStorage *OneDriveStorage::loadFromConfig(Common::String keyPrefix) {
return new OneDriveStorage(accessToken, refreshToken);
}
+void OneDriveStorage::removeFromConfig(Common::String keyPrefix) {
+ ConfMan.removeKey(keyPrefix + "access_token", ConfMan.kCloudDomain);
+ ConfMan.removeKey(keyPrefix + "refresh_token", ConfMan.kCloudDomain);
+}
+
} // End of namespace OneDrive
} // End of namespace Cloud
diff --git a/backends/cloud/onedrive/onedrivestorage.h b/backends/cloud/onedrive/onedrivestorage.h
index 4b18929d73..cc46772282 100644
--- a/backends/cloud/onedrive/onedrivestorage.h
+++ b/backends/cloud/onedrive/onedrivestorage.h
@@ -55,7 +55,7 @@ protected:
public:
/** This constructor uses OAuth code flow to get tokens. */
- OneDriveStorage(Common::String code);
+ OneDriveStorage(Common::String code, Networking::ErrorCallback cb);
virtual ~OneDriveStorage();
/**
@@ -103,6 +103,11 @@ public:
*/
static OneDriveStorage *loadFromConfig(Common::String keyPrefix);
+ /**
+ * Remove all OneDriveStorage-related data from config.
+ */
+ static void removeFromConfig(Common::String keyPrefix);
+
Common::String accessToken() const { return _token; }
};
diff --git a/backends/networking/sdl_net/handlers/indexpagehandler.cpp b/backends/networking/sdl_net/handlers/indexpagehandler.cpp
index 17e5159768..876bdde9ce 100644
--- a/backends/networking/sdl_net/handlers/indexpagehandler.cpp
+++ b/backends/networking/sdl_net/handlers/indexpagehandler.cpp
@@ -24,7 +24,6 @@
#include "backends/networking/sdl_net/handlerutils.h"
#include "backends/networking/sdl_net/localwebserver.h"
#include "common/translation.h"
-#include "gui/storagewizarddialog.h"
namespace Networking {
@@ -34,28 +33,17 @@ IndexPageHandler::~IndexPageHandler() {}
/// public
-Common::String IndexPageHandler::code() const { return _code; }
-
void IndexPageHandler::handle(Client &client) {
- Common::String queryCode = client.queryParameter("code");
-
- if (queryCode == "") {
- // redirect to "/filesAJAX"
- HandlerUtils::setMessageHandler(
- client,
- Common::String::format(
- "%s<br/><a href=\"files\">%s</a>",
- _("This is a local webserver index page."),
- _("Open Files manager")
- ),
- "/filesAJAX"
- );
- return;
- }
-
- _code = queryCode;
- sendCommand(GUI::kStorageCodePassedCmd, 0);
- HandlerUtils::setMessageHandler(client, _("ScummVM got the code and already connects to your cloud storage!"));
+ // redirect to "/filesAJAX"
+ HandlerUtils::setMessageHandler(
+ client,
+ Common::String::format(
+ "%s<br/><a href=\"files\">%s</a>",
+ _("This is a local webserver index page."),
+ _("Open Files manager")
+ ),
+ "/filesAJAX"
+ );
}
bool IndexPageHandler::minimalModeSupported() {
diff --git a/backends/networking/sdl_net/handlers/indexpagehandler.h b/backends/networking/sdl_net/handlers/indexpagehandler.h
index 0d8e616395..b4841bcdca 100644
--- a/backends/networking/sdl_net/handlers/indexpagehandler.h
+++ b/backends/networking/sdl_net/handlers/indexpagehandler.h
@@ -30,12 +30,10 @@ namespace Networking {
class LocalWebserver;
class IndexPageHandler: public BaseHandler, public GUI::CommandSender {
- Common::String _code;
public:
IndexPageHandler();
virtual ~IndexPageHandler();
- Common::String code() const;
virtual void handle(Client &client);
virtual bool minimalModeSupported();
};
diff --git a/gui/ThemeEngine.cpp b/gui/ThemeEngine.cpp
index 8117fbe1ab..7e42bc0ab3 100644
--- a/gui/ThemeEngine.cpp
+++ b/gui/ThemeEngine.cpp
@@ -61,10 +61,6 @@ const char *const ThemeEngine::kImageStopSmallButton = "stopbtn_small.bmp";
const char *const ThemeEngine::kImageEditSmallButton = "editbtn_small.bmp";
const char *const ThemeEngine::kImageSwitchModeSmallButton = "switchbtn_small.bmp";
const char *const ThemeEngine::kImageFastReplaySmallButton = "fastreplay_small.bmp";
-const char *const ThemeEngine::kImageDropboxLogo = "dropbox.bmp";
-const char *const ThemeEngine::kImageOneDriveLogo = "onedrive.bmp";
-const char *const ThemeEngine::kImageGoogleDriveLogo = "googledrive.bmp";
-const char *const ThemeEngine::kImageBoxLogo = "box.bmp";
struct TextDrawData {
const Graphics::Font *_fontPtr;
diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h
index 0fd7e9ecb5..367f5cb2c6 100644
--- a/gui/ThemeEngine.h
+++ b/gui/ThemeEngine.h
@@ -263,10 +263,6 @@ public:
static const char *const kImageEditSmallButton; ///< Edit recording metadata in recorder onscreen dialog (for 320xY)
static const char *const kImageSwitchModeSmallButton; ///< Switch mode button in recorder onscreen dialog (for 320xY)
static const char *const kImageFastReplaySmallButton; ///< Fast playback mode button in recorder onscreen dialog (for 320xY)
- static const char *const kImageDropboxLogo; ///< Dropbox logo used in the StorageWizardDialog
- static const char *const kImageOneDriveLogo; ///< OneDrive logo used in the StorageWizardDialog
- static const char *const kImageGoogleDriveLogo; ///< Google Drive logo used in the StorageWizardDialog
- static const char *const kImageBoxLogo; ///< Box logo used in the StorageWizardDialog
/**
* Graphics mode enumeration.
diff --git a/gui/module.mk b/gui/module.mk
index 87f8dec3b2..799c4e7d61 100644
--- a/gui/module.mk
+++ b/gui/module.mk
@@ -43,8 +43,7 @@ ifdef USE_CLOUD
ifdef USE_LIBCURL
MODULE_OBJS += \
downloaddialog.o \
- remotebrowser.o \
- storagewizarddialog.o
+ remotebrowser.o
endif
endif
diff --git a/gui/options.cpp b/gui/options.cpp
index 5d90b70813..38bfc3bc72 100644
--- a/gui/options.cpp
+++ b/gui/options.cpp
@@ -51,7 +51,6 @@
#ifdef USE_LIBCURL
#include "backends/cloud/cloudmanager.h"
#include "gui/downloaddialog.h"
-#include "gui/storagewizarddialog.h"
#endif
#ifdef USE_SDL_NET
@@ -105,14 +104,17 @@ enum {
#ifdef USE_CLOUD
enum {
- kConfigureStorageCmd = 'cfst',
- kRefreshStorageCmd = 'rfst',
+ kSyncSavesStorageCmd = 'ssst',
kDownloadStorageCmd = 'dlst',
kRunServerCmd = 'rnsv',
kCloudTabContainerReflowCmd = 'ctcr',
kServerPortClearCmd = 'spcl',
kChooseRootDirCmd = 'chrp',
- kRootPathClearCmd = 'clrp'
+ kRootPathClearCmd = 'clrp',
+ kConnectStorageCmd = 'Cnnt',
+ kOpenUrlStorageCmd = 'OpUr',
+ kPasteCodeStorageCmd = 'PsCd',
+ kDisconnectStorageCmd = 'DcSt',
};
#endif
@@ -1486,11 +1488,25 @@ GlobalOptionsDialog::GlobalOptionsDialog(LauncherDialog *launcher)
_storageUsername = 0;
_storageUsedSpaceDesc = 0;
_storageUsedSpace = 0;
+ _storageSyncHint = 0;
_storageLastSyncDesc = 0;
_storageLastSync = 0;
- _storageConnectButton = 0;
- _storageRefreshButton = 0;
+ _storageSyncSavesButton = 0;
+ _storageDownloadHint = 0;
_storageDownloadButton = 0;
+ _storageDisconnectHint = 0;
+ _storageDisconnectButton = 0;
+
+ _connectingStorage = false;
+ _storageWizardNotConnectedHint = 0;
+ _storageWizardOpenLinkHint = 0;
+ _storageWizardLink = 0;
+ _storageWizardCodeHint = 0;
+ _storageWizardCodeBox = 0;
+ _storageWizardPasteButton = 0;
+ _storageWizardConnectButton = 0;
+ _storageWizardConnectionStatusHint = 0;
+
_runServerButton = 0;
_serverInfoLabel = 0;
_rootPathButton = 0;
@@ -1744,7 +1760,7 @@ void GlobalOptionsDialog::build() {
container->setTarget(this);
container->setBackgroundType(ThemeEngine::kDialogBackgroundNone);
- _storagePopUpDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StoragePopupDesc", _("Storage:"), _("Active cloud storage"));
+ _storagePopUpDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StoragePopupDesc", _("Active storage:"), _("Active cloud storage"));
_storagePopUp = new PopUpWidget(container, "GlobalOptions_Cloud_Container.StoragePopup");
#ifdef USE_LIBCURL
Common::StringArray list = CloudMan.listStorages();
@@ -1755,27 +1771,39 @@ void GlobalOptionsDialog::build() {
#endif
_storagePopUp->setSelected(_selectedStorageIndex);
+ const char* context = (g_system->getOverlayWidth() > 320 ? nullptr : "lowres");
+
_storageUsernameDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageUsernameDesc", _("Username:"), _("Username used by this storage"));
- _storageUsername = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageUsernameLabel", "<none>");
+ _storageUsername = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageUsernameLabel", "<none>", "", ThemeEngine::kFontStyleNormal);
_storageUsedSpaceDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageUsedSpaceDesc", _("Used space:"), _("Space used by ScummVM's saved games on this storage"));
- _storageUsedSpace = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageUsedSpaceLabel", "0 bytes");
-
- _storageLastSyncDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageLastSyncDesc", _("Last sync time:"), _("When the last saved games sync for this storage occured"));
- _storageLastSync = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageLastSyncLabel", "<never>");
-
- _storageConnectButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.ConnectButton", _("Connect"), _("Open wizard dialog to connect your cloud storage account"), kConfigureStorageCmd);
- _storageRefreshButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.RefreshButton", _("Refresh"), _("Refresh current cloud storage information (username and usage)"), kRefreshStorageCmd);
- _storageDownloadButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.DownloadButton", _("Download"), _("Open downloads manager dialog"), kDownloadStorageCmd);
+ _storageUsedSpace = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageUsedSpaceLabel", "0 bytes", "", ThemeEngine::kFontStyleNormal);
+
+ _storageLastSyncDesc = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageLastSyncDesc", _("Last sync:"), _("When was the last time saved games were synced with this storage"));
+ _storageLastSync = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageLastSyncLabel", "<never>", "", ThemeEngine::kFontStyleNormal);
+ _storageSyncHint = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageSyncHint", _c("Saves sync automatically on launch, after saving and on loading.", context), "", ThemeEngine::kFontStyleNormal);
+ _storageSyncSavesButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.SyncSavesButton", _("Sync now"), _("Start saves sync"), kSyncSavesStorageCmd);
+
+ _storageDownloadHint = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageDownloadHint", _c("You can download game files from your cloud ScummVM folder:", context));
+ _storageDownloadButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.DownloadButton", _("Download game files"), _("Open downloads manager dialog"), kDownloadStorageCmd);
+
+ _storageDisconnectHint = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageDisconnectHint", _c("To change account for this storage, disconnect and connect again:", context));
+ _storageDisconnectButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.DisconnectButton", _("Disconnect"), _("Stop using this storage on this device"), kDisconnectStorageCmd);
+
+ _storageWizardNotConnectedHint = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageWizardNotConnectedHint", _c("This storage is not connected yet! To connect,", context));
+ _storageWizardOpenLinkHint = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageWizardOpenLinkHint", "1. Open this link:");
+ _storageWizardLink = new ButtonWidget(container, "GlobalOptions_Cloud_Container.StorageWizardLink", "https://cloud.scummvm.org/", _("Open URL"), kOpenUrlStorageCmd);
+ _storageWizardCodeHint = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageWizardCodeHint", _c("2. Get the code and enter it here:", context));
+ _storageWizardCodeBox = new EditTextWidget(container, "GlobalOptions_Cloud_Container.StorageWizardCodeBox", "", 0, 0, 0, ThemeEngine::kFontStyleConsole);
+ _storageWizardPasteButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.StorageWizardPasteButton", _("Paste"), _("Paste code from clipboard"), kPasteCodeStorageCmd);
+ _storageWizardConnectButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.StorageWizardConnectButton", _("3. Connect"), _("Connect your cloud storage account"), kConnectStorageCmd);
+ _storageWizardConnectionStatusHint = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.StorageWizardConnectionStatusHint", "...");
_runServerButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.RunServerButton", _("Run server"), _("Run local webserver"), kRunServerCmd);
_serverInfoLabel = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.ServerInfoLabel", _("Not running"));
// Root path
- if (g_system->getOverlayWidth() > 320)
- _rootPathButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.RootPathButton", _("/root/ Path:"), _("Specifies which directory the Files Manager can access"), kChooseRootDirCmd);
- else
- _rootPathButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.RootPathButton", _c("/root/ Path:", "lowres"), _("Specifies which directory the Files Manager can access"), kChooseRootDirCmd);
+ _rootPathButton = new ButtonWidget(container, "GlobalOptions_Cloud_Container.RootPathButton", _c("/root/ Path:", context), _("Specifies which directory the Files Manager can access"), kChooseRootDirCmd);
_rootPath = new StaticTextWidget(container, "GlobalOptions_Cloud_Container.RootPath", "/foo/bar", _("Specifies which directory the Files Manager can access"));
_rootPathClearButton = addClearButton(container, "GlobalOptions_Cloud_Container.RootPathClearButton", kRootPathClearCmd);
@@ -1882,6 +1910,17 @@ void GlobalOptionsDialog::clean() {
OptionsDialog::clean();
}
+void GlobalOptionsDialog::shiftWidget(Widget *widget, const char *widgetName, int32 xOffset, int32 yOffset) {
+ if (!widget) return;
+
+ int16 x, y;
+ uint16 w, h;
+ if (!g_gui.xmlEval()->getWidgetData(widgetName, x, y, w, h))
+ warning("%s's position is undefined", widgetName);
+
+ widget->setPos(x + xOffset, y + yOffset);
+}
+
void GlobalOptionsDialog::apply() {
OptionsDialog::apply();
@@ -2167,47 +2206,120 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3
reflowLayout();
break;
}
- case kConfigureStorageCmd:
- {
-#ifdef NETWORKING_LOCALWEBSERVER_ENABLE_PORT_OVERRIDE
- // save server's port
- uint32 port = Networking::LocalWebserver::getPort();
- if (_serverPort) {
- uint64 contents = _serverPort->getEditString().asUint64();
- if (contents != 0)
- port = contents;
- }
- ConfMan.setInt("local_server_port", port);
- ConfMan.flushToDisk();
-#endif // NETWORKING_LOCALWEBSERVER_ENABLE_PORT_OVERRIDE
- StorageWizardDialog dialog(_selectedStorageIndex);
+ case kSyncSavesStorageCmd: {
+ CloudMan.syncSaves(
+ new Common::Callback<GlobalOptionsDialog, Cloud::Storage::BoolResponse>(this, &GlobalOptionsDialog::storageSavesSyncedCallback)
+ );
+ break;
+ }
+ case kDownloadStorageCmd: {
+ DownloadDialog dialog(_selectedStorageIndex, _launcher);
dialog.runModal();
- //update container's scrollbar
- reflowLayout();
break;
}
- case kRefreshStorageCmd:
- {
- CloudMan.info(
- new Common::Callback<GlobalOptionsDialog, Cloud::Storage::StorageInfoResponse>(this, &GlobalOptionsDialog::storageInfoCallback),
- new Common::Callback<GlobalOptionsDialog, Networking::ErrorResponse>(this, &GlobalOptionsDialog::storageErrorCallback)
- );
- Common::String dir = CloudMan.savesDirectoryPath();
- if (dir.lastChar() == '/')
- dir.deleteLastChar();
- CloudMan.listDirectory(
- dir,
- new Common::Callback<GlobalOptionsDialog, Cloud::Storage::ListDirectoryResponse>(this, &GlobalOptionsDialog::storageListDirectoryCallback),
- new Common::Callback<GlobalOptionsDialog, Networking::ErrorResponse>(this, &GlobalOptionsDialog::storageErrorCallback)
+ case kOpenUrlStorageCmd: {
+ Common::String url = "https://cloud.scummvm.org/";
+ switch (_selectedStorageIndex) {
+ case Cloud::kStorageDropboxId:
+ url += "dropbox";
+ break;
+ case Cloud::kStorageOneDriveId:
+ url += "onedrive";
+ break;
+ case Cloud::kStorageGoogleDriveId:
+ url += "gdrive";
+ break;
+ case Cloud::kStorageBoxId:
+ url += "box";
+ break;
+ }
+
+ if (!g_system->openUrl(url)) {
+ MessageDialog alert(_("Failed to open URL!\nPlease navigate to this page manually."));
+ alert.runModal();
+ }
+ break;
+ }
+ case kPasteCodeStorageCmd: {
+ if (g_system->hasTextInClipboard()) {
+ Common::String message = g_system->getTextFromClipboard();
+ if (!message.empty()) {
+ _storageWizardCodeBox->setEditString(message);
+ _redrawCloudTab = true;
+ }
+ }
+ break;
+ }
+ case kConnectStorageCmd: {
+ Common::String code = "";
+ if (_storageWizardCodeBox)
+ code = _storageWizardCodeBox->getEditString();
+ if (code.size() == 0)
+ return;
+
+ if (CloudMan.isWorking()) {
+ bool cancel = true;
+
+ MessageDialog alert(_("Another Storage is working now. Do you want to interrupt it?"), _("Yes"), _("No"));
+ if (alert.runModal() == GUI::kMessageOK) {
+ if (CloudMan.isDownloading())
+ CloudMan.cancelDownload();
+ if (CloudMan.isSyncing())
+ CloudMan.cancelSync();
+
+ // I believe it still would return `true` here, but just in case
+ if (CloudMan.isWorking()) {
+ MessageDialog alert2(_("Wait until current Storage finishes up and try again."));
+ alert2.runModal();
+ } else {
+ cancel = false;
+ }
+ }
+
+ if (cancel) {
+ return;
+ }
+ }
+
+ if (_storageWizardConnectionStatusHint)
+ _storageWizardConnectionStatusHint->setLabel(_("Connecting..."));
+ CloudMan.connectStorage(
+ _selectedStorageIndex, code,
+ new Common::Callback<GlobalOptionsDialog, Networking::ErrorResponse>(this, &GlobalOptionsDialog::storageConnectionCallback)
);
+ _connectingStorage = true;
+ _redrawCloudTab = true;
break;
}
- case kDownloadStorageCmd:
- {
- DownloadDialog dialog(_selectedStorageIndex, _launcher);
- dialog.runModal();
- break;
+ case kDisconnectStorageCmd: {
+ if (_selectedStorageIndex == CloudMan.getStorageIndex() && CloudMan.isWorking()) {
+ bool cancel = true;
+
+ MessageDialog alert(_("This Storage is working now. Do you want to interrupt it?"), _("Yes"), _("No"));
+ if (alert.runModal() == GUI::kMessageOK) {
+ if (CloudMan.isDownloading())
+ CloudMan.cancelDownload();
+ if (CloudMan.isSyncing())
+ CloudMan.cancelSync();
+
+ // I believe it still would return `true` here, but just in case
+ if (CloudMan.isWorking()) {
+ MessageDialog alert2(_("Wait until current Storage finishes up and try again."));
+ alert2.runModal();
+ } else {
+ cancel = false;
+ }
+ }
+
+ if (cancel) {
+ return;
+ }
}
+
+ CloudMan.disconnectStorage(_selectedStorageIndex);
+ _redrawCloudTab = true;
+ break;
+ }
#endif // USE_LIBCURL
#ifdef USE_SDL_NET
case kRunServerCmd:
@@ -2329,24 +2441,29 @@ void GlobalOptionsDialog::setupCloudTab() {
if (_storagePopUpDesc) _storagePopUpDesc->setVisible(true);
if (_storagePopUp) _storagePopUp->setVisible(true);
+ Common::String username = CloudMan.getStorageUsername(_selectedStorageIndex);
+ bool storageConnected = (username != "");
bool shown = (_selectedStorageIndex != Cloud::kStorageNoneId);
- if (_storageUsernameDesc) _storageUsernameDesc->setVisible(shown);
+ bool shownConnectedInfo = (shown && storageConnected);
+
+ if (_storageUsernameDesc) _storageUsernameDesc->setVisible(shownConnectedInfo);
if (_storageUsername) {
- Common::String username = CloudMan.getStorageUsername(_selectedStorageIndex);
- if (username == "")
- username = _("<none>");
_storageUsername->setLabel(username);
- _storageUsername->setVisible(shown);
+ _storageUsername->setVisible(shownConnectedInfo);
}
- if (_storageUsedSpaceDesc) _storageUsedSpaceDesc->setVisible(shown);
+ if (_storageUsedSpaceDesc) _storageUsedSpaceDesc->setVisible(shownConnectedInfo);
if (_storageUsedSpace) {
uint64 usedSpace = CloudMan.getStorageUsedSpace(_selectedStorageIndex);
Common::String usedSpaceNumber, usedSpaceUnits;
usedSpaceNumber = Common::getHumanReadableBytes(usedSpace, usedSpaceUnits);
_storageUsedSpace->setLabel(Common::String::format("%s %s", usedSpaceNumber.c_str(), _(usedSpaceUnits.c_str())));
- _storageUsedSpace->setVisible(shown);
+ _storageUsedSpace->setVisible(shownConnectedInfo);
}
- if (_storageLastSyncDesc) _storageLastSyncDesc->setVisible(shown);
+ if (_storageSyncHint) {
+ _storageSyncHint->setVisible(shownConnectedInfo);
+ _storageSyncHint->setEnabled(false);
+ }
+ if (_storageLastSyncDesc) _storageLastSyncDesc->setVisible(shownConnectedInfo);
if (_storageLastSync) {
Common::String sync = CloudMan.getStorageLastSync(_selectedStorageIndex);
if (sync == "") {
@@ -2356,16 +2473,96 @@ void GlobalOptionsDialog::setupCloudTab() {
sync = _("<never>");
}
_storageLastSync->setLabel(sync);
- _storageLastSync->setVisible(shown);
+ _storageLastSync->setVisible(shownConnectedInfo);
+ }
+ if (_storageSyncSavesButton)
+ _storageSyncSavesButton->setVisible(shownConnectedInfo && _selectedStorageIndex == CloudMan.getStorageIndex());
+
+ {
+ int16 x, y;
+ uint16 w, h;
+ int16 downloadHintY, downloadButtonY, disconnectHintY;
+ if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageDownloadHint", x, y, w, h))
+ warning("GlobalOptions_Cloud_Container.StorageDownloadHint's position is undefined");
+ downloadHintY = y;
+ if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.DownloadButton", x, y, w, h))
+ warning("GlobalOptions_Cloud_Container.DownloadButton's position is undefined");
+ downloadButtonY = y;
+ if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageDisconnectHint", x, y, w, h))
+ warning("GlobalOptions_Cloud_Container.StorageDisconnectHint's position is undefined");
+ disconnectHintY = y;
+
+ bool showDownloadButton = (shownConnectedInfo && _selectedStorageIndex == CloudMan.getStorageIndex() && _selectedStorageIndex != Cloud::kStorageGoogleDriveId); // cannot download via Google Drive
+ if (_storageDownloadHint) _storageDownloadHint->setVisible(showDownloadButton);
+ if (_storageDownloadButton) _storageDownloadButton->setVisible(showDownloadButton);
+ if (_storageDisconnectHint) _storageDisconnectHint->setVisible(shownConnectedInfo);
+ if (_storageDisconnectButton) _storageDisconnectButton->setVisible(shownConnectedInfo);
+
+ if (showDownloadButton) {
+ if (_storageDownloadHint) _storageDownloadHint->setPos(_storageDownloadHint->getRelX(), downloadHintY);
+ if (_storageDownloadButton) _storageDownloadButton->setPos(_storageDownloadButton->getRelX(), downloadButtonY);
+ if (_storageDisconnectHint) _storageDisconnectHint->setPos(_storageDisconnectHint->getRelX(), disconnectHintY);
+ if (_storageDisconnectButton)_storageDisconnectButton->setPos(_storageDisconnectButton->getRelX(), disconnectHintY + downloadButtonY - downloadHintY);
+ } else {
+ if (_storageDisconnectHint) _storageDisconnectHint->setPos(_storageDisconnectHint->getRelX(), downloadHintY);
+ if (_storageDisconnectButton)_storageDisconnectButton->setPos(_storageDisconnectButton->getRelX(), downloadButtonY);
+ }
+
+ if (!shownConnectedInfo) {
+ bool connecting = _connectingStorage;
+ if (_storageWizardNotConnectedHint) _storageWizardNotConnectedHint->setVisible(shown);
+ if (_storageWizardOpenLinkHint) _storageWizardOpenLinkHint->setVisible(shown);
+ if (_storageWizardLink) {
+ _storageWizardLink->setVisible(shown);
+ _storageWizardLink->setEnabled(g_system->hasFeature(OSystem::kFeatureOpenUrl) && !connecting);
+ }
+ if (_storageWizardCodeHint) _storageWizardCodeHint->setVisible(shown);
+ if (_storageWizardCodeBox) {
+ _storageWizardCodeBox->setVisible(shown);
+ _storageWizardCodeBox->setEnabled(!connecting);
+ }
+ if (_storageWizardPasteButton) {
+ _storageWizardPasteButton->setVisible(shown && g_system->hasFeature(OSystem::kFeatureClipboardSupport));
+ _storageWizardPasteButton->setEnabled(!connecting);
+ }
+ if (_storageWizardConnectButton) {
+ _storageWizardConnectButton->setVisible(shown);
+ _storageWizardConnectButton->setEnabled(!connecting);
+ }
+ if (_storageWizardConnectionStatusHint) {
+ _storageWizardConnectionStatusHint->setVisible(shown && _storageWizardConnectionStatusHint->getLabel() != "...");
+ _storageWizardConnectionStatusHint->setEnabled(!connecting);
+ }
+
+ int16 x2, y2;
+ uint16 w2, h2;
+ int16 shiftUp;
+ if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageUsernameDesc", x2, y2, w2, h2))
+ warning("GlobalOptions_Cloud_Container.StorageUsernameDesc's position is undefined");
+ shiftUp = y2;
+ if (!g_gui.xmlEval()->getWidgetData("GlobalOptions_Cloud_Container.StorageWizardNotConnectedHint", x2, y2, w2, h2))
+ warning("GlobalOptions_Cloud_Container.StorageWizardNotConnectedHint's position is undefined");
+ shiftUp = y2 - shiftUp;
+
+ shiftWidget(_storageWizardNotConnectedHint, "GlobalOptions_Cloud_Container.StorageWizardNotConnectedHint", 0, -shiftUp);
+ shiftWidget(_storageWizardOpenLinkHint, "GlobalOptions_Cloud_Container.StorageWizardOpenLinkHint", 0, -shiftUp);
+ shiftWidget(_storageWizardLink, "GlobalOptions_Cloud_Container.StorageWizardLink", 0, -shiftUp);
+ shiftWidget(_storageWizardCodeHint, "GlobalOptions_Cloud_Container.StorageWizardCodeHint", 0, -shiftUp);
+ shiftWidget(_storageWizardCodeBox, "GlobalOptions_Cloud_Container.StorageWizardCodeBox", 0, -shiftUp);
+ shiftWidget(_storageWizardPasteButton, "GlobalOptions_Cloud_Container.StorageWizardPasteButton", 0, -shiftUp);
+ shiftWidget(_storageWizardConnectButton, "GlobalOptions_Cloud_Container.StorageWizardConnectButton", 0, -shiftUp);
+ shiftWidget(_storageWizardConnectionStatusHint, "GlobalOptions_Cloud_Container.StorageWizardConnectionStatusHint", 0, -shiftUp);
+ }
+
+ if (!shown)
+ serverLabelPosition = (_storageUsernameDesc ? _storageUsernameDesc->getRelY() : 0);
+ else {
+ if (shownConnectedInfo)
+ serverLabelPosition = (_storageDisconnectButton ? _storageDisconnectButton->getRelY() + _storageDisconnectButton->getHeight() + 16 : 0);
+ else
+ serverLabelPosition = (_storageWizardConnectButton ? _storageWizardConnectButton->getRelY() + _storageWizardConnectButton->getHeight() + 16 : 0);
+ }
}
- if (_storageConnectButton)
- _storageConnectButton->setVisible(shown);
- if (_storageRefreshButton)
- _storageRefreshButton->setVisible(shown && _selectedStorageIndex == CloudMan.getStorageIndex());
- if (_storageDownloadButton)
- _storageDownloadButton->setVisible(shown && _selectedStorageIndex == CloudMan.getStorageIndex());
- if (!shown)
- serverLabelPosition = (_storageUsernameDesc ? _storageUsernameDesc->getRelY() : 0);
#else // USE_LIBCURL
_selectedStorageIndex = 0;
@@ -2387,10 +2584,10 @@ void GlobalOptionsDialog::setupCloudTab() {
_storageLastSyncDesc->setVisible(false);
if (_storageLastSync)
_storageLastSync->setVisible(false);
- if (_storageConnectButton)
- _storageConnectButton->setVisible(false);
- if (_storageRefreshButton)
- _storageRefreshButton->setVisible(false);
+ if (_storageDisconnectButton)
+ _storageDisconnectButton->setVisible(false);
+ if (_storageSyncSavesButton)
+ _storageSyncSavesButton->setVisible(false);
if (_storageDownloadButton)
_storageDownloadButton->setVisible(false);
@@ -2504,23 +2701,51 @@ void GlobalOptionsDialog::setupCloudTab() {
if (_serverPortClearButton)
_serverPortClearButton->setVisible(false);
#endif // USE_SDL_NET
+
+ // temporary hide all local server-related info to see how Cloud looks without it
+ /*
+ if (_runServerButton)
+ _runServerButton->setVisible(false);
+ if (_serverInfoLabel) {
+ _serverInfoLabel->setPos(_serverInfoLabel->getRelX(), serverLabelPosition);
+ _serverInfoLabel->setVisible(false);
+ }
+ if (_rootPathButton)
+ _rootPathButton->setVisible(false);
+ if (_rootPath)
+ _rootPath->setVisible(false);
+ if (_rootPathClearButton)
+ _rootPathClearButton->setVisible(false);
+ if (_serverPortDesc)
+ _serverPortDesc->setVisible(false);
+ if (_serverPort)
+ _serverPort->setVisible(false);
+ if (_serverPortClearButton)
+ _serverPortClearButton->setVisible(false);
+ */
}
#ifdef USE_LIBCURL
-void GlobalOptionsDialog::storageInfoCallback(Cloud::Storage::StorageInfoResponse response) {
- //we could've used response.value.email()
- //but Storage already notified CloudMan
- //so we just set the flag to redraw our cloud tab
+void GlobalOptionsDialog::storageConnectionCallback(Networking::ErrorResponse response) {
+ Common::String message = "...";
+ if (!response.failed && !response.interrupted) {
+ // success
+ g_system->displayMessageOnOSD(_("Storage connected."));
+ } else {
+ message = _("Failed to connect storage.");
+ if (response.failed) {
+ message = Common::String(_("Failed to connect storage: ")) + _(response.response.c_str());
+ }
+ }
+
+ if (_storageWizardConnectionStatusHint)
+ _storageWizardConnectionStatusHint->setLabel(message);
+
_redrawCloudTab = true;
+ _connectingStorage = false;
}
-void GlobalOptionsDialog::storageListDirectoryCallback(Cloud::Storage::ListDirectoryResponse response) {
- Common::Array<Cloud::StorageFile> &files = response.value;
- uint64 totalSize = 0;
- for (uint32 i = 0; i < files.size(); ++i)
- if (!files[i].isDirectory())
- totalSize += files[i].size();
- CloudMan.setStorageUsedSpace(CloudMan.getStorageIndex(), totalSize);
+void GlobalOptionsDialog::storageSavesSyncedCallback(Cloud::Storage::BoolResponse response) {
_redrawCloudTab = true;
}
diff --git a/gui/options.h b/gui/options.h
index ad9cb2aed9..13983c1657 100644
--- a/gui/options.h
+++ b/gui/options.h
@@ -301,11 +301,25 @@ protected:
StaticTextWidget *_storageUsername;
StaticTextWidget *_storageUsedSpaceDesc;
StaticTextWidget *_storageUsedSpace;
+ StaticTextWidget *_storageSyncHint;
StaticTextWidget *_storageLastSyncDesc;
StaticTextWidget *_storageLastSync;
- ButtonWidget *_storageConnectButton;
- ButtonWidget *_storageRefreshButton;
+ ButtonWidget *_storageSyncSavesButton;
+ StaticTextWidget *_storageDownloadHint;
ButtonWidget *_storageDownloadButton;
+ StaticTextWidget *_storageDisconnectHint;
+ ButtonWidget *_storageDisconnectButton;
+
+ bool _connectingStorage;
+ StaticTextWidget *_storageWizardNotConnectedHint;
+ StaticTextWidget *_storageWizardOpenLinkHint;
+ StaticTextWidget *_storageWizardLink;
+ StaticTextWidget *_storageWizardCodeHint;
+ EditTextWidget *_storageWizardCodeBox;
+ ButtonWidget *_storageWizardPasteButton;
+ ButtonWidget *_storageWizardConnectButton;
+ StaticTextWidget *_storageWizardConnectionStatusHint;
+
ButtonWidget *_runServerButton;
StaticTextWidget *_serverInfoLabel;
ButtonWidget *_rootPathButton;
@@ -319,11 +333,12 @@ protected:
bool _serverWasRunning;
#endif
+ void shiftWidget(Widget *widget, const char *widgetName, int32 xOffset, int32 yOffset);
void setupCloudTab();
#ifdef USE_LIBCURL
- void storageInfoCallback(Cloud::Storage::StorageInfoResponse response);
- void storageListDirectoryCallback(Cloud::Storage::ListDirectoryResponse response);
+ void storageConnectionCallback(Networking::ErrorResponse response);
+ void storageSavesSyncedCallback(Cloud::Storage::BoolResponse response);
void storageErrorCallback(Networking::ErrorResponse response);
#endif
#endif // USE_CLOUD
diff --git a/gui/storagewizarddialog.cpp b/gui/storagewizarddialog.cpp
deleted file mode 100644
index b01d4422b8..0000000000
--- a/gui/storagewizarddialog.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "gui/storagewizarddialog.h"
-#include "gui/gui-manager.h"
-#include "gui/message.h"
-#include "gui/widget.h"
-#include "gui/widgets/edittext.h"
-#include "gui/widgets/scrollcontainer.h"
-#include "backends/cloud/cloudmanager.h"
-#ifdef USE_SDL_NET
-#include "backends/networking/sdl_net/localwebserver.h"
-#endif
-#include "common/translation.h"
-
-namespace GUI {
-
-enum {
- kConnectCmd = 'Cnnt',
- kCodeBoxCmd = 'CdBx',
- kOpenUrlCmd = 'OpUr',
- kPasteCodeCmd = 'PsCd',
- kStorageWizardContainerReflowCmd = 'SWCr'
-};
-
-StorageWizardDialog::StorageWizardDialog(uint32 storageId):
- Dialog("GlobalOptions_Cloud_ConnectionWizard"), _storageId(storageId), _close(false) {
-#ifdef USE_SDL_NET
- _stopServerOnClose = false;
-#endif
- _backgroundType = GUI::ThemeEngine::kDialogBackgroundPlain;
-
- ScrollContainerWidget *container = new ScrollContainerWidget(this, "GlobalOptions_Cloud_ConnectionWizard.Container", kStorageWizardContainerReflowCmd);
- container->setTarget(this);
-
- Common::String headline = Common::String::format(_("%s Storage Connection Wizard"), CloudMan.listStorages()[_storageId].c_str());
- _headlineWidget = new StaticTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.Headline", headline);
-
- _navigateLineWidget = new StaticTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.NavigateLine", _("Navigate to the following URL:"));
- _urlLineWidget = new StaticTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.URLLine", getUrl());
-
- _returnLine1 = new StaticTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.ReturnLine1", _("Obtain the code from the storage, enter it"));
- _returnLine2 = new StaticTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.ReturnLine2", _("in the following field and press 'Connect':"));
- _codeWidget = new EditTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.CodeBox1", "", 0, kCodeBoxCmd);
- _messageWidget = new StaticTextWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.MessageLine", "");
-
- // Buttons
- _cancelWidget = new ButtonWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.CancelButton", _("Cancel"), 0, kCloseCmd);
- _openUrlWidget = new ButtonWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.OpenUrlButton", _("Open URL"), 0, kOpenUrlCmd);
- _pasteCodeWidget = new ButtonWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.PasteCodeButton", _("Paste"), _("Pastes clipboard contents into fields"), kPasteCodeCmd);
- _connectWidget = new ButtonWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.ConnectButton", _("Connect"), 0, kConnectCmd);
-
- // Initialy the code is empty, so disable the connect button
- _connectWidget->setEnabled(false);
-
- _picture = new GraphicsWidget(container, "GlobalOptions_Cloud_ConnectionWizard_Container.Picture");
-#ifndef DISABLE_FANCY_THEMES
- if (g_gui.theme()->supportsImages()) {
- _picture->useThemeTransparency(true);
- switch (_storageId) {
- case Cloud::kStorageDropboxId:
- _picture->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageDropboxLogo));
- break;
- case Cloud::kStorageOneDriveId:
- _picture->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageOneDriveLogo));
- break;
- case Cloud::kStorageGoogleDriveId:
- _picture->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageGoogleDriveLogo));
- break;
- case Cloud::kStorageBoxId:
- _picture->setGfx(g_gui.theme()->getImageSurface(ThemeEngine::kImageBoxLogo));
- break;
- }
- }
-#endif
-
- containerWidgetsReflow();
-}
-
-void StorageWizardDialog::open() {
- Dialog::open();
-
- if (CloudMan.isWorking()) {
- bool doClose = true;
-
- MessageDialog alert(_("Another Storage is active. Do you want to interrupt it?"), _("Yes"), _("No"));
- if (alert.runModal() == GUI::kMessageOK) {
- if (CloudMan.isDownloading())
- CloudMan.cancelDownload();
- if (CloudMan.isSyncing())
- CloudMan.cancelSync();
-
- // I believe it still would return `true` here, but just in case
- if (CloudMan.isWorking()) {
- MessageDialog alert2(_("Wait until current Storage finishes up and try again."));
- alert2.runModal();
- } else {
- doClose = false;
- }
- }
-
- if (doClose) {
- close();
- }
- }
-}
-
-void StorageWizardDialog::close() {
- Dialog::close();
-}
-
-void StorageWizardDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
- switch (cmd) {
- case kCodeBoxCmd: {
- Common::String code = _codeWidget->getEditString();
- bool ok = (code.size() > 0);
- _connectWidget->setEnabled(ok);
- _messageWidget->setLabel("");
- break;
- }
- case kOpenUrlCmd: {
- if (!g_system->openUrl(getUrl())) {
- MessageDialog alert(_("Failed to open URL!\nPlease navigate to this page manually."));
- alert.runModal();
- }
- break;
- }
- case kPasteCodeCmd: {
- if (g_system->hasTextInClipboard()) {
- Common::String message = g_system->getTextFromClipboard();
- if (!message.empty()) {
- _codeWidget->setEditString(message);
- }
- handleCommand(sender, kCodeBoxCmd, data);
- g_gui.scheduleTopDialogRedraw();
- }
- break;
- }
- case kConnectCmd: {
- Common::String code = _codeWidget->getEditString();
- if (code.size() == 0)
- return;
-
- CloudMan.connectStorage(_storageId, code);
- setResult(1);
- close();
- break;
- }
-#ifdef USE_SDL_NET
- case kStorageCodePassedCmd:
- CloudMan.connectStorage(_storageId, LocalServer.indexPageHandler().code());
- _close = true;
- break;
-#endif
- case kStorageWizardContainerReflowCmd:
- containerWidgetsReflow();
- break;
- default:
- Dialog::handleCommand(sender, cmd, data);
- }
-}
-
-void StorageWizardDialog::handleTickle() {
- if (_close) {
- setResult(1);
- close();
- }
-
- Dialog::handleTickle();
-}
-
-void StorageWizardDialog::containerWidgetsReflow() {
- // contents
- if (_headlineWidget) _headlineWidget->setVisible(true);
- if (_navigateLineWidget) _navigateLineWidget->setVisible(true);
- if (_urlLineWidget) _urlLineWidget->setVisible(true);
- if (_returnLine1) _returnLine1->setVisible(true);
- if (_returnLine2) _returnLine2->setVisible(true);
-
- _codeWidget->setVisible(true);
- _messageWidget->setVisible(true);
-
- // left column / first bottom row
- if (_picture) {
- _picture->setVisible(g_system->getOverlayWidth() > 320);
- }
- if (_openUrlWidget) {
- bool visible = g_system->hasFeature(OSystem::kFeatureOpenUrl);
- _openUrlWidget->setVisible(visible);
- }
- if (_pasteCodeWidget) {
- bool visible = g_system->hasFeature(OSystem::kFeatureClipboardSupport);
- _pasteCodeWidget->setVisible(visible);
- }
-
- // bottom row
- if (_cancelWidget) _cancelWidget->setVisible(true);
- if (_connectWidget) _connectWidget->setVisible(true);
-}
-
-Common::String StorageWizardDialog::getUrl() const {
- return "https://cloud.scummvm.org/";
-}
-
-} // End of namespace GUI
diff --git a/gui/storagewizarddialog.h b/gui/storagewizarddialog.h
deleted file mode 100644
index ede37505ee..0000000000
--- a/gui/storagewizarddialog.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef GUI_STORAGEWIZARDDIALOG_H
-#define GUI_STORAGEWIZARDDIALOG_H
-
-#include "gui/dialog.h"
-#include "common/str.h"
-
-namespace GUI {
-
-class CommandSender;
-class EditTextWidget;
-class StaticTextWidget;
-class ButtonWidget;
-class GraphicsWidget;
-
-#ifdef USE_SDL_NET
-enum StorageWizardDialogCommands {
- kStorageCodePassedCmd = 'SWDC'
-};
-#endif
-
-class StorageWizardDialog : public Dialog {
- uint32 _storageId;
-
- StaticTextWidget *_headlineWidget;
- StaticTextWidget *_navigateLineWidget;
- StaticTextWidget *_urlLineWidget;
- StaticTextWidget *_returnLine1;
- StaticTextWidget *_returnLine2;
- EditTextWidget *_codeWidget;
- StaticTextWidget *_messageWidget;
-
- GraphicsWidget *_picture;
- ButtonWidget *_openUrlWidget;
- ButtonWidget *_pasteCodeWidget;
-
- ButtonWidget *_cancelWidget;
- ButtonWidget *_connectWidget;
-
- bool _close;
-#ifdef USE_SDL_NET
- bool _stopServerOnClose;
-#endif
-
- /** Hides/shows widgets for Container to work with them correctly. */
- void containerWidgetsReflow();
-
- /** Return short scummvm.org URL for user to navigate to. */
- Common::String getUrl() const;
-
-public:
- StorageWizardDialog(uint32 storageId);
-
- virtual void open();
- virtual void close();
- virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
- virtual void handleTickle();
-};
-
-} // End of namespace GUI
-
-#endif
diff --git a/gui/themes/scummclassic.zip b/gui/themes/scummclassic.zip
index 6bd0fc9522..78229c36c1 100644
--- a/gui/themes/scummclassic.zip
+++ b/gui/themes/scummclassic.zip
Binary files differ
diff --git a/gui/themes/scummclassic/classic_layout.stx b/gui/themes/scummclassic/classic_layout.stx
index c92c4d1718..3929af9e81 100644
--- a/gui/themes/scummclassic/classic_layout.stx
+++ b/gui/themes/scummclassic/classic_layout.stx
@@ -58,6 +58,12 @@
<widget name = 'SmallLabel'
size = '24, Globals.Line.Height'
/>
+ <widget name = 'CloudTabLabel'
+ size = '200, Globals.Line.Height'
+ />
+ <widget name = 'CloudTabLabelValue'
+ size = '200, Globals.Line.Height'
+ />
<widget name = 'ShortOptionsLabel'
size = '60, Globals.Line.Height'
@@ -66,6 +72,9 @@
<widget name = 'Button'
size = '108, 24'
/>
+ <widget name = 'WideButton'
+ size = '216, 24'
+ />
<widget name = 'Slider'
size = '128, 18'
/>
@@ -602,49 +611,126 @@
<dialog name = 'GlobalOptions_Cloud_Container' overlays = 'GlobalOptions_Cloud.Container'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
+ <layout type = 'horizontal' padding = '-19, 7, 0, 0' spacing = '10'>
+ <layout type = 'vertical' padding = '0, 0, 2, 0' spacing = '2'>
+ <widget name = 'StoragePopupDesc'
+ type = 'OptionsLabel'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '2'>
+ <widget name = 'StoragePopup'
+ type = 'PopUp'
+ />
+ </layout>
+ </layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StoragePopupDesc'
- type = 'OptionsLabel'
- />
- <widget name = 'StoragePopup'
- type = 'PopUp'
- />
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageUsernameDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsernameLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageUsedSpaceDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsedSpaceLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StorageUsernameDesc'
- type = 'OptionsLabel'
- />
- <widget name = 'StorageUsernameLabel'
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageLastSyncDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageLastSyncLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 7, 0' spacing = '2'>
+ <widget name = 'SyncSavesButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -4, 0' spacing = '10' center = 'true'>
+ <widget name = 'StorageSyncHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StorageUsedSpaceDesc'
- type = 'OptionsLabel'
- />
- <widget name = 'StorageUsedSpaceLabel'
- height = 'Globals.Line.Height'
- />
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '4'>
+ <widget name = 'StorageDownloadHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DownloadButton'
+ type = 'WideButton'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StorageLastSyncDesc'
- type = 'OptionsLabel'
+ <layout type = 'vertical' padding = '0, 0, 8, 0' spacing = '4'>
+ <widget name = 'StorageDisconnectHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DisconnectButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+
+ <!-- here goes unconnected Storage layout (connection wizard) -->
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageWizardNotConnectedHint'
+ height = 'Globals.Line.Height'
/>
- <widget name = 'StorageLastSyncLabel'
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' center = 'true'>
+ <layout type = 'vertical' padding = '0, 0, 2, 0' spacing = '4'>
+ <widget name = 'StorageWizardOpenLinkHint'
+ width = '106'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '4'>
+ <widget name = 'StorageWizardLink'
+ width = '192'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' center = 'true'>
+ <widget name = 'StorageWizardCodeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- <widget name = 'RefreshButton'
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardCodeBox'
+ width = '108'
+ height = '24'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardPasteButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' center = 'true'>
+ <widget name = 'StorageWizardConnectButton'
type = 'Button'
/>
- <widget name = 'DownloadButton'
- type = 'Button'
+ <widget name = 'StorageWizardConnectionStatusHint'
+ height = 'Globals.Line.Height'
/>
</layout>
+
+ <!-- here goes Wi-Fi Sharing -->
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
<widget name = 'RunServerButton'
type = 'Button'
@@ -716,99 +802,6 @@
</layout>
</dialog>
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard' overlays = 'Dialog.GlobalOptions'>
- <layout type = 'vertical' padding = '0, 0, 0, 0'>
- <widget name = 'Container'/>
- </layout>
- </dialog>
-
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard_Container' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container'>
- <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '0'>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '6'>
- <widget name = 'Picture'
- width = '109'
- height = '109'
- />
- <widget name = 'OpenUrlButton'
- type = 'Button'
- />
- <widget name = 'PasteCodeButton'
- type = 'Button'
- />
- </layout>
- <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '6'>
- <widget name = 'Headline'
- height = 'Globals.Line.Height'
- />
- <space size = '4' />
- <widget name = 'NavigateLine'
- height = 'Globals.Line.Height'
- />
- <widget name = 'URLLine'
- height = 'Globals.Line.Height'
- />
- <space size = '4' />
- <widget name = 'ReturnLine1'
- height = 'Globals.Line.Height'
- />
- <widget name = 'ReturnLine2'
- height = 'Globals.Line.Height'
- />
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox1'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox2'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox3'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox4'
- width = '70'
- height = 'Globals.Line.Height'
- />
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox5'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox6'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox7'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox8'
- width = '70'
- height = 'Globals.Line.Height'
- />
- </layout>
- <widget name = 'MessageLine'
- height = 'Globals.Line.Height'
- />
- <space size = '6' />
- </layout>
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'CancelButton'
- type = 'Button'
- />
- <space />
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- </layout>
- </layout>
- </dialog>
-
<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'>
<layout type='vertical' padding='8,8,8,8' center='true'>
<widget name='Action'
diff --git a/gui/themes/scummclassic/classic_layout_lowres.stx b/gui/themes/scummclassic/classic_layout_lowres.stx
index 67e82f9127..8f39a69b17 100644
--- a/gui/themes/scummclassic/classic_layout_lowres.stx
+++ b/gui/themes/scummclassic/classic_layout_lowres.stx
@@ -56,6 +56,9 @@
<widget name = 'Button'
size = '72, 16'
/>
+ <widget name = 'WideButton'
+ size = '144, 16'
+ />
<widget name = 'Slider'
size = '85, 12'
@@ -68,6 +71,12 @@
<widget name = 'SmallLabel'
size = '18, Globals.Line.Height'
/>
+ <widget name = 'CloudTabLabel'
+ size = '180, Globals.Line.Height'
+ />
+ <widget name = 'CloudTabLabelValue'
+ size = '180, Globals.Line.Height'
+ />
<widget name = 'PopUp'
size = '-1, 15'
/>
@@ -605,58 +614,128 @@
</dialog>
<dialog name = 'GlobalOptions_Cloud_Container' overlays = 'GlobalOptions_Cloud.Container'>
- <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
+ <layout type = 'vertical' padding = '10, 13, 10, 10' spacing = '8'>
+ <layout type = 'horizontal' padding = '-10, 1, 0, 0' spacing = '6'>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '1'>
+ <widget name = 'StoragePopupDesc'
+ width = '100'
+ height = 'Globals.Line.Height'
+ textalign = 'right'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '1'>
+ <widget name = 'StoragePopup'
+ type = 'PopUp'
+ />
+ </layout>
+ </layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StoragePopupDesc'
- width = '80'
- height = 'Globals.Line.Height'
- textalign = 'right'
- />
- <widget name = 'StoragePopup'
- type = 'PopUp'
- />
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageUsernameDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsernameLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageUsedSpaceDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsedSpaceLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StorageUsernameDesc'
- width = '80'
- height = 'Globals.Line.Height'
- textalign = 'right'
- />
- <widget name = 'StorageUsernameLabel'
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageLastSyncDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageLastSyncLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 5, 0' spacing = '1'>
+ <widget name = 'SyncSavesButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -3, 0' spacing = '6' center = 'true'>
+ <widget name = 'StorageSyncHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StorageUsedSpaceDesc'
- width = '80'
- height = 'Globals.Line.Height'
- textalign = 'right'
- />
- <widget name = 'StorageUsedSpaceLabel'
- height = 'Globals.Line.Height'
- />
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '4'>
+ <widget name = 'StorageDownloadHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DownloadButton'
+ type = 'WideButton'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StorageLastSyncDesc'
- width = '80'
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '4'>
+ <widget name = 'StorageDisconnectHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DisconnectButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+
+ <!-- here goes unconnected Storage layout (connection wizard) -->
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageWizardNotConnectedHint'
height = 'Globals.Line.Height'
- textalign = 'right'
/>
- <widget name = 'StorageLastSyncLabel'
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -3, 0' spacing = '6' center = 'true'>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '2'>
+ <widget name = 'StorageWizardOpenLinkHint'
+ width = '90'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '4'>
+ <widget name = 'StorageWizardLink'
+ width = '150'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '6' center = 'true'>
+ <widget name = 'StorageWizardCodeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- <widget name = 'RefreshButton'
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardCodeBox'
+ width = '72'
+ height = '16'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardPasteButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '6' center = 'true'>
+ <widget name = 'StorageWizardConnectButton'
type = 'Button'
/>
- <widget name = 'DownloadButton'
- type = 'Button'
+ <widget name = 'StorageWizardConnectionStatusHint'
+ height = 'Globals.Line.Height'
/>
</layout>
+
+ <!-- here goes Wi-Fi Sharing -->
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
<widget name = 'RunServerButton'
type = 'Button'
@@ -730,94 +809,6 @@
</layout>
</dialog>
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard' overlays = 'Dialog.GlobalOptions'>
- <layout type = 'vertical' padding = '0, 0, 0, 0'>
- <widget name = 'Container'/>
- </layout>
- </dialog>
-
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard_Container' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container'>
- <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
- <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '4'>
- <widget name = 'Headline'
- height = 'Globals.Line.Height'
- />
- <space size = '2' />
- <widget name = 'NavigateLine'
- height = 'Globals.Line.Height'
- />
- <widget name = 'URLLine'
- height = 'Globals.Line.Height'
- />
- <space size = '2' />
- <widget name = 'ReturnLine1'
- height = 'Globals.Line.Height'
- />
- <widget name = 'ReturnLine2'
- height = 'Globals.Line.Height'
- />
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox1'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox2'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox3'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox4'
- width = '60'
- height = '16'
- />
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox5'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox6'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox7'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox8'
- width = '60'
- height = '16'
- />
- </layout>
- <widget name = 'MessageLine'
- height = 'Globals.Line.Height'
- />
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'OpenUrlButton'
- type = 'Button'
- />
- <widget name = 'PasteCodeButton'
- type = 'Button'
- />
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CancelButton'
- type = 'Button'
- />
- <space />
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- </layout>
- <space size = '6' />
- <widget name = 'Picture' width = '1' height = '1' />
- </layout>
- </layout>
- </dialog>
-
<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'>
<layout type='vertical' padding='8,8,8,8' center='true'>
<widget name='Action'
diff --git a/gui/themes/scummmodern.zip b/gui/themes/scummmodern.zip
index 1a5fd5c432..d1b4c239a1 100644
--- a/gui/themes/scummmodern.zip
+++ b/gui/themes/scummmodern.zip
Binary files differ
diff --git a/gui/themes/scummmodern/box.bmp b/gui/themes/scummmodern/box.bmp
deleted file mode 100644
index 21fb650f02..0000000000
--- a/gui/themes/scummmodern/box.bmp
+++ /dev/null
Binary files differ
diff --git a/gui/themes/scummmodern/dropbox.bmp b/gui/themes/scummmodern/dropbox.bmp
deleted file mode 100644
index bfe620740f..0000000000
--- a/gui/themes/scummmodern/dropbox.bmp
+++ /dev/null
Binary files differ
diff --git a/gui/themes/scummmodern/googledrive.bmp b/gui/themes/scummmodern/googledrive.bmp
deleted file mode 100644
index f79a0e7769..0000000000
--- a/gui/themes/scummmodern/googledrive.bmp
+++ /dev/null
Binary files differ
diff --git a/gui/themes/scummmodern/onedrive.bmp b/gui/themes/scummmodern/onedrive.bmp
deleted file mode 100644
index cd26d71d3c..0000000000
--- a/gui/themes/scummmodern/onedrive.bmp
+++ /dev/null
Binary files differ
diff --git a/gui/themes/scummmodern/scummmodern_gfx.stx b/gui/themes/scummmodern/scummmodern_gfx.stx
index 8b884abcc2..0e62f36627 100644
--- a/gui/themes/scummmodern/scummmodern_gfx.stx
+++ b/gui/themes/scummmodern/scummmodern_gfx.stx
@@ -119,10 +119,6 @@
<bitmap filename = 'editbtn_small.bmp'/>
<bitmap filename = 'switchbtn_small.bmp'/>
<bitmap filename = 'fastreplay_small.bmp'/>
- <bitmap filename = 'dropbox.bmp'/>
- <bitmap filename = 'onedrive.bmp'/>
- <bitmap filename = 'googledrive.bmp'/>
- <bitmap filename = 'box.bmp'/>
</bitmaps>
<fonts>
diff --git a/gui/themes/scummmodern/scummmodern_layout.stx b/gui/themes/scummmodern/scummmodern_layout.stx
index d6c927c251..b1d4e28015 100644
--- a/gui/themes/scummmodern/scummmodern_layout.stx
+++ b/gui/themes/scummmodern/scummmodern_layout.stx
@@ -65,10 +65,19 @@
<widget name = 'SmallLabel'
size = '24, Globals.Line.Height'
/>
+ <widget name = 'CloudTabLabel'
+ size = '200, Globals.Line.Height'
+ />
+ <widget name = 'CloudTabLabelValue'
+ size = '200, Globals.Line.Height'
+ />
<widget name = 'Button'
size = '108, 24'
/>
+ <widget name = 'WideButton'
+ size = '216, 24'
+ />
<widget name = 'Slider'
size = '128, 18'
@@ -616,49 +625,126 @@
<dialog name = 'GlobalOptions_Cloud_Container' overlays = 'GlobalOptions_Cloud.Container'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
+ <layout type = 'horizontal' padding = '-27, 7, 0, 0' spacing = '10'>
+ <layout type = 'vertical' padding = '0, 0, 2, 0' spacing = '2'>
+ <widget name = 'StoragePopupDesc'
+ type = 'OptionsLabel'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '2'>
+ <widget name = 'StoragePopup'
+ type = 'PopUp'
+ />
+ </layout>
+ </layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StoragePopupDesc'
- type = 'OptionsLabel'
- />
- <widget name = 'StoragePopup'
- type = 'PopUp'
- />
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageUsernameDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsernameLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageUsedSpaceDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsedSpaceLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StorageUsernameDesc'
- type = 'OptionsLabel'
- />
- <widget name = 'StorageUsernameLabel'
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageLastSyncDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageLastSyncLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 7, 0' spacing = '2'>
+ <widget name = 'SyncSavesButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -4, 0' spacing = '10' center = 'true'>
+ <widget name = 'StorageSyncHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StorageUsedSpaceDesc'
- type = 'OptionsLabel'
- />
- <widget name = 'StorageUsedSpaceLabel'
- height = 'Globals.Line.Height'
- />
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '4'>
+ <widget name = 'StorageDownloadHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DownloadButton'
+ type = 'WideButton'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StorageLastSyncDesc'
- type = 'OptionsLabel'
+ <layout type = 'vertical' padding = '0, 0, 8, 0' spacing = '4'>
+ <widget name = 'StorageDisconnectHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DisconnectButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+
+ <!-- here goes unconnected Storage layout (connection wizard) -->
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageWizardNotConnectedHint'
+ height = 'Globals.Line.Height'
/>
- <widget name = 'StorageLastSyncLabel'
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -4, 0' spacing = '10' center = 'true'>
+ <layout type = 'vertical' padding = '0, 0, 2, 0' spacing = '4'>
+ <widget name = 'StorageWizardOpenLinkHint'
+ width = '96'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '4'>
+ <widget name = 'StorageWizardLink'
+ width = '192'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' center = 'true'>
+ <widget name = 'StorageWizardCodeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- <widget name = 'RefreshButton'
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardCodeBox'
+ width = '108'
+ height = '24'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardPasteButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' center = 'true'>
+ <widget name = 'StorageWizardConnectButton'
type = 'Button'
/>
- <widget name = 'DownloadButton'
- type = 'Button'
+ <widget name = 'StorageWizardConnectionStatusHint'
+ height = 'Globals.Line.Height'
/>
</layout>
+
+ <!-- here goes Wi-Fi Sharing -->
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
<widget name = 'RunServerButton'
type = 'Button'
@@ -730,99 +816,6 @@
</layout>
</dialog>
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard' overlays = 'Dialog.GlobalOptions'>
- <layout type = 'vertical' padding = '0, 0, 0, 0'>
- <widget name = 'Container'/>
- </layout>
- </dialog>
-
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard_Container' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container'>
- <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '0'>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '6'>
- <widget name = 'Picture'
- width = '109'
- height = '109'
- />
- <widget name = 'OpenUrlButton'
- type = 'Button'
- />
- <widget name = 'PasteCodeButton'
- type = 'Button'
- />
- </layout>
- <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '6'>
- <widget name = 'Headline'
- height = 'Globals.Line.Height'
- />
- <space size = '4' />
- <widget name = 'NavigateLine'
- height = 'Globals.Line.Height'
- />
- <widget name = 'URLLine'
- height = 'Globals.Line.Height'
- />
- <space size = '4' />
- <widget name = 'ReturnLine1'
- height = 'Globals.Line.Height'
- />
- <widget name = 'ReturnLine2'
- height = 'Globals.Line.Height'
- />
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox1'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox2'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox3'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox4'
- width = '70'
- height = 'Globals.Line.Height'
- />
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox5'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox6'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox7'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox8'
- width = '70'
- height = 'Globals.Line.Height'
- />
- </layout>
- <widget name = 'MessageLine'
- height = 'Globals.Line.Height'
- />
- <space size = '6' />
- </layout>
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'CancelButton'
- type = 'Button'
- />
- <space />
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- </layout>
- </layout>
- </dialog>
-
<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'>
<layout type='vertical' padding='8,8,8,8' center='true'>
<widget name='Action'
diff --git a/gui/themes/scummmodern/scummmodern_layout_lowres.stx b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
index 464450cbdc..fd9990d2e3 100644
--- a/gui/themes/scummmodern/scummmodern_layout_lowres.stx
+++ b/gui/themes/scummmodern/scummmodern_layout_lowres.stx
@@ -46,6 +46,9 @@
<widget name = 'Button'
size = '72, 16'
/>
+ <widget name = 'WideButton'
+ size = '144, 16'
+ />
<widget name = 'Slider'
size = '85, 12'
@@ -66,6 +69,12 @@
<widget name = 'SmallLabel'
size = '18, Globals.Line.Height'
/>
+ <widget name = 'CloudTabLabel'
+ size = '170, Globals.Line.Height'
+ />
+ <widget name = 'CloudTabLabelValue'
+ size = '170, Globals.Line.Height'
+ />
<widget name = 'PopUp'
size = '-1, 15'
/>
@@ -603,58 +612,128 @@
</dialog>
<dialog name = 'GlobalOptions_Cloud_Container' overlays = 'GlobalOptions_Cloud.Container'>
- <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
+ <layout type = 'vertical' padding = '10, 13, 10, 10' spacing = '8'>
+ <layout type = 'horizontal' padding = '-7, 1, 0, 0' spacing = '6'>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '1'>
+ <widget name = 'StoragePopupDesc'
+ width = '80'
+ height = 'Globals.Line.Height'
+ textalign = 'right'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '1'>
+ <widget name = 'StoragePopup'
+ type = 'PopUp'
+ />
+ </layout>
+ </layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StoragePopupDesc'
- width = '80'
- height = 'Globals.Line.Height'
- textalign = 'right'
- />
- <widget name = 'StoragePopup'
- type = 'PopUp'
- />
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageUsernameDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsernameLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageUsedSpaceDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsedSpaceLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StorageUsernameDesc'
- width = '80'
- height = 'Globals.Line.Height'
- textalign = 'right'
- />
- <widget name = 'StorageUsernameLabel'
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageLastSyncDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageLastSyncLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 5, 0' spacing = '1'>
+ <widget name = 'SyncSavesButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -3, 0' spacing = '6' center = 'true'>
+ <widget name = 'StorageSyncHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StorageUsedSpaceDesc'
- width = '80'
- height = 'Globals.Line.Height'
- textalign = 'right'
- />
- <widget name = 'StorageUsedSpaceLabel'
- height = 'Globals.Line.Height'
- />
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '4'>
+ <widget name = 'StorageDownloadHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DownloadButton'
+ type = 'WideButton'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StorageLastSyncDesc'
- width = '80'
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '4'>
+ <widget name = 'StorageDisconnectHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DisconnectButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+
+ <!-- here goes unconnected Storage layout (connection wizard) -->
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageWizardNotConnectedHint'
height = 'Globals.Line.Height'
- textalign = 'right'
/>
- <widget name = 'StorageLastSyncLabel'
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -3, 0' spacing = '6' center = 'true'>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '2'>
+ <widget name = 'StorageWizardOpenLinkHint'
+ width = '90'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '4'>
+ <widget name = 'StorageWizardLink'
+ width = '150'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '6' center = 'true'>
+ <widget name = 'StorageWizardCodeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- <widget name = 'RefreshButton'
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardCodeBox'
+ width = '72'
+ height = '16'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardPasteButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '6' center = 'true'>
+ <widget name = 'StorageWizardConnectButton'
type = 'Button'
/>
- <widget name = 'DownloadButton'
- type = 'Button'
+ <widget name = 'StorageWizardConnectionStatusHint'
+ height = 'Globals.Line.Height'
/>
</layout>
+
+ <!-- here goes Wi-Fi Sharing -->
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
<widget name = 'RunServerButton'
type = 'Button'
@@ -728,94 +807,6 @@
</layout>
</dialog>
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard' overlays = 'Dialog.GlobalOptions'>
- <layout type = 'vertical' padding = '0, 0, 0, 0'>
- <widget name = 'Container'/>
- </layout>
- </dialog>
-
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard_Container' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container'>
- <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
- <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '4'>
- <widget name = 'Headline'
- height = 'Globals.Line.Height'
- />
- <space size = '2' />
- <widget name = 'NavigateLine'
- height = 'Globals.Line.Height'
- />
- <widget name = 'URLLine'
- height = 'Globals.Line.Height'
- />
- <space size = '2' />
- <widget name = 'ReturnLine1'
- height = 'Globals.Line.Height'
- />
- <widget name = 'ReturnLine2'
- height = 'Globals.Line.Height'
- />
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox1'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox2'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox3'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox4'
- width = '60'
- height = '16'
- />
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox5'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox6'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox7'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox8'
- width = '60'
- height = '16'
- />
- </layout>
- <widget name = 'MessageLine'
- height = 'Globals.Line.Height'
- />
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'OpenUrlButton'
- type = 'Button'
- />
- <widget name = 'PasteCodeButton'
- type = 'Button'
- />
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CancelButton'
- type = 'Button'
- />
- <space />
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- </layout>
- <space size = '6' />
- <widget name = 'Picture' width = '1' height = '1' />
- </layout>
- </layout>
- </dialog>
-
<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'>
<layout type='vertical' padding='8,8,8,8' center='true'>
<widget name='Action'
diff --git a/gui/themes/scummremastered.zip b/gui/themes/scummremastered.zip
index 6d235b48f2..5b5f82d2b3 100644
--- a/gui/themes/scummremastered.zip
+++ b/gui/themes/scummremastered.zip
Binary files differ
diff --git a/gui/themes/scummremastered/box.bmp b/gui/themes/scummremastered/box.bmp
deleted file mode 100644
index 7da33fc5fa..0000000000
--- a/gui/themes/scummremastered/box.bmp
+++ /dev/null
Binary files differ
diff --git a/gui/themes/scummremastered/dropbox.bmp b/gui/themes/scummremastered/dropbox.bmp
deleted file mode 100644
index bfe620740f..0000000000
--- a/gui/themes/scummremastered/dropbox.bmp
+++ /dev/null
Binary files differ
diff --git a/gui/themes/scummremastered/googledrive.bmp b/gui/themes/scummremastered/googledrive.bmp
deleted file mode 100644
index f79a0e7769..0000000000
--- a/gui/themes/scummremastered/googledrive.bmp
+++ /dev/null
Binary files differ
diff --git a/gui/themes/scummremastered/onedrive.bmp b/gui/themes/scummremastered/onedrive.bmp
deleted file mode 100644
index 16f67cb179..0000000000
--- a/gui/themes/scummremastered/onedrive.bmp
+++ /dev/null
Binary files differ
diff --git a/gui/themes/scummremastered/remastered_gfx.stx b/gui/themes/scummremastered/remastered_gfx.stx
index f5144321a0..76b722c5d5 100644
--- a/gui/themes/scummremastered/remastered_gfx.stx
+++ b/gui/themes/scummremastered/remastered_gfx.stx
@@ -120,10 +120,6 @@
<bitmap filename = 'editbtn_small.bmp'/>
<bitmap filename = 'switchbtn_small.bmp'/>
<bitmap filename = 'fastreplay_small.bmp'/>
- <bitmap filename = 'dropbox.bmp'/>
- <bitmap filename = 'onedrive.bmp'/>
- <bitmap filename = 'googledrive.bmp'/>
- <bitmap filename = 'box.bmp'/>
</bitmaps>
<fonts>
diff --git a/gui/themes/scummremastered/remastered_layout.stx b/gui/themes/scummremastered/remastered_layout.stx
index d6c927c251..b1d4e28015 100644
--- a/gui/themes/scummremastered/remastered_layout.stx
+++ b/gui/themes/scummremastered/remastered_layout.stx
@@ -65,10 +65,19 @@
<widget name = 'SmallLabel'
size = '24, Globals.Line.Height'
/>
+ <widget name = 'CloudTabLabel'
+ size = '200, Globals.Line.Height'
+ />
+ <widget name = 'CloudTabLabelValue'
+ size = '200, Globals.Line.Height'
+ />
<widget name = 'Button'
size = '108, 24'
/>
+ <widget name = 'WideButton'
+ size = '216, 24'
+ />
<widget name = 'Slider'
size = '128, 18'
@@ -616,49 +625,126 @@
<dialog name = 'GlobalOptions_Cloud_Container' overlays = 'GlobalOptions_Cloud.Container'>
<layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
+ <layout type = 'horizontal' padding = '-27, 7, 0, 0' spacing = '10'>
+ <layout type = 'vertical' padding = '0, 0, 2, 0' spacing = '2'>
+ <widget name = 'StoragePopupDesc'
+ type = 'OptionsLabel'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '2'>
+ <widget name = 'StoragePopup'
+ type = 'PopUp'
+ />
+ </layout>
+ </layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StoragePopupDesc'
- type = 'OptionsLabel'
- />
- <widget name = 'StoragePopup'
- type = 'PopUp'
- />
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageUsernameDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsernameLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageUsedSpaceDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsedSpaceLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StorageUsernameDesc'
- type = 'OptionsLabel'
- />
- <widget name = 'StorageUsernameLabel'
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageLastSyncDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageLastSyncLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 7, 0' spacing = '2'>
+ <widget name = 'SyncSavesButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -4, 0' spacing = '10' center = 'true'>
+ <widget name = 'StorageSyncHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StorageUsedSpaceDesc'
- type = 'OptionsLabel'
- />
- <widget name = 'StorageUsedSpaceLabel'
- height = 'Globals.Line.Height'
- />
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '4'>
+ <widget name = 'StorageDownloadHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DownloadButton'
+ type = 'WideButton'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'StorageLastSyncDesc'
- type = 'OptionsLabel'
+ <layout type = 'vertical' padding = '0, 0, 8, 0' spacing = '4'>
+ <widget name = 'StorageDisconnectHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DisconnectButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+
+ <!-- here goes unconnected Storage layout (connection wizard) -->
+ <layout type = 'vertical' padding = '0, 0, 6, 0' spacing = '2'>
+ <widget name = 'StorageWizardNotConnectedHint'
+ height = 'Globals.Line.Height'
/>
- <widget name = 'StorageLastSyncLabel'
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -4, 0' spacing = '10' center = 'true'>
+ <layout type = 'vertical' padding = '0, 0, 2, 0' spacing = '4'>
+ <widget name = 'StorageWizardOpenLinkHint'
+ width = '96'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '4'>
+ <widget name = 'StorageWizardLink'
+ width = '192'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' center = 'true'>
+ <widget name = 'StorageWizardCodeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- <widget name = 'RefreshButton'
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardCodeBox'
+ width = '108'
+ height = '24'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardPasteButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '10' center = 'true'>
+ <widget name = 'StorageWizardConnectButton'
type = 'Button'
/>
- <widget name = 'DownloadButton'
- type = 'Button'
+ <widget name = 'StorageWizardConnectionStatusHint'
+ height = 'Globals.Line.Height'
/>
</layout>
+
+ <!-- here goes Wi-Fi Sharing -->
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
<widget name = 'RunServerButton'
type = 'Button'
@@ -730,99 +816,6 @@
</layout>
</dialog>
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard' overlays = 'Dialog.GlobalOptions'>
- <layout type = 'vertical' padding = '0, 0, 0, 0'>
- <widget name = 'Container'/>
- </layout>
- </dialog>
-
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard_Container' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container'>
- <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '0'>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '6'>
- <widget name = 'Picture'
- width = '109'
- height = '109'
- />
- <widget name = 'OpenUrlButton'
- type = 'Button'
- />
- <widget name = 'PasteCodeButton'
- type = 'Button'
- />
- </layout>
- <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '6'>
- <widget name = 'Headline'
- height = 'Globals.Line.Height'
- />
- <space size = '4' />
- <widget name = 'NavigateLine'
- height = 'Globals.Line.Height'
- />
- <widget name = 'URLLine'
- height = 'Globals.Line.Height'
- />
- <space size = '4' />
- <widget name = 'ReturnLine1'
- height = 'Globals.Line.Height'
- />
- <widget name = 'ReturnLine2'
- height = 'Globals.Line.Height'
- />
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox1'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox2'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox3'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox4'
- width = '70'
- height = 'Globals.Line.Height'
- />
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox5'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox6'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox7'
- width = '70'
- height = 'Globals.Line.Height'
- />
- <widget name = 'CodeBox8'
- width = '70'
- height = 'Globals.Line.Height'
- />
- </layout>
- <widget name = 'MessageLine'
- height = 'Globals.Line.Height'
- />
- <space size = '6' />
- </layout>
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '10' center = 'true'>
- <widget name = 'CancelButton'
- type = 'Button'
- />
- <space />
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- </layout>
- </layout>
- </dialog>
-
<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'>
<layout type='vertical' padding='8,8,8,8' center='true'>
<widget name='Action'
diff --git a/gui/themes/scummremastered/remastered_layout_lowres.stx b/gui/themes/scummremastered/remastered_layout_lowres.stx
index 464450cbdc..fd9990d2e3 100644
--- a/gui/themes/scummremastered/remastered_layout_lowres.stx
+++ b/gui/themes/scummremastered/remastered_layout_lowres.stx
@@ -46,6 +46,9 @@
<widget name = 'Button'
size = '72, 16'
/>
+ <widget name = 'WideButton'
+ size = '144, 16'
+ />
<widget name = 'Slider'
size = '85, 12'
@@ -66,6 +69,12 @@
<widget name = 'SmallLabel'
size = '18, Globals.Line.Height'
/>
+ <widget name = 'CloudTabLabel'
+ size = '170, Globals.Line.Height'
+ />
+ <widget name = 'CloudTabLabelValue'
+ size = '170, Globals.Line.Height'
+ />
<widget name = 'PopUp'
size = '-1, 15'
/>
@@ -603,58 +612,128 @@
</dialog>
<dialog name = 'GlobalOptions_Cloud_Container' overlays = 'GlobalOptions_Cloud.Container'>
- <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
+ <layout type = 'vertical' padding = '10, 13, 10, 10' spacing = '8'>
+ <layout type = 'horizontal' padding = '-7, 1, 0, 0' spacing = '6'>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '1'>
+ <widget name = 'StoragePopupDesc'
+ width = '80'
+ height = 'Globals.Line.Height'
+ textalign = 'right'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '1'>
+ <widget name = 'StoragePopup'
+ type = 'PopUp'
+ />
+ </layout>
+ </layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StoragePopupDesc'
- width = '80'
- height = 'Globals.Line.Height'
- textalign = 'right'
- />
- <widget name = 'StoragePopup'
- type = 'PopUp'
- />
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageUsernameDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsernameLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageUsedSpaceDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageUsedSpaceLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StorageUsernameDesc'
- width = '80'
- height = 'Globals.Line.Height'
- textalign = 'right'
- />
- <widget name = 'StorageUsernameLabel'
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageLastSyncDesc'
+ type = 'CloudTabLabel'
+ />
+ <widget name = 'StorageLastSyncLabel'
+ type = 'CloudTabLabelValue'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 5, 0' spacing = '1'>
+ <widget name = 'SyncSavesButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -3, 0' spacing = '6' center = 'true'>
+ <widget name = 'StorageSyncHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StorageUsedSpaceDesc'
- width = '80'
- height = 'Globals.Line.Height'
- textalign = 'right'
- />
- <widget name = 'StorageUsedSpaceLabel'
- height = 'Globals.Line.Height'
- />
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '4'>
+ <widget name = 'StorageDownloadHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DownloadButton'
+ type = 'WideButton'
+ />
+ </layout>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'StorageLastSyncDesc'
- width = '80'
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '4'>
+ <widget name = 'StorageDisconnectHint'
+ height = 'Globals.Line.Height'
+ />
+ <widget name = 'DisconnectButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+
+ <!-- here goes unconnected Storage layout (connection wizard) -->
+ <layout type = 'vertical' padding = '0, 0, 3, 0' spacing = '1'>
+ <widget name = 'StorageWizardNotConnectedHint'
height = 'Globals.Line.Height'
- textalign = 'right'
/>
- <widget name = 'StorageLastSyncLabel'
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -3, 0' spacing = '6' center = 'true'>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '2'>
+ <widget name = 'StorageWizardOpenLinkHint'
+ width = '90'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, 1, 0' spacing = '4'>
+ <widget name = 'StorageWizardLink'
+ width = '150'
+ height = 'Globals.Line.Height'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '6' center = 'true'>
+ <widget name = 'StorageWizardCodeHint'
height = 'Globals.Line.Height'
/>
</layout>
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- <widget name = 'RefreshButton'
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardCodeBox'
+ width = '72'
+ height = '16'
+ />
+ </layout>
+ <layout type = 'vertical' padding = '0, 0, -2, 0' spacing = '2'>
+ <widget name = 'StorageWizardPasteButton'
+ type = 'Button'
+ />
+ </layout>
+ </layout>
+ <layout type = 'horizontal' padding = '0, 0, -2, 0' spacing = '6' center = 'true'>
+ <widget name = 'StorageWizardConnectButton'
type = 'Button'
/>
- <widget name = 'DownloadButton'
- type = 'Button'
+ <widget name = 'StorageWizardConnectionStatusHint'
+ height = 'Globals.Line.Height'
/>
</layout>
+
+ <!-- here goes Wi-Fi Sharing -->
<layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '6' center = 'true'>
<widget name = 'RunServerButton'
type = 'Button'
@@ -728,94 +807,6 @@
</layout>
</dialog>
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard' overlays = 'Dialog.GlobalOptions'>
- <layout type = 'vertical' padding = '0, 0, 0, 0'>
- <widget name = 'Container'/>
- </layout>
- </dialog>
-
- <dialog name = 'GlobalOptions_Cloud_ConnectionWizard_Container' overlays = 'GlobalOptions_Cloud_ConnectionWizard.Container'>
- <layout type = 'vertical' padding = '16, 16, 16, 16' spacing = '8'>
- <layout type = 'vertical' padding = '0, 0, 0, 0' spacing = '4'>
- <widget name = 'Headline'
- height = 'Globals.Line.Height'
- />
- <space size = '2' />
- <widget name = 'NavigateLine'
- height = 'Globals.Line.Height'
- />
- <widget name = 'URLLine'
- height = 'Globals.Line.Height'
- />
- <space size = '2' />
- <widget name = 'ReturnLine1'
- height = 'Globals.Line.Height'
- />
- <widget name = 'ReturnLine2'
- height = 'Globals.Line.Height'
- />
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox1'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox2'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox3'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox4'
- width = '60'
- height = '16'
- />
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CodeBox5'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox6'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox7'
- width = '60'
- height = '16'
- />
- <widget name = 'CodeBox8'
- width = '60'
- height = '16'
- />
- </layout>
- <widget name = 'MessageLine'
- height = 'Globals.Line.Height'
- />
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'OpenUrlButton'
- type = 'Button'
- />
- <widget name = 'PasteCodeButton'
- type = 'Button'
- />
- </layout>
- <layout type = 'horizontal' padding = '0, 0, 0, 0' spacing = '4' center = 'true'>
- <widget name = 'CancelButton'
- type = 'Button'
- />
- <space />
- <widget name = 'ConnectButton'
- type = 'Button'
- />
- </layout>
- <space size = '6' />
- <widget name = 'Picture' width = '1' height = '1' />
- </layout>
- </layout>
- </dialog>
-
<dialog name='KeysDialog' overlays='Dialog.GlobalOptions' shading='dim'>
<layout type='vertical' padding='8,8,8,8' center='true'>
<widget name='Action'
diff --git a/gui/widgets/edittext.cpp b/gui/widgets/edittext.cpp
index ba9ef616ba..b73cb99ced 100644
--- a/gui/widgets/edittext.cpp
+++ b/gui/widgets/edittext.cpp
@@ -28,26 +28,26 @@
namespace GUI {
-EditTextWidget::EditTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd)
+EditTextWidget::EditTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd, ThemeEngine::FontStyle font)
: EditableWidget(boss, x, y - 1, w, h + 2, tooltip, cmd) {
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE);
_type = kEditTextWidget;
_finishCmd = finishCmd;
setEditString(text);
- setFontStyle(ThemeEngine::kFontStyleNormal);
+ setFontStyle(font);
_leftPadding = _rightPadding = 0;
}
-EditTextWidget::EditTextWidget(GuiObject *boss, const String &name, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd)
+EditTextWidget::EditTextWidget(GuiObject *boss, const String &name, const String &text, const char *tooltip, uint32 cmd, uint32 finishCmd, ThemeEngine::FontStyle font)
: EditableWidget(boss, name, tooltip, cmd) {
setFlags(WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS | WIDGET_WANT_TICKLE);
_type = kEditTextWidget;
_finishCmd = finishCmd;
setEditString(text);
- setFontStyle(ThemeEngine::kFontStyleNormal);
+ setFontStyle(font);
_leftPadding = _rightPadding = 0;
}
diff --git a/gui/widgets/edittext.h b/gui/widgets/edittext.h
index 9a1b698606..a20d40eb33 100644
--- a/gui/widgets/edittext.h
+++ b/gui/widgets/edittext.h
@@ -40,8 +40,8 @@ protected:
int _rightPadding;
public:
- EditTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, const char *tooltip = 0, uint32 cmd = 0, uint32 finishCmd = 0);
- EditTextWidget(GuiObject *boss, const String &name, const String &text, const char *tooltp = 0, uint32 cmd = 0, uint32 finishCmd = 0);
+ EditTextWidget(GuiObject *boss, int x, int y, int w, int h, const String &text, const char *tooltip = 0, uint32 cmd = 0, uint32 finishCmd = 0, ThemeEngine::FontStyle font = ThemeEngine::kFontStyleNormal);
+ EditTextWidget(GuiObject *boss, const String &name, const String &text, const char *tooltp = 0, uint32 cmd = 0, uint32 finishCmd = 0, ThemeEngine::FontStyle font = ThemeEngine::kFontStyleNormal);
void setEditString(const String &str);
diff --git a/gui/widgets/scrollcontainer.cpp b/gui/widgets/scrollcontainer.cpp
index 7e3f50d3bb..5a0e408d1e 100644
--- a/gui/widgets/scrollcontainer.cpp
+++ b/gui/widgets/scrollcontainer.cpp
@@ -74,6 +74,7 @@ void ScrollContainerWidget::recalc() {
h = max - min;
if (h <= _limitH) _scrolledY = 0;
+ if (_scrolledY > h - _limitH) _scrolledY = 0;
_verticalScroll->_numEntries = h;
_verticalScroll->_currentPos = _scrolledY;