aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
Diffstat (limited to 'launcher')
-rw-r--r--launcher/Application.cpp42
-rw-r--r--launcher/Application.h3
-rw-r--r--launcher/BaseInstaller.h5
-rw-r--r--launcher/BaseVersion.h5
-rw-r--r--launcher/BaseVersionList.cpp10
-rw-r--r--launcher/BaseVersionList.h8
-rw-r--r--launcher/CMakeLists.txt1
-rw-r--r--launcher/DesktopServices.cpp19
-rw-r--r--launcher/DesktopServices.h2
-rw-r--r--launcher/FileSystem.cpp37
-rw-r--r--launcher/GZip.cpp4
-rw-r--r--launcher/HoeDown.h2
-rw-r--r--launcher/java/JavaInstallList.cpp10
-rw-r--r--launcher/java/JavaInstallList.h6
-rw-r--r--launcher/java/JavaUtils.cpp12
-rw-r--r--launcher/main.cpp1
-rw-r--r--launcher/meta/Index.cpp16
-rw-r--r--launcher/meta/Index.h17
-rw-r--r--launcher/meta/JsonFormat.cpp18
-rw-r--r--launcher/meta/Version.cpp4
-rw-r--r--launcher/meta/Version.h11
-rw-r--r--launcher/meta/VersionList.cpp30
-rw-r--r--launcher/meta/VersionList.h32
-rw-r--r--launcher/minecraft/VanillaInstanceCreationTask.cpp2
-rw-r--r--launcher/minecraft/VanillaInstanceCreationTask.h8
-rw-r--r--launcher/minecraft/launch/VerifyJavaInstall.cpp2
-rw-r--r--launcher/modplatform/atlauncher/ATLPackInstallTask.cpp11
-rw-r--r--launcher/modplatform/atlauncher/ATLPackInstallTask.h8
-rw-r--r--launcher/modplatform/flame/FileResolvingTask.cpp33
-rw-r--r--launcher/modplatform/flame/FileResolvingTask.h3
-rw-r--r--launcher/modplatform/helpers/NetworkModAPI.cpp1
-rw-r--r--launcher/modplatform/modrinth/ModrinthPackIndex.cpp55
-rw-r--r--launcher/resources/OSX/OSX.qrc1
-rw-r--r--launcher/resources/OSX/scalable/launch.svg33
-rw-r--r--launcher/resources/OSX/scalable/launcher.svg14
-rw-r--r--launcher/resources/backgrounds/backgrounds.qrc12
-rw-r--r--launcher/resources/backgrounds/kitteh-bday.png (renamed from launcher/resources/backgrounds/cattiversary.png)bin99736 -> 99736 bytes
-rw-r--r--launcher/resources/backgrounds/kitteh-xmas.png (renamed from launcher/resources/backgrounds/catmas.png)bin72818 -> 72818 bytes
-rw-r--r--launcher/resources/backgrounds/kitteh.png (renamed from launcher/resources/backgrounds/catbgrnd2.png)bin62973 -> 62973 bytes
-rw-r--r--launcher/resources/backgrounds/rory-bday.pngbin0 -> 83235 bytes
-rw-r--r--launcher/resources/backgrounds/rory-flat-bday.pngbin0 -> 57713 bytes
-rw-r--r--launcher/resources/backgrounds/rory-flat-xmas.pngbin0 -> 59495 bytes
-rw-r--r--launcher/resources/backgrounds/rory-flat.pngbin0 -> 52337 bytes
-rw-r--r--launcher/resources/backgrounds/rory-xmas.pngbin0 -> 85543 bytes
-rw-r--r--launcher/resources/backgrounds/rory.pngbin0 -> 76448 bytes
-rw-r--r--launcher/resources/flat/flat.qrc1
-rw-r--r--launcher/resources/flat/scalable/launch.svg16
-rw-r--r--launcher/resources/flat/scalable/launcher.svg14
-rw-r--r--launcher/resources/flat_white/flat_white.qrc51
-rw-r--r--launcher/resources/flat_white/index.theme11
-rw-r--r--launcher/resources/flat_white/scalable/about.svg3
-rw-r--r--launcher/resources/flat_white/scalable/accounts.svg3
-rw-r--r--launcher/resources/flat_white/scalable/bug.svg3
-rw-r--r--launcher/resources/flat_white/scalable/cat.svg3
-rw-r--r--launcher/resources/flat_white/scalable/centralmods.svg3
-rw-r--r--launcher/resources/flat_white/scalable/checkupdate.svg3
-rw-r--r--launcher/resources/flat_white/scalable/copy.svg3
-rw-r--r--launcher/resources/flat_white/scalable/coremods.svg3
-rw-r--r--launcher/resources/flat_white/scalable/custom-commands.svg86
-rw-r--r--launcher/resources/flat_white/scalable/delete.svg5
-rw-r--r--launcher/resources/flat_white/scalable/discord.svg4
-rw-r--r--launcher/resources/flat_white/scalable/export.svg5
-rw-r--r--launcher/resources/flat_white/scalable/externaltools.svg3
-rw-r--r--launcher/resources/flat_white/scalable/help.svg17
-rw-r--r--launcher/resources/flat_white/scalable/instance-settings.svg3
-rw-r--r--launcher/resources/flat_white/scalable/jarmods.svg3
-rw-r--r--launcher/resources/flat_white/scalable/java.svg3
-rw-r--r--launcher/resources/flat_white/scalable/language.svg103
-rw-r--r--launcher/resources/flat_white/scalable/launch.svg16
-rw-r--r--launcher/resources/flat_white/scalable/launcher.svg2
-rw-r--r--launcher/resources/flat_white/scalable/loadermods.svg3
-rw-r--r--launcher/resources/flat_white/scalable/log.svg3
-rw-r--r--launcher/resources/flat_white/scalable/minecraft.svg3
-rw-r--r--launcher/resources/flat_white/scalable/multimc.svg3
-rw-r--r--launcher/resources/flat_white/scalable/new.svg3
-rw-r--r--launcher/resources/flat_white/scalable/news.svg3
-rw-r--r--launcher/resources/flat_white/scalable/notes.svg3
-rw-r--r--launcher/resources/flat_white/scalable/packages.svg3
-rw-r--r--launcher/resources/flat_white/scalable/patreon.svg3
-rw-r--r--launcher/resources/flat_white/scalable/proxy.svg3
-rw-r--r--launcher/resources/flat_white/scalable/quickmods.svg3
-rw-r--r--launcher/resources/flat_white/scalable/reddit-alien.svg3
-rw-r--r--launcher/resources/flat_white/scalable/refresh.svg3
-rw-r--r--launcher/resources/flat_white/scalable/rename.svg4
-rw-r--r--launcher/resources/flat_white/scalable/resourcepacks.svg3
-rw-r--r--launcher/resources/flat_white/scalable/screenshot-placeholder.svg3
-rw-r--r--launcher/resources/flat_white/scalable/screenshots.svg3
-rw-r--r--launcher/resources/flat_white/scalable/settings.svg3
-rw-r--r--launcher/resources/flat_white/scalable/shaderpacks.svg56
-rw-r--r--launcher/resources/flat_white/scalable/star.svg3
-rw-r--r--launcher/resources/flat_white/scalable/status-bad.svg3
-rw-r--r--launcher/resources/flat_white/scalable/status-good.svg3
-rw-r--r--launcher/resources/flat_white/scalable/status-running.svg3
-rw-r--r--launcher/resources/flat_white/scalable/status-yellow.svg3
-rw-r--r--launcher/resources/flat_white/scalable/tag.svg4
-rw-r--r--launcher/resources/flat_white/scalable/viewfolder.svg3
-rw-r--r--launcher/resources/flat_white/scalable/worlds.svg3
-rw-r--r--launcher/resources/iOS/iOS.qrc1
-rw-r--r--launcher/resources/iOS/scalable/launch.svg17
-rw-r--r--launcher/resources/iOS/scalable/launcher.svg14
-rw-r--r--launcher/resources/multimc/scalable/launcher.svg14
-rw-r--r--launcher/resources/pe_blue/pe_blue.qrc1
-rw-r--r--launcher/resources/pe_blue/scalable/launch.svg20
-rw-r--r--launcher/resources/pe_blue/scalable/launcher.svg14
-rw-r--r--launcher/resources/pe_colored/pe_colored.qrc1
-rw-r--r--launcher/resources/pe_colored/scalable/launch.svg23
-rw-r--r--launcher/resources/pe_colored/scalable/launcher.svg14
-rw-r--r--launcher/resources/pe_dark/pe_dark.qrc1
-rw-r--r--launcher/resources/pe_dark/scalable/launch.svg17
-rw-r--r--launcher/resources/pe_dark/scalable/launcher.svg14
-rw-r--r--launcher/resources/pe_light/pe_light.qrc1
-rw-r--r--launcher/resources/pe_light/scalable/launch.svg17
-rw-r--r--launcher/resources/pe_light/scalable/launcher.svg14
-rw-r--r--launcher/tasks/Task.cpp2
-rw-r--r--launcher/translations/TranslationsModel.cpp6
-rw-r--r--launcher/ui/MainWindow.cpp50
-rw-r--r--launcher/ui/dialogs/AboutDialog.cpp9
-rw-r--r--launcher/ui/dialogs/AboutDialog.ui13
-rw-r--r--launcher/ui/dialogs/ModUpdateDialog.cpp15
-rw-r--r--launcher/ui/dialogs/ProgressDialog.cpp2
-rw-r--r--launcher/ui/dialogs/VersionSelectDialog.cpp2
-rw-r--r--launcher/ui/dialogs/VersionSelectDialog.h2
-rw-r--r--launcher/ui/pages/global/APIPage.ui2
-rw-r--r--launcher/ui/pages/global/LauncherPage.cpp37
-rw-r--r--launcher/ui/pages/global/LauncherPage.ui43
-rw-r--r--launcher/ui/pages/modplatform/ModModel.cpp25
-rw-r--r--launcher/ui/pages/modplatform/ModModel.h1
-rw-r--r--launcher/ui/pages/modplatform/VanillaPage.cpp8
-rw-r--r--launcher/ui/pages/modplatform/VanillaPage.h12
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp2
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp9
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h4
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameModel.cpp52
-rw-r--r--launcher/ui/pages/modplatform/flame/FlamePage.cpp10
-rw-r--r--launcher/ui/pages/modplatform/flame/FlamePage.ui9
-rw-r--r--launcher/ui/themes/DarkTheme.cpp2
-rw-r--r--launcher/ui/widgets/JavaSettingsWidget.cpp2
-rw-r--r--launcher/ui/widgets/JavaSettingsWidget.h2
-rw-r--r--launcher/ui/widgets/ModFilterWidget.h4
-rw-r--r--launcher/ui/widgets/VersionSelectWidget.cpp6
-rw-r--r--launcher/ui/widgets/VersionSelectWidget.h4
141 files changed, 1169 insertions, 330 deletions
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index ae832b6b..3fe463e8 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -62,6 +62,7 @@
#ifdef Q_OS_WIN
#include "ui/WinDarkmode.h"
+#include <versionhelpers.h>
#endif
#include "ui/setupwizard/SetupWizard.h"
@@ -245,7 +246,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
{{"s", "server"}, "Join the specified server on launch (only valid in combination with --launch)", "address"},
{{"a", "profile"}, "Use the account specified by its profile name (only valid in combination with --launch)", "profile"},
{"alive", "Write a small '" + liveCheckFile + "' file after the launcher starts"},
- {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"}
+ {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"},
+ {"show", "Opens the window for the specified instance (by instance ID)", "show"}
});
parser.addHelpOption();
parser.addVersionOption();
@@ -257,6 +259,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_profileToUse = parser.value("profile");
m_liveCheck = parser.isSet("alive");
m_zipToImport = parser.value("import");
+ m_instanceIdToShowWindowOf = parser.value("show");
// error if --launch is missing with --server or --profile
if((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty())
@@ -498,6 +501,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
// Theming
m_settings->registerSetting("IconTheme", QString("pe_colored"));
m_settings->registerSetting("ApplicationTheme", QString("system"));
+ m_settings->registerSetting("BackgroundCat", QString("kitteh"));
// Remembered state
m_settings->registerSetting("LastUsedGroupForNewInstance", QString());
@@ -992,6 +996,16 @@ void Application::performMainStartupAction()
return;
}
}
+ if(!m_instanceIdToShowWindowOf.isEmpty())
+ {
+ auto inst = instances()->getInstanceById(m_instanceIdToShowWindowOf);
+ if(inst)
+ {
+ qDebug() << "<> Showing window of instance " << m_instanceIdToShowWindowOf;
+ showInstanceWindow(inst);
+ return;
+ }
+ }
if(!m_mainWindow)
{
// normal main window
@@ -1130,15 +1144,6 @@ std::vector<ITheme *> Application::getValidApplicationThemes()
return ret;
}
-bool Application::isFlatpak()
-{
- #ifdef Q_OS_LINUX
- return QFile::exists("/.flatpak-info");
- #else
- return false;
- #endif
-}
-
void Application::setApplicationTheme(const QString& name, bool initial)
{
auto systemPalette = qApp->palette();
@@ -1148,7 +1153,7 @@ void Application::setApplicationTheme(const QString& name, bool initial)
auto & theme = (*themeIter).second;
theme->apply(initial);
#ifdef Q_OS_WIN
- if (m_mainWindow) {
+ if (m_mainWindow && IsWindows10OrGreater()) {
if (QString::compare(theme->id(), "dark") == 0) {
WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true);
} else {
@@ -1171,7 +1176,7 @@ void Application::setIconTheme(const QString& name)
QIcon Application::getThemedIcon(const QString& name)
{
if(name == "logo") {
- return QIcon(":/org.prismlauncher.PrismLauncher.svg"); // FIXME: Make this a BuildConfig variable
+ return QIcon(":/" + BuildConfig.LAUNCHER_SVGFILENAME);
}
return QIcon::fromTheme(name);
}
@@ -1389,10 +1394,13 @@ MainWindow* Application::showMainWindow(bool minimized)
m_mainWindow->restoreState(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowState").toByteArray()));
m_mainWindow->restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("MainWindowGeometry").toByteArray()));
#ifdef Q_OS_WIN
- if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) {
- WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true);
- } else {
- WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false);
+ if (IsWindows10OrGreater())
+ {
+ if (QString::compare(settings()->get("ApplicationTheme").toString(), "dark") == 0) {
+ WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), true);
+ } else {
+ WinDarkmode::setDarkWinTitlebar(m_mainWindow->winId(), false);
+ }
}
#endif
if(minimized)
@@ -1577,7 +1585,7 @@ QString Application::getJarPath(QString jarFile)
{
QStringList potentialPaths = {
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
- FS::PathCombine(m_rootPath, "share/jars"),
+ FS::PathCombine(m_rootPath, "share/" + BuildConfig.LAUNCHER_APP_BINARY_NAME),
#endif
FS::PathCombine(m_rootPath, "jars"),
FS::PathCombine(applicationDirPath(), "jars")
diff --git a/launcher/Application.h b/launcher/Application.h
index 34ad8c15..8fa0ab10 100644
--- a/launcher/Application.h
+++ b/launcher/Application.h
@@ -116,8 +116,6 @@ public:
QIcon getThemedIcon(const QString& name);
- bool isFlatpak();
-
void setIconTheme(const QString& name);
std::vector<ITheme *> getValidApplicationThemes();
@@ -301,6 +299,7 @@ public:
QString m_profileToUse;
bool m_liveCheck = false;
QUrl m_zipToImport;
+ QString m_instanceIdToShowWindowOf;
std::unique_ptr<QFile> logFile;
};
diff --git a/launcher/BaseInstaller.h b/launcher/BaseInstaller.h
index b2e6a14d..a1b80e93 100644
--- a/launcher/BaseInstaller.h
+++ b/launcher/BaseInstaller.h
@@ -17,13 +17,14 @@
#include <memory>
+#include "BaseVersion.h"
+
class MinecraftInstance;
class QDir;
class QString;
class QObject;
class Task;
class BaseVersion;
-typedef std::shared_ptr<BaseVersion> BaseVersionPtr;
class BaseInstaller
{
@@ -35,7 +36,7 @@ public:
virtual bool add(MinecraftInstance *to);
virtual bool remove(MinecraftInstance *from);
- virtual Task *createInstallTask(MinecraftInstance *instance, BaseVersionPtr version, QObject *parent) = 0;
+ virtual Task *createInstallTask(MinecraftInstance *instance, BaseVersion::Ptr version, QObject *parent) = 0;
protected:
virtual QString id() const = 0;
diff --git a/launcher/BaseVersion.h b/launcher/BaseVersion.h
index b88105fb..ca0e4502 100644
--- a/launcher/BaseVersion.h
+++ b/launcher/BaseVersion.h
@@ -25,6 +25,7 @@
class BaseVersion
{
public:
+ using Ptr = std::shared_ptr<BaseVersion>;
virtual ~BaseVersion() {}
/*!
* A string used to identify this version in config files.
@@ -54,6 +55,4 @@ public:
};
};
-typedef std::shared_ptr<BaseVersion> BaseVersionPtr;
-
-Q_DECLARE_METATYPE(BaseVersionPtr)
+Q_DECLARE_METATYPE(BaseVersion::Ptr)
diff --git a/launcher/BaseVersionList.cpp b/launcher/BaseVersionList.cpp
index b4a7d6dd..4ed82612 100644
--- a/launcher/BaseVersionList.cpp
+++ b/launcher/BaseVersionList.cpp
@@ -40,20 +40,20 @@ BaseVersionList::BaseVersionList(QObject *parent) : QAbstractListModel(parent)
{
}
-BaseVersionPtr BaseVersionList::findVersion(const QString &descriptor)
+BaseVersion::Ptr BaseVersionList::findVersion(const QString &descriptor)
{
for (int i = 0; i < count(); i++)
{
if (at(i)->descriptor() == descriptor)
return at(i);
}
- return BaseVersionPtr();
+ return nullptr;
}
-BaseVersionPtr BaseVersionList::getRecommended() const
+BaseVersion::Ptr BaseVersionList::getRecommended() const
{
if (count() <= 0)
- return BaseVersionPtr();
+ return nullptr;
else
return at(0);
}
@@ -66,7 +66,7 @@ QVariant BaseVersionList::data(const QModelIndex &index, int role) const
if (index.row() > count())
return QVariant();
- BaseVersionPtr version = at(index.row());
+ BaseVersion::Ptr version = at(index.row());
switch (role)
{
diff --git a/launcher/BaseVersionList.h b/launcher/BaseVersionList.h
index 80a91e8f..31f29022 100644
--- a/launcher/BaseVersionList.h
+++ b/launcher/BaseVersionList.h
@@ -70,7 +70,7 @@ public:
virtual bool isLoaded() = 0;
//! Gets the version at the given index.
- virtual const BaseVersionPtr at(int i) const = 0;
+ virtual const BaseVersion::Ptr at(int i) const = 0;
//! Returns the number of versions in the list.
virtual int count() const = 0;
@@ -90,13 +90,13 @@ public:
* \return A const pointer to the version with the given descriptor. NULL if
* one doesn't exist.
*/
- virtual BaseVersionPtr findVersion(const QString &descriptor);
+ virtual BaseVersion::Ptr findVersion(const QString &descriptor);
/*!
* \brief Gets the recommended version from this list
* If the list doesn't support recommended versions, this works exactly as getLatestStable
*/
- virtual BaseVersionPtr getRecommended() const;
+ virtual BaseVersion::Ptr getRecommended() const;
/*!
* Sorts the version list.
@@ -117,5 +117,5 @@ slots:
* then copies the versions and sets their parents correctly.
* \param versions List of versions whose parents should be set.
*/
- virtual void updateListData(QList<BaseVersionPtr> versions) = 0;
+ virtual void updateListData(QList<BaseVersion::Ptr> versions) = 0;
};
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index 79ac49c7..0dae47df 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -602,6 +602,7 @@ SET(LAUNCHER_SOURCES
resources/OSX/OSX.qrc
resources/iOS/iOS.qrc
resources/flat/flat.qrc
+ resources/flat_white/flat_white.qrc
resources/documents/documents.qrc
../${Launcher_Branding_LogoQRC}
diff --git a/launcher/DesktopServices.cpp b/launcher/DesktopServices.cpp
index c29cbe7d..302eaf96 100644
--- a/launcher/DesktopServices.cpp
+++ b/launcher/DesktopServices.cpp
@@ -119,7 +119,7 @@ bool openDirectory(const QString &path, bool ensureExists)
return QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath()));
};
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
- if(!APPLICATION->isFlatpak())
+ if(!isFlatpak())
{
return IndirectOpen(f);
}
@@ -140,7 +140,7 @@ bool openFile(const QString &path)
return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
};
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
- if(!APPLICATION->isFlatpak())
+ if(!isFlatpak())
{
return IndirectOpen(f);
}
@@ -158,7 +158,7 @@ bool openFile(const QString &application, const QString &path, const QString &wo
qDebug() << "Opening file" << path << "using" << application;
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
- if(!APPLICATION->isFlatpak())
+ if(!isFlatpak())
{
return IndirectOpen([&]()
{
@@ -178,7 +178,7 @@ bool run(const QString &application, const QStringList &args, const QString &wor
{
qDebug() << "Running" << application << "with args" << args.join(' ');
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
- if(!APPLICATION->isFlatpak())
+ if(!isFlatpak())
{
// FIXME: the pid here is fake. So if something depends on it, it will likely misbehave
return IndirectOpen([&]()
@@ -203,7 +203,7 @@ bool openUrl(const QUrl &url)
return QDesktopServices::openUrl(url);
};
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
- if(!APPLICATION->isFlatpak())
+ if(!isFlatpak())
{
return IndirectOpen(f);
}
@@ -216,4 +216,13 @@ bool openUrl(const QUrl &url)
#endif
}
+bool isFlatpak()
+{
+#ifdef Q_OS_LINUX
+ return QFile::exists("/.flatpak-info");
+#else
+ return false;
+#endif
+}
+
}
diff --git a/launcher/DesktopServices.h b/launcher/DesktopServices.h
index 1c081da4..21c9cae0 100644
--- a/launcher/DesktopServices.h
+++ b/launcher/DesktopServices.h
@@ -33,4 +33,6 @@ namespace DesktopServices
* Open the URL, most likely in a browser. Maybe.
*/
bool openUrl(const QUrl &url);
+
+ bool isFlatpak();
}
diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp
index 39e68c20..4026d6c1 100644
--- a/launcher/FileSystem.cpp
+++ b/launcher/FileSystem.cpp
@@ -44,6 +44,7 @@
#include <QStandardPaths>
#include <QTextStream>
#include <QUrl>
+#include "DesktopServices.h"
#if defined Q_OS_WIN32
#include <objbase.h>
@@ -182,6 +183,21 @@ bool copy::operator()(const QString& offset)
if (!m_followSymlinks)
opt |= copy_opts::copy_symlinks;
+ // Function that'll do the actual copying
+ auto copy_file = [&](QString src_path, QString relative_dst_path) {
+ if (m_blacklist && m_blacklist->matches(relative_dst_path))
+ return;
+
+ auto dst_path = PathCombine(dst, relative_dst_path);
+ ensureFilePathExists(dst_path);
+
+ fs::copy(toStdString(src_path), toStdString(dst_path), opt, err);
+ if (err) {
+ qWarning() << "Failed to copy files:" << QString::fromStdString(err.message());
+ qDebug() << "Source file:" << src_path;
+ qDebug() << "Destination file:" << dst_path;
+ }
+ };
// We can't use copy_opts::recursive because we need to take into account the
// blacklisted paths, so we iterate over the source directory, and if there's no blacklist
@@ -193,20 +209,13 @@ bool copy::operator()(const QString& offset)
auto src_path = source_it.next();
auto relative_path = src_dir.relativeFilePath(src_path);
- if (m_blacklist && m_blacklist->matches(relative_path))
- continue;
-
- auto dst_path = PathCombine(dst, relative_path);
- ensureFilePathExists(dst_path);
-
- fs::copy(toStdString(src_path), toStdString(dst_path), opt, err);
- if (err) {
- qWarning() << "Failed to copy files:" << QString::fromStdString(err.message());
- qDebug() << "Source file:" << src_path;
- qDebug() << "Destination file:" << dst_path;
- }
+ copy_file(src_path, relative_path);
}
+ // If the root src is not a directory, the previous iterator won't run.
+ if (!fs::is_directory(toStdString(src)))
+ copy_file(src, "");
+
return err.value() == 0;
}
@@ -228,6 +237,9 @@ bool trash(QString path, QString *pathInTrash = nullptr)
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
return false;
#else
+ // FIXME: Figure out trash in Flatpak. Qt seemingly doesn't use the Trash portal
+ if (DesktopServices::isFlatpak())
+ return false;
return QFile::moveToTrash(path, pathInTrash);
#endif
}
@@ -401,6 +413,7 @@ bool overrideFolder(QString overwritten_path, QString override_path)
std::error_code err;
fs::copy_options opt = copy_opts::recursive | copy_opts::overwrite_existing;
+ // FIXME: hello traveller! Apparently std::copy does NOT overwrite existing files on GNU libstdc++ on Windows?
fs::copy(toStdString(override_path), toStdString(overwritten_path), opt, err);
if (err) {
diff --git a/launcher/GZip.cpp b/launcher/GZip.cpp
index 067104cf..e36dc8a4 100644
--- a/launcher/GZip.cpp
+++ b/launcher/GZip.cpp
@@ -72,7 +72,7 @@ bool GZip::unzip(const QByteArray &compressedBytes, QByteArray &uncompressedByte
uncompLength *= 2;
}
- strm.next_out = (Bytef *)(uncompressedBytes.data() + strm.total_out);
+ strm.next_out = reinterpret_cast<Bytef *>((uncompressedBytes.data() + strm.total_out));
strm.avail_out = uncompLength - strm.total_out;
// Inflate another chunk.
@@ -129,7 +129,7 @@ bool GZip::zip(const QByteArray &uncompressedBytes, QByteArray &compressedBytes)
{
compressedBytes.resize(compressedBytes.size() * 2);
}
- zs.next_out = (Bytef *) (compressedBytes.data() + offset);
+ zs.next_out = reinterpret_cast<Bytef*>((compressedBytes.data() + offset));
temp = zs.avail_out = compressedBytes.size() - offset;
ret = deflate(&zs, Z_FINISH);
offset += temp - zs.avail_out;
diff --git a/launcher/HoeDown.h b/launcher/HoeDown.h
index b9e06ffb..cb62de6c 100644
--- a/launcher/HoeDown.h
+++ b/launcher/HoeDown.h
@@ -42,7 +42,7 @@ public:
}
void put(QByteArray input)
{
- hoedown_buffer_put(buf, (uint8_t *) input.data(), input.size());
+ hoedown_buffer_put(buf, reinterpret_cast<uint8_t *>(input.data()), input.size());
}
const uint8_t * data() const
{
diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp
index 0249bd22..155c956a 100644
--- a/launcher/java/JavaInstallList.cpp
+++ b/launcher/java/JavaInstallList.cpp
@@ -73,7 +73,7 @@ void JavaInstallList::load()
}
}
-const BaseVersionPtr JavaInstallList::at(int i) const
+const BaseVersion::Ptr JavaInstallList::at(int i) const
{
return m_vlist.at(i);
}
@@ -122,7 +122,7 @@ BaseVersionList::RoleList JavaInstallList::providesRoles() const
}
-void JavaInstallList::updateListData(QList<BaseVersionPtr> versions)
+void JavaInstallList::updateListData(QList<BaseVersion::Ptr> versions)
{
beginResetModel();
m_vlist = versions;
@@ -137,7 +137,7 @@ void JavaInstallList::updateListData(QList<BaseVersionPtr> versions)
m_loadTask.reset();
}
-bool sortJavas(BaseVersionPtr left, BaseVersionPtr right)
+bool sortJavas(BaseVersion::Ptr left, BaseVersion::Ptr right)
{
auto rleft = std::dynamic_pointer_cast<JavaInstall>(right);
auto rright = std::dynamic_pointer_cast<JavaInstall>(left);
@@ -210,11 +210,11 @@ void JavaListLoadTask::javaCheckerFinished()
}
}
- QList<BaseVersionPtr> javas_bvp;
+ QList<BaseVersion::Ptr> javas_bvp;
for (auto java : candidates)
{
//qDebug() << java->id << java->arch << " at " << java->path;
- BaseVersionPtr bp_java = std::dynamic_pointer_cast<BaseVersion>(java);
+ BaseVersion::Ptr bp_java = std::dynamic_pointer_cast<BaseVersion>(java);
if (bp_java)
{
diff --git a/launcher/java/JavaInstallList.h b/launcher/java/JavaInstallList.h
index 3c237edf..733dc7e1 100644
--- a/launcher/java/JavaInstallList.h
+++ b/launcher/java/JavaInstallList.h
@@ -42,7 +42,7 @@ public:
Task::Ptr getLoadTask() override;
bool isLoaded() override;
- const BaseVersionPtr at(int i) const override;
+ const BaseVersion::Ptr at(int i) const override;
int count() const override;
void sortVersions() override;
@@ -50,7 +50,7 @@ public:
RoleList providesRoles() const override;
public slots:
- void updateListData(QList<BaseVersionPtr> versions) override;
+ void updateListData(QList<BaseVersion::Ptr> versions) override;
protected:
void load();
@@ -59,7 +59,7 @@ protected:
protected:
Status m_status = Status::NotDone;
shared_qobject_ptr<JavaListLoadTask> m_loadTask;
- QList<BaseVersionPtr> m_vlist;
+ QList<BaseVersion::Ptr> m_vlist;
};
class JavaListLoadTask : public Task
diff --git a/launcher/java/JavaUtils.cpp b/launcher/java/JavaUtils.cpp
index 040fe821..6c0c60cd 100644
--- a/launcher/java/JavaUtils.cpp
+++ b/launcher/java/JavaUtils.cpp
@@ -379,7 +379,9 @@ QList<QString> JavaUtils::FindJavaPaths()
}
}
- return addJavasFromEnv(candidates);
+ candidates = addJavasFromEnv(candidates);
+ candidates.removeDuplicates();
+ return candidates;
}
#elif defined(Q_OS_MAC)
@@ -402,7 +404,9 @@ QList<QString> JavaUtils::FindJavaPaths()
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java");
}
- return addJavasFromEnv(javas);
+ javas = addJavasFromEnv(javas);
+ javas.removeDuplicates();
+ return javas;
}
#elif defined(Q_OS_LINUX)
@@ -448,7 +452,9 @@ QList<QString> JavaUtils::FindJavaPaths()
scanJavaDir("/opt/jdks");
// flatpak
scanJavaDir("/app/jdk");
- return addJavasFromEnv(javas);
+ javas = addJavasFromEnv(javas);
+ javas.removeDuplicates();
+ return javas;
}
#else
QList<QString> JavaUtils::FindJavaPaths()
diff --git a/launcher/main.cpp b/launcher/main.cpp
index c6a7614c..e2116f38 100644
--- a/launcher/main.cpp
+++ b/launcher/main.cpp
@@ -84,6 +84,7 @@ int main(int argc, char *argv[])
Q_INIT_RESOURCE(OSX);
Q_INIT_RESOURCE(iOS);
Q_INIT_RESOURCE(flat);
+ Q_INIT_RESOURCE(flat_white);
return app.exec();
}
case Application::Failed:
diff --git a/launcher/meta/Index.cpp b/launcher/meta/Index.cpp
index 6802470d..eec1b329 100644
--- a/launcher/meta/Index.cpp
+++ b/launcher/meta/Index.cpp
@@ -24,7 +24,7 @@ Index::Index(QObject *parent)
: QAbstractListModel(parent)
{
}
-Index::Index(const QVector<VersionListPtr> &lists, QObject *parent)
+Index::Index(const QVector<VersionList::Ptr> &lists, QObject *parent)
: QAbstractListModel(parent), m_lists(lists)
{
for (int i = 0; i < m_lists.size(); ++i)
@@ -41,7 +41,7 @@ QVariant Index::data(const QModelIndex &index, int role) const
return QVariant();
}
- VersionListPtr list = m_lists.at(index.row());
+ VersionList::Ptr list = m_lists.at(index.row());
switch (role)
{
case Qt::DisplayRole:
@@ -81,9 +81,9 @@ bool Index::hasUid(const QString &uid) const
return m_uids.contains(uid);
}
-VersionListPtr Index::get(const QString &uid)
+VersionList::Ptr Index::get(const QString &uid)
{
- VersionListPtr out = m_uids.value(uid, nullptr);
+ VersionList::Ptr out = m_uids.value(uid, nullptr);
if(!out)
{
out = std::make_shared<VersionList>(uid);
@@ -92,7 +92,7 @@ VersionListPtr Index::get(const QString &uid)
return out;
}
-VersionPtr Index::get(const QString &uid, const QString &version)
+Version::Ptr Index::get(const QString &uid, const QString &version)
{
auto list = get(uid);
return list->getVersion(version);
@@ -105,7 +105,7 @@ void Index::parse(const QJsonObject& obj)
void Index::merge(const std::shared_ptr<Index> &other)
{
- const QVector<VersionListPtr> lists = std::dynamic_pointer_cast<Index>(other)->m_lists;
+ const QVector<VersionList::Ptr> lists = std::dynamic_pointer_cast<Index>(other)->m_lists;
// initial load, no need to merge
if (m_lists.isEmpty())
{
@@ -120,7 +120,7 @@ void Index::merge(const std::shared_ptr<Index> &other)
}
else
{
- for (const VersionListPtr &list : lists)
+ for (const VersionList::Ptr &list : lists)
{
if (m_uids.contains(list->uid()))
{
@@ -138,7 +138,7 @@ void Index::merge(const std::shared_ptr<Index> &other)
}
}
-void Index::connectVersionList(const int row, const VersionListPtr &list)
+void Index::connectVersionList(const int row, const VersionList::Ptr &list)
{
connect(list.get(), &VersionList::nameChanged, this, [this, row]()
{
diff --git a/launcher/meta/Index.h b/launcher/meta/Index.h
index d33ab0c8..06ea09dc 100644
--- a/launcher/meta/Index.h
+++ b/launcher/meta/Index.h
@@ -19,20 +19,19 @@
#include <memory>
#include "BaseEntity.h"
+#include "meta/VersionList.h"
class Task;
namespace Meta
{
-using VersionListPtr = std::shared_ptr<class VersionList>;
-using VersionPtr = std::shared_ptr<class Version>;
class Index : public QAbstractListModel, public BaseEntity
{
Q_OBJECT
public:
explicit Index(QObject *parent = nullptr);
- explicit Index(const QVector<VersionListPtr> &lists, QObject *parent = nullptr);
+ explicit Index(const QVector<VersionList::Ptr> &lists, QObject *parent = nullptr);
enum
{
@@ -49,21 +48,21 @@ public:
QString localFilename() const override { return "index.json"; }
// queries
- VersionListPtr get(const QString &uid);
- VersionPtr get(const QString &uid, const QString &version);
+ VersionList::Ptr get(const QString &uid);
+ Version::Ptr get(const QString &uid, const QString &version);
bool hasUid(const QString &uid) const;
- QVector<VersionListPtr> lists() const { return m_lists; }
+ QVector<VersionList::Ptr> lists() const { return m_lists; }
public: // for usage by parsers only
void merge(const std::shared_ptr<Index> &other);
void parse(const QJsonObject &obj) override;
private:
- QVector<VersionListPtr> m_lists;
- QHash<QString, VersionListPtr> m_uids;
+ QVector<VersionList::Ptr> m_lists;
+ QHash<QString, VersionList::Ptr> m_uids;
- void connectVersionList(const int row, const VersionListPtr &list);
+ void connectVersionList(const int row, const VersionList::Ptr &list);
};
}
diff --git a/launcher/meta/JsonFormat.cpp b/launcher/meta/JsonFormat.cpp
index 796da4bb..473f37d6 100644
--- a/launcher/meta/JsonFormat.cpp
+++ b/launcher/meta/JsonFormat.cpp
@@ -37,11 +37,11 @@ MetadataVersion currentFormatVersion()
static std::shared_ptr<Index> parseIndexInternal(const QJsonObject &obj)
{
const QVector<QJsonObject> objects = requireIsArrayOf<QJsonObject>(obj, "packages");
- QVector<VersionListPtr> lists;
+ QVector<VersionList::Ptr> lists;
lists.reserve(objects.size());
std::transform(objects.begin(), objects.end(), std::back_inserter(lists), [](const QJsonObject &obj)
{
- VersionListPtr list = std::make_shared<VersionList>(requireString(obj, "uid"));
+ VersionList::Ptr list = std::make_shared<VersionList>(requireString(obj, "uid"));
list->setName(ensureString(obj, "name", QString()));
return list;
});
@@ -49,9 +49,9 @@ static std::shared_ptr<Index> parseIndexInternal(const QJsonObject &obj)
}
// Version
-static VersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj)
+static Version::Ptr parseCommonVersion(const QString &uid, const QJsonObject &obj)
{
- VersionPtr version = std::make_shared<Version>(uid, requireString(obj, "version"));
+ Version::Ptr version = std::make_shared<Version>(uid, requireString(obj, "version"));
version->setTime(QDateTime::fromString(requireString(obj, "releaseTime"), Qt::ISODate).toMSecsSinceEpoch() / 1000);
version->setType(ensureString(obj, "type", QString()));
version->setRecommended(ensureBoolean(obj, QString("recommended"), false));
@@ -63,9 +63,9 @@ static VersionPtr parseCommonVersion(const QString &uid, const QJsonObject &obj)
return version;
}
-static std::shared_ptr<Version> parseVersionInternal(const QJsonObject &obj)
+static Version::Ptr parseVersionInternal(const QJsonObject &obj)
{
- VersionPtr version = parseCommonVersion(requireString(obj, "uid"), obj);
+ Version::Ptr version = parseCommonVersion(requireString(obj, "uid"), obj);
version->setData(OneSixVersionFormat::versionFileFromJson(QJsonDocument(obj),
QString("%1/%2.json").arg(version->uid(), version->version()),
@@ -74,12 +74,12 @@ static std::shared_ptr<Version> parseVersionInternal(const QJsonObject &obj)
}
// Version list / package
-static std::shared_ptr<VersionList> parseVersionListInternal(const QJsonObject &obj)
+static VersionList::Ptr parseVersionListInternal(const QJsonObject &obj)
{
const QString uid = requireString(obj, "uid");
const QVector<QJsonObject> versionsRaw = requireIsArrayOf<QJsonObject>(obj, "versions");
- QVector<VersionPtr> versions;
+ QVector<Version::Ptr> versions;
versions.reserve(versionsRaw.size());
std::transform(versionsRaw.begin(), versionsRaw.end(), std::back_inserter(versions), [uid](const QJsonObject &vObj)
{
@@ -88,7 +88,7 @@ static std::shared_ptr<VersionList> parseVersionListInternal(const QJsonObject &
return version;
});
- VersionListPtr list = std::make_shared<VersionList>(uid);
+ VersionList::Ptr list = std::make_shared<VersionList>(uid);
list->setName(ensureString(obj, "name", QString()));
list->setVersions(versions);
return list;
diff --git a/launcher/meta/Version.cpp b/launcher/meta/Version.cpp
index a8dc3169..68cfa55c 100644
--- a/launcher/meta/Version.cpp
+++ b/launcher/meta/Version.cpp
@@ -54,7 +54,7 @@ void Meta::Version::parse(const QJsonObject& obj)
parseVersion(obj, this);
}
-void Meta::Version::mergeFromList(const Meta::VersionPtr& other)
+void Meta::Version::mergeFromList(const Meta::Version::Ptr& other)
{
if(other->m_providesRecommendations)
{
@@ -85,7 +85,7 @@ void Meta::Version::mergeFromList(const Meta::VersionPtr& other)
}
}
-void Meta::Version::merge(const VersionPtr &other)
+void Meta::Version::merge(const Version::Ptr &other)
{
mergeFromList(other);
if(other->m_data)
diff --git a/launcher/meta/Version.h b/launcher/meta/Version.h
index dea8dc8a..7228fa36 100644
--- a/launcher/meta/Version.h
+++ b/launcher/meta/Version.h
@@ -30,13 +30,14 @@
namespace Meta
{
-using VersionPtr = std::shared_ptr<class Version>;
class Version : public QObject, public BaseVersion, public BaseEntity
{
Q_OBJECT
-public: /* con/des */
+public:
+ using Ptr = std::shared_ptr<Version>;
+
explicit Version(const QString &uid, const QString &version);
virtual ~Version();
@@ -78,8 +79,8 @@ public: /* con/des */
return m_data != nullptr;
}
- void merge(const VersionPtr &other);
- void mergeFromList(const VersionPtr &other);
+ void merge(const Version::Ptr &other);
+ void mergeFromList(const Version::Ptr &other);
void parse(const QJsonObject &obj) override;
QString localFilename() const override;
@@ -113,4 +114,4 @@ private:
};
}
-Q_DECLARE_METATYPE(Meta::VersionPtr)
+Q_DECLARE_METATYPE(Meta::Version::Ptr)
diff --git a/launcher/meta/VersionList.cpp b/launcher/meta/VersionList.cpp
index f609e94c..7f001dfc 100644
--- a/launcher/meta/VersionList.cpp
+++ b/launcher/meta/VersionList.cpp
@@ -40,7 +40,7 @@ bool VersionList::isLoaded()
return BaseEntity::isLoaded();
}
-const BaseVersionPtr VersionList::at(int i) const
+const BaseVersion::Ptr VersionList::at(int i) const
{
return m_versions.at(i);
}
@@ -52,7 +52,7 @@ int VersionList::count() const
void VersionList::sortVersions()
{
beginResetModel();
- std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b)
+ std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr &a, const Version::Ptr &b)
{
return *a.get() < *b.get();
});
@@ -66,7 +66,7 @@ QVariant VersionList::data(const QModelIndex &index, int role) const
return QVariant();
}
- VersionPtr version = m_versions.at(index.row());
+ Version::Ptr version = m_versions.at(index.row());
switch (role)
{
@@ -129,9 +129,9 @@ QString VersionList::humanReadable() const
return m_name.isEmpty() ? m_uid : m_name;
}
-VersionPtr VersionList::getVersion(const QString &version)
+Version::Ptr VersionList::getVersion(const QString &version)
{
- VersionPtr out = m_lookup.value(version, nullptr);
+ Version::Ptr out = m_lookup.value(version, nullptr);
if(!out)
{
out = std::make_shared<Version>(m_uid, version);
@@ -143,7 +143,7 @@ VersionPtr VersionList::getVersion(const QString &version)
bool VersionList::hasVersion(QString version) const
{
auto ver = std::find_if(m_versions.constBegin(), m_versions.constEnd(),
- [&](Meta::VersionPtr const& a){ return a->version() == version; });
+ [&](Meta::Version::Ptr const& a){ return a->version() == version; });
return (ver != m_versions.constEnd());
}
@@ -153,11 +153,11 @@ void VersionList::setName(const QString &name)
emit nameChanged(name);
}
-void VersionList::setVersions(const QVector<VersionPtr> &versions)
+void VersionList::setVersions(const QVector<Version::Ptr> &versions)
{
beginResetModel();
m_versions = versions;
- std::sort(m_versions.begin(), m_versions.end(), [](const VersionPtr &a, const VersionPtr &b)
+ std::sort(m_versions.begin(), m_versions.end(), [](const Version::Ptr &a, const Version::Ptr &b)
{
return a->rawTime() > b->rawTime();
});
@@ -168,7 +168,7 @@ void VersionList::setVersions(const QVector<VersionPtr> &versions)
}
// FIXME: this is dumb, we have 'recommended' as part of the metadata already...
- auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const VersionPtr &ptr) { return ptr->type() == "release"; });
+ auto recommendedIt = std::find_if(m_versions.constBegin(), m_versions.constEnd(), [](const Version::Ptr &ptr) { return ptr->type() == "release"; });
m_recommended = recommendedIt == m_versions.constEnd() ? nullptr : *recommendedIt;
endResetModel();
}
@@ -179,7 +179,7 @@ void VersionList::parse(const QJsonObject& obj)
}
// FIXME: this is dumb, we have 'recommended' as part of the metadata already...
-static const Meta::VersionPtr &getBetterVersion(const Meta::VersionPtr &a, const Meta::VersionPtr &b)
+static const Meta::Version::Ptr &getBetterVersion(const Meta::Version::Ptr &a, const Meta::Version::Ptr &b)
{
if(!a)
return b;
@@ -194,7 +194,7 @@ static const Meta::VersionPtr &getBetterVersion(const Meta::VersionPtr &a, const
return (a->type() == "release" ? a : b);
}
-void VersionList::mergeFromIndex(const VersionListPtr &other)
+void VersionList::mergeFromIndex(const VersionList::Ptr &other)
{
if (m_name != other->m_name)
{
@@ -202,7 +202,7 @@ void VersionList::mergeFromIndex(const VersionListPtr &other)
}
}
-void VersionList::merge(const VersionListPtr &other)
+void VersionList::merge(const VersionList::Ptr &other)
{
if (m_name != other->m_name)
{
@@ -216,7 +216,7 @@ void VersionList::merge(const VersionListPtr &other)
{
qWarning() << "Empty list loaded ...";
}
- for (const VersionPtr &version : other->m_versions)
+ for (const Version::Ptr &version : other->m_versions)
{
// we already have the version. merge the contents
if (m_lookup.contains(version->version()))
@@ -235,7 +235,7 @@ void VersionList::merge(const VersionListPtr &other)
endResetModel();
}
-void VersionList::setupAddedVersion(const int row, const VersionPtr &version)
+void VersionList::setupAddedVersion(const int row, const Version::Ptr &version)
{
// FIXME: do not disconnect from everythin, disconnect only the lambdas here
version->disconnect();
@@ -244,7 +244,7 @@ void VersionList::setupAddedVersion(const int row, const VersionPtr &version)
connect(version.get(), &Version::typeChanged, this, [this, row]() { emit dataChanged(index(row), index(row), QVector<int>() << TypeRole); });
}
-BaseVersionPtr VersionList::getRecommended() const
+BaseVersion::Ptr VersionList::getRecommended() const
{
return m_recommended;
}
diff --git a/launcher/meta/VersionList.h b/launcher/meta/VersionList.h
index a6db2fd7..a4d5603d 100644
--- a/launcher/meta/VersionList.h
+++ b/launcher/meta/VersionList.h
@@ -20,10 +20,10 @@
#include <QJsonObject>
#include <memory>
+#include "meta/Version.h"
+
namespace Meta
{
-using VersionPtr = std::shared_ptr<class Version>;
-using VersionListPtr = std::shared_ptr<class VersionList>;
class VersionList : public BaseVersionList, public BaseEntity
{
@@ -33,6 +33,8 @@ class VersionList : public BaseVersionList, public BaseEntity
public:
explicit VersionList(const QString &uid, QObject *parent = nullptr);
+ using Ptr = std::shared_ptr<VersionList>;
+
enum Roles
{
UidRole = Qt::UserRole + 100,
@@ -43,11 +45,11 @@ public:
Task::Ptr getLoadTask() override;
bool isLoaded() override;
- const BaseVersionPtr at(int i) const override;
+ const BaseVersion::Ptr at(int i) const override;
int count() const override;
void sortVersions() override;
- BaseVersionPtr getRecommended() const override;
+ BaseVersion::Ptr getRecommended() const override;
QVariant data(const QModelIndex &index, int role) const override;
RoleList providesRoles() const override;
@@ -65,38 +67,38 @@ public:
}
QString humanReadable() const;
- VersionPtr getVersion(const QString &version);
+ Version::Ptr getVersion(const QString &version);
bool hasVersion(QString version) const;
- QVector<VersionPtr> versions() const
+ QVector<Version::Ptr> versions() const
{
return m_versions;
}
public: // for usage only by parsers
void setName(const QString &name);
- void setVersions(const QVector<VersionPtr> &versions);
- void merge(const VersionListPtr &other);
- void mergeFromIndex(const VersionListPtr &other);
+ void setVersions(const QVector<Version::Ptr> &versions);
+ void merge(const VersionList::Ptr &other);
+ void mergeFromIndex(const VersionList::Ptr &other);
void parse(const QJsonObject &obj) override;
signals:
void nameChanged(const QString &name);
protected slots:
- void updateListData(QList<BaseVersionPtr>) override
+ void updateListData(QList<BaseVersion::Ptr>) override
{
}
private:
- QVector<VersionPtr> m_versions;
- QHash<QString, VersionPtr> m_lookup;
+ QVector<Version::Ptr> m_versions;
+ QHash<QString, Version::Ptr> m_lookup;
QString m_uid;
QString m_name;
- VersionPtr m_recommended;
+ Version::Ptr m_recommended;
- void setupAddedVersion(const int row, const VersionPtr &version);
+ void setupAddedVersion(const int row, const Version::Ptr &version);
};
}
-Q_DECLARE_METATYPE(Meta::VersionListPtr)
+Q_DECLARE_METATYPE(Meta::VersionList::Ptr)
diff --git a/launcher/minecraft/VanillaInstanceCreationTask.cpp b/launcher/minecraft/VanillaInstanceCreationTask.cpp
index c45daa9a..0bb92e87 100644
--- a/launcher/minecraft/VanillaInstanceCreationTask.cpp
+++ b/launcher/minecraft/VanillaInstanceCreationTask.cpp
@@ -7,7 +7,7 @@
#include "minecraft/PackProfile.h"
#include "settings/INISettingsObject.h"
-VanillaCreationTask::VanillaCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loader_version)
+VanillaCreationTask::VanillaCreationTask(BaseVersion::Ptr version, QString loader, BaseVersion::Ptr loader_version)
: InstanceCreationTask(), m_version(std::move(version)), m_using_loader(true), m_loader(std::move(loader)), m_loader_version(std::move(loader_version))
{}
diff --git a/launcher/minecraft/VanillaInstanceCreationTask.h b/launcher/minecraft/VanillaInstanceCreationTask.h
index 7a37bbd6..d1b81682 100644
--- a/launcher/minecraft/VanillaInstanceCreationTask.h
+++ b/launcher/minecraft/VanillaInstanceCreationTask.h
@@ -7,16 +7,16 @@
class VanillaCreationTask final : public InstanceCreationTask {
Q_OBJECT
public:
- VanillaCreationTask(BaseVersionPtr version) : InstanceCreationTask(), m_version(std::move(version)) {}
- VanillaCreationTask(BaseVersionPtr version, QString loader, BaseVersionPtr loader_version);
+ VanillaCreationTask(BaseVersion::Ptr version) : InstanceCreationTask(), m_version(std::move(version)) {}
+ VanillaCreationTask(BaseVersion::Ptr version, QString loader, BaseVersion::Ptr loader_version);
bool createInstance() override;
private:
// Version to update to / create of the instance.
- BaseVersionPtr m_version;
+ BaseVersion::Ptr m_version;
bool m_using_loader = false;
QString m_loader;
- BaseVersionPtr m_loader_version;
+ BaseVersion::Ptr m_loader_version;
};
diff --git a/launcher/minecraft/launch/VerifyJavaInstall.cpp b/launcher/minecraft/launch/VerifyJavaInstall.cpp
index 99809f82..6ae666b4 100644
--- a/launcher/minecraft/launch/VerifyJavaInstall.cpp
+++ b/launcher/minecraft/launch/VerifyJavaInstall.cpp
@@ -71,5 +71,7 @@ void VerifyJavaInstall::executeTask() {
{
emit logLine(tr("Java version %1").arg(major), MessageLevel::Error);
}
+ emit logLine(tr("Go to instance Java settings to change your Java version or disable the Java compatibility check if you know what you're doing."), MessageLevel::Error);
+
emitFailed(QString("Incompatible Java major version"));
}
diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp
index a553eafd..291ad916 100644
--- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp
+++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp
@@ -58,7 +58,7 @@
namespace ATLauncher {
-static Meta::VersionPtr getComponentVersion(const QString& uid, const QString& version);
+static Meta::Version::Ptr getComponentVersion(const QString& uid, const QString& version);
PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString packName, QString version, InstallMode installMode)
{
@@ -736,7 +736,12 @@ void PackInstallTask::downloadMods()
QVector<QString> selectedMods;
if (!optionalMods.isEmpty()) {
setStatus(tr("Selecting optional mods..."));
- selectedMods = m_support->chooseOptionalMods(m_version, optionalMods);
+ auto mods = m_support->chooseOptionalMods(m_version, optionalMods);
+ if (!mods.has_value()) {
+ emitAborted();
+ return;
+ }
+ selectedMods = mods.value();
}
setStatus(tr("Downloading mods..."));
@@ -1032,7 +1037,7 @@ void PackInstallTask::install()
emitSucceeded();
}
-static Meta::VersionPtr getComponentVersion(const QString& uid, const QString& version)
+static Meta::Version::Ptr getComponentVersion(const QString& uid, const QString& version)
{
auto vlist = APPLICATION->metadataIndex()->get(uid);
if (!vlist)
diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.h b/launcher/modplatform/atlauncher/ATLPackInstallTask.h
index ed4436f0..90e25ae2 100644
--- a/launcher/modplatform/atlauncher/ATLPackInstallTask.h
+++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.h
@@ -62,13 +62,13 @@ public:
/**
* Requests a user interaction to select which optional mods should be installed.
*/
- virtual QVector<QString> chooseOptionalMods(PackVersion version, QVector<ATLauncher::VersionMod> mods) = 0;
+ virtual std::optional<QVector<QString>> chooseOptionalMods(PackVersion version, QVector<ATLauncher::VersionMod> mods) = 0;
/**
* Requests a user interaction to select a component version from a given version list
* and constrained to a given Minecraft version.
*/
- virtual QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) = 0;
+ virtual QString chooseVersion(Meta::VersionList::Ptr vlist, QString minecraftVersion) = 0;
/**
* Requests a user interaction to display a message.
@@ -137,8 +137,8 @@ private:
QString archivePath;
QStringList jarmods;
- Meta::VersionPtr minecraftVersion;
- QMap<QString, Meta::VersionPtr> componentsToInstall;
+ Meta::Version::Ptr minecraftVersion;
+ QMap<QString, Meta::Version::Ptr> componentsToInstall;
QFuture<std::optional<QStringList>> m_extractFuture;
QFutureWatcher<std::optional<QStringList>> m_extractFutureWatcher;
diff --git a/launcher/modplatform/flame/FileResolvingTask.cpp b/launcher/modplatform/flame/FileResolvingTask.cpp
index 1e7f5559..25b56fbd 100644
--- a/launcher/modplatform/flame/FileResolvingTask.cpp
+++ b/launcher/modplatform/flame/FileResolvingTask.cpp
@@ -3,6 +3,8 @@
#include "Json.h"
#include "net/Upload.h"
+#include "modplatform/modrinth/ModrinthPackIndex.h"
+
Flame::FileResolvingTask::FileResolvingTask(const shared_qobject_ptr<QNetworkAccessManager>& network, Flame::Manifest& toProcess)
: m_network(network), m_toProcess(toProcess)
{}
@@ -12,6 +14,8 @@ bool Flame::FileResolvingTask::abort()
bool aborted = true;
if (m_dljob)
aborted &= m_dljob->abort();
+ if (m_checkJob)
+ aborted &= m_checkJob->abort();
return aborted ? Task::abort() : false;
}
@@ -40,7 +44,7 @@ void Flame::FileResolvingTask::netJobFinished()
setProgress(1, 3);
int index = 0;
// job to check modrinth for blocked projects
- auto job = new NetJob("Modrinth check", m_network);
+ m_checkJob = new NetJob("Modrinth check", m_network);
blockedProjects = QMap<File *,QByteArray *>();
auto doc = Json::requireDocument(*result);
auto array = Json::requireArray(doc.object()["data"]);
@@ -60,15 +64,15 @@ void Flame::FileResolvingTask::netJobFinished()
out.resolved = true;
});
- job->addNetAction(dl);
+ m_checkJob->addNetAction(dl);
blockedProjects.insert(&out, output);
}
}
index++;
}
- connect(job, &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished);
+ connect(m_checkJob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::modrinthCheckFinished);
- job->start();
+ m_checkJob->start();
}
void Flame::FileResolvingTask::modrinthCheckFinished() {
@@ -82,18 +86,21 @@ void Flame::FileResolvingTask::modrinthCheckFinished() {
delete bytes;
continue;
}
+
QJsonDocument doc = QJsonDocument::fromJson(*bytes);
auto obj = doc.object();
- auto array = Json::requireArray(obj,"files");
- for (auto file: array) {
- auto fileObj = Json::requireObject(file);
- auto primary = Json::requireBoolean(fileObj,"primary");
- if (primary) {
- out->url = Json::requireUrl(fileObj,"url");
- qDebug() << "Found alternative on modrinth " << out->fileName;
- break;
- }
+ auto file = Modrinth::loadIndexedPackVersion(obj);
+
+ // If there's more than one mod loader for this version, we can't know for sure
+ // which file is relative to each loader, so it's best to not use any one and
+ // let the user download it manually.
+ if (file.loaders.size() <= 1) {
+ out->url = file.downloadUrl;
+ qDebug() << "Found alternative on modrinth " << out->fileName;
+ } else {
+ out->resolved = false;
}
+
delete bytes;
}
//copy to an output list and filter out projects found on modrinth
diff --git a/launcher/modplatform/flame/FileResolvingTask.h b/launcher/modplatform/flame/FileResolvingTask.h
index f71b87ce..8fc17ea9 100644
--- a/launcher/modplatform/flame/FileResolvingTask.h
+++ b/launcher/modplatform/flame/FileResolvingTask.h
@@ -30,8 +30,9 @@ protected slots:
private: /* data */
shared_qobject_ptr<QNetworkAccessManager> m_network;
Flame::Manifest m_toProcess;
- std::shared_ptr<QByteArray> result;
+ std::shared_ptr<QByteArray> result;
NetJob::Ptr m_dljob;
+ NetJob::Ptr m_checkJob;
void modrinthCheckFinished();
diff --git a/launcher/modplatform/helpers/NetworkModAPI.cpp b/launcher/modplatform/helpers/NetworkModAPI.cpp
index 866e7540..7633030e 100644
--- a/launcher/modplatform/helpers/NetworkModAPI.cpp
+++ b/launcher/modplatform/helpers/NetworkModAPI.cpp
@@ -15,6 +15,7 @@ void NetworkModAPI::searchMods(CallerType* caller, SearchArgs&& args) const
QObject::connect(netJob, &NetJob::started, caller, [caller, netJob] { caller->setActiveJob(netJob); });
QObject::connect(netJob, &NetJob::failed, caller, &CallerType::searchRequestFailed);
+ QObject::connect(netJob, &NetJob::aborted, caller, &CallerType::searchRequestAborted);
QObject::connect(netJob, &NetJob::succeeded, caller, [caller, response] {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
diff --git a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp
index 3e53becb..ae45e096 100644
--- a/launcher/modplatform/modrinth/ModrinthPackIndex.cpp
+++ b/launcher/modplatform/modrinth/ModrinthPackIndex.cpp
@@ -1,20 +1,20 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
-* PolyMC - Minecraft Launcher
-* Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
-*
-* 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, version 3.
-*
-* 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, see <https://www.gnu.org/licenses/>.
-*/
+ * PolyMC - Minecraft Launcher
+ * Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
+ *
+ * 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, version 3.
+ *
+ * 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, see <https://www.gnu.org/licenses/>.
+ */
#include "ModrinthPackIndex.h"
#include "ModrinthAPI.h"
@@ -35,7 +35,7 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
pack.provider = ModPlatform::Provider::MODRINTH;
pack.name = Json::requireString(obj, "title");
-
+
pack.slug = Json::ensureString(obj, "slug", "");
if (!pack.slug.isEmpty())
pack.websiteUrl = "https://modrinth.com/mod/" + pack.slug;
@@ -59,23 +59,23 @@ void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
void Modrinth::loadExtraPackData(ModPlatform::IndexedPack& pack, QJsonObject& obj)
{
pack.extraData.issuesUrl = Json::ensureString(obj, "issues_url");
- if(pack.extraData.issuesUrl.endsWith('/'))
+ if (pack.extraData.issuesUrl.endsWith('/'))
pack.extraData.issuesUrl.chop(1);
pack.extraData.sourceUrl = Json::ensureString(obj, "source_url");
- if(pack.extraData.sourceUrl.endsWith('/'))
+ if (pack.extraData.sourceUrl.endsWith('/'))
pack.extraData.sourceUrl.chop(1);
pack.extraData.wikiUrl = Json::ensureString(obj, "wiki_url");
- if(pack.extraData.wikiUrl.endsWith('/'))
+ if (pack.extraData.wikiUrl.endsWith('/'))
pack.extraData.wikiUrl.chop(1);
pack.extraData.discordUrl = Json::ensureString(obj, "discord_url");
- if(pack.extraData.discordUrl.endsWith('/'))
+ if (pack.extraData.discordUrl.endsWith('/'))
pack.extraData.discordUrl.chop(1);
auto donate_arr = Json::ensureArray(obj, "donation_urls");
- for(auto d : donate_arr){
+ for (auto d : donate_arr) {
auto d_obj = Json::requireObject(d);
ModPlatform::DonationData donate;
@@ -104,7 +104,7 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
auto obj = versionIter.toObject();
auto file = loadIndexedPackVersion(obj);
- if(file.fileId.isValid()) // Heuristic to check if the returned value is valid
+ if (file.fileId.isValid()) // Heuristic to check if the returned value is valid
unsortedVersions.append(file);
}
auto orderSortPredicate = [](const ModPlatform::IndexedVersion& a, const ModPlatform::IndexedVersion& b) -> bool {
@@ -116,7 +116,8 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack,
pack.versionsLoaded = true;
}
-auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_type, QString preferred_file_name) -> ModPlatform::IndexedVersion
+auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_type, QString preferred_file_name)
+ -> ModPlatform::IndexedVersion
{
ModPlatform::IndexedVersion file;
@@ -141,6 +142,12 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_t
auto files = Json::requireArray(obj, "files");
int i = 0;
+ if (files.empty()) {
+ // This should not happen normally, but check just in case
+ qWarning() << "Modrinth returned an unexpected empty list of files:" << obj;
+ return {};
+ }
+
// Find correct file (needed in cases where one version may have multiple files)
// Will default to the last one if there's no primary (though I think Modrinth requires that
// at least one file is primary, idk)
@@ -167,7 +174,7 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject &obj, QString preferred_hash_t
file.fileName = Json::requireString(parent, "filename");
file.is_preferred = Json::requireBoolean(parent, "primary") || (files.count() == 1);
auto hash_list = Json::requireObject(parent, "hashes");
-
+
if (hash_list.contains(preferred_hash_type)) {
file.hash = Json::requireString(hash_list, preferred_hash_type);
file.hash_type = preferred_hash_type;
diff --git a/launcher/resources/OSX/OSX.qrc b/launcher/resources/OSX/OSX.qrc
index 55be28b5..19fe312b 100644
--- a/launcher/resources/OSX/OSX.qrc
+++ b/launcher/resources/OSX/OSX.qrc
@@ -38,5 +38,6 @@
<file>scalable/tag.svg</file>
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
+ <file>scalable/launch.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/OSX/scalable/launch.svg b/launcher/resources/OSX/scalable/launch.svg
new file mode 100644
index 00000000..fb189162
--- /dev/null
+++ b/launcher/resources/OSX/scalable/launch.svg
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ id="Calque_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 32.099998 32"
+ enable-background="new 0 0 32 32"
+ xml:space="preserve"
+ width="32.099998"
+ height="32"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs45" />
+
+<rect
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ fill="none"
+ width="32"
+ height="32"
+ id="rect1776"
+ x="0.1"
+ y="0" /><path
+ fill="#b6b5b6"
+ d="M 30,28.4 H 2 c -1.1,0 -2,-0.9 -2,-2 v -18 c 0,-1.1 0.9,-2 2,-2 h 28 c 1.1,0 2,0.9 2,2 v 18 c 0,1.1 -0.9,2 -2,2 z"
+ id="path1778" /><path
+ fill="#fbfbfb"
+ d="M 30,27.4 H 2 c -1.1,0 -2,-0.9 -2,-2 v -17 c 0,-1.1 0.9,-2 2,-2 h 28 c 1.1,0 2,0.9 2,2 v 17 c 0,1.1 -0.9,2 -2,2 z"
+ id="path1780" /><path
+ id="path11889"
+ style="color:#000000;fill:#585858;fill-opacity:1;stroke-width:0.999994;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
+ d="m 11.520289,8.4637512 c -0.06474,-0.00183 -0.129661,-0.00125 -0.194234,0.00117 C 9.7763279,8.5230552 8.3049,9.7900155 8.3049,11.461507 v 10.877094 c -6e-7,2.228655 2.616628,3.738089 4.545774,2.622156 l 9.398109,-5.436205 c 1.928423,-1.115516 1.928423,-4.133479 0,-5.248993 L 12.850674,8.839348 C 12.428673,8.595238 11.973493,8.4765655 11.520289,8.4637512 Z m -0.184873,1.2309276 c 0.307885,1.456e-4 0.612521,0.080796 0.882242,0.2363567 a 0.89871379,0.89871379 0 0 0 0.0012,0 l 9.398109,5.4362075 c 1.143234,0.659415 1.143234,2.406201 0,3.065618 l -9.398109,5.436206 a 0.89871379,0.89871379 0 0 0 -0.0012,0 C 11.076744,24.528497 9.5659235,23.656375 9.56625,22.338599 V 11.461504 c 3.043e-4,-0.851902 0.622381,-1.5925143 1.461434,-1.7399133 0.102209,-0.018038 0.205103,-0.026958 0.307732,-0.026912 z" /></svg>
diff --git a/launcher/resources/OSX/scalable/launcher.svg b/launcher/resources/OSX/scalable/launcher.svg
index 69dd84b1..aeee8433 100644
--- a/launcher/resources/OSX/scalable/launcher.svg
+++ b/launcher/resources/OSX/scalable/launcher.svg
@@ -37,17 +37,21 @@
</cc:Agent>
</dc:contributor>
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
- <dc:rights>
- <cc:Agent>
- <dc:title>CC BY-SA 4.0</dc:title>
- </cc:Agent>
- </dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>Prism Launcher</dc:title>
</cc:Agent>
</dc:publisher>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
</cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
+ </cc:License>
</rdf:RDF>
</metadata>
</svg>
diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc
index 52921512..fb426707 100644
--- a/launcher/resources/backgrounds/backgrounds.qrc
+++ b/launcher/resources/backgrounds/backgrounds.qrc
@@ -1,8 +1,14 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/backgrounds">
- <file alias="kitteh">catbgrnd2.png</file>
- <file alias="catmas">catmas.png</file>
- <file alias="cattiversary">cattiversary.png</file>
+ <file alias="kitteh">kitteh.png</file>
+ <file alias="kitteh-xmas">kitteh-xmas.png</file>
+ <file alias="kitteh-bday">kitteh-bday.png</file>
+ <file alias="rory">rory.png</file>
+ <file alias="rory-xmas">rory-xmas.png</file>
+ <file alias="rory-bday">rory-bday.png</file>
+ <file alias="rory-flat">rory-flat.png</file>
+ <file alias="rory-flat-xmas">rory-flat-xmas.png</file>
+ <file alias="rory-flat-bday">rory-flat-bday.png</file>
</qresource>
</RCC>
diff --git a/launcher/resources/backgrounds/cattiversary.png b/launcher/resources/backgrounds/kitteh-bday.png
index 09a36566..09a36566 100644
--- a/launcher/resources/backgrounds/cattiversary.png
+++ b/launcher/resources/backgrounds/kitteh-bday.png
Binary files differ
diff --git a/launcher/resources/backgrounds/catmas.png b/launcher/resources/backgrounds/kitteh-xmas.png
index 8bdb1d5c..8bdb1d5c 100644
--- a/launcher/resources/backgrounds/catmas.png
+++ b/launcher/resources/backgrounds/kitteh-xmas.png
Binary files differ
diff --git a/launcher/resources/backgrounds/catbgrnd2.png b/launcher/resources/backgrounds/kitteh.png
index e9de7f27..e9de7f27 100644
--- a/launcher/resources/backgrounds/catbgrnd2.png
+++ b/launcher/resources/backgrounds/kitteh.png
Binary files differ
diff --git a/launcher/resources/backgrounds/rory-bday.png b/launcher/resources/backgrounds/rory-bday.png
new file mode 100644
index 00000000..66b88094
--- /dev/null
+++ b/launcher/resources/backgrounds/rory-bday.png
Binary files differ
diff --git a/launcher/resources/backgrounds/rory-flat-bday.png b/launcher/resources/backgrounds/rory-flat-bday.png
new file mode 100644
index 00000000..8a6e366d
--- /dev/null
+++ b/launcher/resources/backgrounds/rory-flat-bday.png
Binary files differ
diff --git a/launcher/resources/backgrounds/rory-flat-xmas.png b/launcher/resources/backgrounds/rory-flat-xmas.png
new file mode 100644
index 00000000..96c3ae38
--- /dev/null
+++ b/launcher/resources/backgrounds/rory-flat-xmas.png
Binary files differ
diff --git a/launcher/resources/backgrounds/rory-flat.png b/launcher/resources/backgrounds/rory-flat.png
new file mode 100644
index 00000000..ccec0662
--- /dev/null
+++ b/launcher/resources/backgrounds/rory-flat.png
Binary files differ
diff --git a/launcher/resources/backgrounds/rory-xmas.png b/launcher/resources/backgrounds/rory-xmas.png
new file mode 100644
index 00000000..107feb78
--- /dev/null
+++ b/launcher/resources/backgrounds/rory-xmas.png
Binary files differ
diff --git a/launcher/resources/backgrounds/rory.png b/launcher/resources/backgrounds/rory.png
new file mode 100644
index 00000000..577f4dce
--- /dev/null
+++ b/launcher/resources/backgrounds/rory.png
Binary files differ
diff --git a/launcher/resources/flat/flat.qrc b/launcher/resources/flat/flat.qrc
index 7f59da7b..508e0a9f 100644
--- a/launcher/resources/flat/flat.qrc
+++ b/launcher/resources/flat/flat.qrc
@@ -46,5 +46,6 @@
<file>scalable/tag.svg</file>
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
+ <file>scalable/launch.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/flat/scalable/launch.svg b/launcher/resources/flat/scalable/launch.svg
new file mode 100644
index 00000000..b462f2e4
--- /dev/null
+++ b/launcher/resources/flat/scalable/launch.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ fill="#757575"
+ height="48"
+ width="48"
+ version="1.1"
+ id="svg24108"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs24112" />
+ <path
+ d="M 11.674384,43.35533 V 4.3446706 L 42.325617,23.850001 Z"
+ id="path24106"
+ style="stroke-width:1" />
+</svg>
diff --git a/launcher/resources/flat/scalable/launcher.svg b/launcher/resources/flat/scalable/launcher.svg
index 69dd84b1..aeee8433 100644
--- a/launcher/resources/flat/scalable/launcher.svg
+++ b/launcher/resources/flat/scalable/launcher.svg
@@ -37,17 +37,21 @@
</cc:Agent>
</dc:contributor>
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
- <dc:rights>
- <cc:Agent>
- <dc:title>CC BY-SA 4.0</dc:title>
- </cc:Agent>
- </dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>Prism Launcher</dc:title>
</cc:Agent>
</dc:publisher>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
</cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
+ </cc:License>
</rdf:RDF>
</metadata>
</svg>
diff --git a/launcher/resources/flat_white/flat_white.qrc b/launcher/resources/flat_white/flat_white.qrc
new file mode 100644
index 00000000..e11d6316
--- /dev/null
+++ b/launcher/resources/flat_white/flat_white.qrc
@@ -0,0 +1,51 @@
+<!DOCTYPE RCC>
+<RCC version="1.0">
+ <qresource prefix="/icons/flat_white">
+ <file>index.theme</file>
+ <file>scalable/about.svg</file>
+ <file>scalable/accounts.svg</file>
+ <file>scalable/bug.svg</file>
+ <file>scalable/cat.svg</file>
+ <file>scalable/centralmods.svg</file>
+ <file>scalable/checkupdate.svg</file>
+ <file>scalable/copy.svg</file>
+ <file>scalable/coremods.svg</file>
+ <file>scalable/custom-commands.svg</file>
+ <file>scalable/discord.svg</file>
+ <file>scalable/externaltools.svg</file>
+ <file>scalable/help.svg</file>
+ <file>scalable/instance-settings.svg</file>
+ <file>scalable/jarmods.svg</file>
+ <file>scalable/java.svg</file>
+ <file>scalable/language.svg</file>
+ <file>scalable/launcher.svg</file>
+ <file>scalable/loadermods.svg</file>
+ <file>scalable/log.svg</file>
+ <file>scalable/minecraft.svg</file>
+ <file>scalable/new.svg</file>
+ <file>scalable/news.svg</file>
+ <file>scalable/notes.svg</file>
+ <file>scalable/packages.svg</file>
+ <file>scalable/proxy.svg</file>
+ <file>scalable/quickmods.svg</file>
+ <file>scalable/reddit-alien.svg</file>
+ <file>scalable/refresh.svg</file>
+ <file>scalable/resourcepacks.svg</file>
+ <file>scalable/shaderpacks.svg</file>
+ <file>scalable/screenshot-placeholder.svg</file>
+ <file>scalable/screenshots.svg</file>
+ <file>scalable/settings.svg</file>
+ <file>scalable/star.svg</file>
+ <file>scalable/status-bad.svg</file>
+ <file>scalable/status-good.svg</file>
+ <file>scalable/status-running.svg</file>
+ <file>scalable/status-yellow.svg</file>
+ <file>scalable/viewfolder.svg</file>
+ <file>scalable/worlds.svg</file>
+ <file>scalable/delete.svg</file>
+ <file>scalable/export.svg</file>
+ <file>scalable/rename.svg</file>
+ <file>scalable/tag.svg</file>
+ <file>scalable/launch.svg</file>
+ </qresource>
+</RCC>
diff --git a/launcher/resources/flat_white/index.theme b/launcher/resources/flat_white/index.theme
new file mode 100644
index 00000000..54dd0e10
--- /dev/null
+++ b/launcher/resources/flat_white/index.theme
@@ -0,0 +1,11 @@
+[Icon Theme]
+Name=Flat (White)
+Comment=White version of the flat icons (dark mode)
+Inherits=multimc
+Directories=scalable
+
+[scalable]
+Size=48
+Type=Scalable
+MinSize=16
+MaxSize=256
diff --git a/launcher/resources/flat_white/scalable/about.svg b/launcher/resources/flat_white/scalable/about.svg
new file mode 100644
index 00000000..e42ca948
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/about.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/accounts.svg b/launcher/resources/flat_white/scalable/accounts.svg
new file mode 100644
index 00000000..e714bde1
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/accounts.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M16,13C15.71,13 15.38,13 15.03,13.05C16.19,13.89 17,15 17,16.5V19H23V16.5C23,14.17 18.33,13 16,13M8,13C5.67,13 1,14.17 1,16.5V19H15V16.5C15,14.17 10.33,13 8,13M8,11A3,3 0 0,0 11,8A3,3 0 0,0 8,5A3,3 0 0,0 5,8A3,3 0 0,0 8,11M16,11A3,3 0 0,0 19,8A3,3 0 0,0 16,5A3,3 0 0,0 13,8A3,3 0 0,0 16,11Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/bug.svg b/launcher/resources/flat_white/scalable/bug.svg
new file mode 100644
index 00000000..3122702e
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/bug.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/cat.svg b/launcher/resources/flat_white/scalable/cat.svg
new file mode 100644
index 00000000..18da097a
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/cat.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12,8L10.67,8.09C9.81,7.07 7.4,4.5 5,4.5C5,4.5 3.03,7.46 4.96,11.41C4.41,12.24 4.07,12.67 4,13.66L2.07,13.95L2.28,14.93L4.04,14.67L4.18,15.38L2.61,16.32L3.08,17.21L4.53,16.32C5.68,18.76 8.59,20 12,20C15.41,20 18.32,18.76 19.47,16.32L20.92,17.21L21.39,16.32L19.82,15.38L19.96,14.67L21.72,14.93L21.93,13.95L20,13.66C19.93,12.67 19.59,12.24 19.04,11.41C20.97,7.46 19,4.5 19,4.5C16.6,4.5 14.19,7.07 13.33,8.09L12,8M9,11A1,1 0 0,1 10,12A1,1 0 0,1 9,13A1,1 0 0,1 8,12A1,1 0 0,1 9,11M15,11A1,1 0 0,1 16,12A1,1 0 0,1 15,13A1,1 0 0,1 14,12A1,1 0 0,1 15,11M11,14H13L12.3,15.39C12.5,16.03 13.06,16.5 13.75,16.5A1.5,1.5 0 0,0 15.25,15H15.75A2,2 0 0,1 13.75,17C13,17 12.35,16.59 12,16V16H12C11.65,16.59 11,17 10.25,17A2,2 0 0,1 8.25,15H8.75A1.5,1.5 0 0,0 10.25,16.5C10.94,16.5 11.5,16.03 11.7,15.39L11,14Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/centralmods.svg b/launcher/resources/flat_white/scalable/centralmods.svg
new file mode 100644
index 00000000..d8d10f2f
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/centralmods.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M20 6h-8l-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-2.06 11L15 15.28 12.06 17l.78-3.33-2.59-2.24 3.41-.29L15 8l1.34 3.14 3.41.29-2.59 2.24.78 3.33z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/checkupdate.svg b/launcher/resources/flat_white/scalable/checkupdate.svg
new file mode 100644
index 00000000..0fa66fc2
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/checkupdate.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M21 10.12h-6.78l2.74-2.82c-2.73-2.7-7.15-2.8-9.88-.1-2.73 2.71-2.73 7.08 0 9.79 2.73 2.71 7.15 2.71 9.88 0C18.32 15.65 19 14.08 19 12.1h2c0 1.98-.88 4.55-2.64 6.29-3.51 3.48-9.21 3.48-12.72 0-3.5-3.47-3.53-9.11-.02-12.58 3.51-3.47 9.14-3.47 12.65 0L21 3v7.12zM12.5 8v4.25l3.5 2.08-.72 1.21L11 13V8h1.5z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/copy.svg b/launcher/resources/flat_white/scalable/copy.svg
new file mode 100644
index 00000000..1aaed97b
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/copy.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/coremods.svg b/launcher/resources/flat_white/scalable/coremods.svg
new file mode 100644
index 00000000..32c34383
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/coremods.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M22,12A10,10,0,1,1,12,2,10,10,0,0,1,22,12ZM12,4a8,8,0,1,0,8,8A8,8,0,0,0,12,4Zm4.23,14-1.12-4.82,3.73-3.23-4.92-.42L12,5,10.08,9.54,5.16,10l3.73,3.23L7.77,18,12,15.45,16.23,18"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/custom-commands.svg b/launcher/resources/flat_white/scalable/custom-commands.svg
new file mode 100644
index 00000000..3d67d8f1
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/custom-commands.svg
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ fill="#D8DEE9"
+ height="24"
+ viewBox="0 0 24 24"
+ width="24"
+ version="1.1"
+ id="svg4"
+ sodipodi:docname="custom-commands.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="3440"
+ inkscape:window-height="1382"
+ id="namedview6"
+ showgrid="true"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:zoom="39.333333"
+ inkscape:cx="11.38983"
+ inkscape:cy="13.283898"
+ inkscape:window-x="0"
+ inkscape:window-y="32"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg4"
+ inkscape:pagecheckerboard="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid981" />
+ <sodipodi:guide
+ position="-8,11.440678"
+ orientation="1,0"
+ id="guide1060"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="-28.34375,24"
+ orientation="0,1"
+ id="guide1062"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <g
+ style="fill:#000000"
+ id="g821"
+ transform="matrix(0.0322459,0,0,0.0322459,-17.878956,30.647558)">
+ <g
+ style="fill:#000000"
+ id="g819" />
+ </g>
+ <g
+ id="g503">
+ <path
+ d="M 0,0 H 24 V 24 H 0 Z"
+ fill="none"
+ id="path491" />
+ <path
+ d="M 8.7,15.9 4.8,12 8.7,8.1 C 9.09,7.71 9.09,7.09 8.7,6.7 8.31,6.31 7.69,6.31 7.3,6.7 l -4.59,4.59 c -0.39,0.39 -0.39,1.02 0,1.41 l 4.59,4.6 c 0.39,0.39 1.01,0.39 1.4,0 0.39,-0.39 0.39,-1.01 0,-1.4 z m 6.6,0 3.9,-3.9 -3.9,-3.9 c -0.39,-0.39 -0.39,-1.01 0,-1.4 0.39,-0.39 1.01,-0.39 1.4,0 l 4.59,4.59 c 0.39,0.39 0.39,1.02 0,1.41 l -4.59,4.6 c -0.39,0.39 -1.01,0.39 -1.4,0 -0.39,-0.39 -0.39,-1.01 0,-1.4 z"
+ id="path493" />
+ </g>
+</svg>
diff --git a/launcher/resources/flat_white/scalable/delete.svg b/launcher/resources/flat_white/scalable/delete.svg
new file mode 100644
index 00000000..3365a96f
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/delete.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" version="1.1" id="svg4" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
+ <defs id="defs8"/>
+ <path id="path5145" style="fill:#D8DEE9;fill-opacity:1;stroke:none;stroke-width:1.4;stroke-linecap:square;stroke-linejoin:miter;stroke-dasharray:none" d="M 7.1074219 0.96484375 L 7.1074219 2.7304688 L 2.6132812 2.7304688 L 2.6132812 4.4960938 L 21.386719 4.4960938 L 21.386719 2.7304688 L 16.892578 2.7304688 L 16.892578 0.96484375 L 7.1074219 0.96484375 z M 5.0058594 6.0839844 L 5.0058594 22.859375 L 18.994141 22.859375 L 18.994141 6.0839844 L 5.0058594 6.0839844 z M 7.9160156 9.0605469 L 10.193359 9.0605469 L 10.193359 19.882812 L 7.9160156 19.882812 L 7.9160156 9.0605469 z M 13.804688 9.0605469 L 16.085938 9.0605469 L 16.085938 19.882812 L 13.804688 19.882812 L 13.804688 9.0605469 z "/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/discord.svg b/launcher/resources/flat_white/scalable/discord.svg
new file mode 100644
index 00000000..ee07ed25
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/discord.svg
@@ -0,0 +1,4 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M10.14,11.63a1.15,1.15,0,1,0,1,1.14A1.1,1.1,0,0,0,10.14,11.63Zm3.75,0a1.15,1.15,0,1,0,1,1.14A1.1,1.1,0,0,0,13.89,11.63Z"/>
+ <path d="M18.89,3H5.11A2.11,2.11,0,0,0,3,5.12V19a2.11,2.11,0,0,0,2.11,2.12H16.77l-.55-1.9,1.32,1.22,1.24,1.15,2.21,2V5.12A2.11,2.11,0,0,0,18.89,3Zm-4,13.43s-.37-.44-.68-.83a3.25,3.25,0,0,0,1.86-1.22,5.89,5.89,0,0,1-1.18.61,6.77,6.77,0,0,1-1.49.44,7.21,7.21,0,0,1-2.66,0A8.63,8.63,0,0,1,9.25,15a6,6,0,0,1-.75-.35l-.09-.05,0,0-.29-.17a3.2,3.2,0,0,0,1.8,1.21l-.69.85a3.73,3.73,0,0,1-3.14-1.56,13.77,13.77,0,0,1,1.48-6,5.09,5.09,0,0,1,2.89-1.08l.1.12A6.94,6.94,0,0,0,7.82,9.26s.23-.12.61-.3a7.72,7.72,0,0,1,2.33-.65l.17,0a8.7,8.7,0,0,1,2.08,0,8.38,8.38,0,0,1,3.1,1A6.85,6.85,0,0,0,13.55,8l.14-.16a5.09,5.09,0,0,1,2.89,1.08,13.77,13.77,0,0,1,1.48,6A3.76,3.76,0,0,1,14.92,16.43Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/export.svg b/launcher/resources/flat_white/scalable/export.svg
new file mode 100644
index 00000000..a28bb254
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/export.svg
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" version="1.1" id="svg4" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
+ <defs id="defs8"/>
+ <path id="path2" d="M 4 4 C 2.9000011 4 2.0097656 4.9000011 2.0097656 6 L 2 18 C 2 19.099999 2.9000011 20 4 20 L 20 20 C 21.099999 20 22 19.099999 22 18 L 22 8 C 22 6.9000011 21.099999 6 20 6 L 12 6 L 10 4 L 4 4 z M 12.537109 9.9082031 L 13.185547 10.298828 L 17.554688 12.929688 L 13.185547 15.5625 L 12.537109 15.953125 L 11.755859 14.65625 L 12.404297 14.265625 L 13.349609 13.695312 L 6.4453125 13.695312 L 6.4453125 12.166016 L 13.351562 12.166016 L 12.404297 11.595703 L 11.755859 11.205078 L 12.537109 9.9082031 z "/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/externaltools.svg b/launcher/resources/flat_white/scalable/externaltools.svg
new file mode 100644
index 00000000..e7c0930c
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/externaltools.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M22.7,19L13.6,9.9C14.5,7.6 14,4.9 12.1,3C10.1,1 7.1,0.6 4.7,1.7L9,6L6,9L1.6,4.7C0.4,7.1 0.9,10.1 2.9,12.1C4.8,14 7.5,14.5 9.8,13.6L18.9,22.7C19.3,23.1 19.9,23.1 20.3,22.7L22.6,20.4C23.1,20 23.1,19.3 22.7,19Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/help.svg b/launcher/resources/flat_white/scalable/help.svg
new file mode 100644
index 00000000..82b413fe
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/help.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ id="svg4"
+ version="1.1"
+ width="24"
+ viewBox="0 0 24 24"
+ height="24"
+ fill="#D8DEE9">
+ <path
+ d="m 15.07,11.25 -0.9,0.92 C 13.45,12.89 13,13.5 13,15 h -2 v -0.5 c 0,-1.11 0.45,-2.11 1.17,-2.83 l 1.24,-1.26 C 13.78,10.049999 14,9.549999 14,9 14,7.89 13.100001,7 12,7 A 2,2 0 0 0 10,9 H 7.9999995 A 4,4 0 0 1 12,5 4,4 0 0 1 16,9 c 0,0.879999 -0.36,1.67 -0.93,2.25 M 13,19 h -2 v -2 h 2 M 12,2 A 10,10 0 0 0 1.9999995,12 10,10 0 0 0 12,22 10,10 0 0 0 22,12 C 22,6.47 17.5,2 12,2 Z"
+ id="path817" />
+</svg>
diff --git a/launcher/resources/flat_white/scalable/instance-settings.svg b/launcher/resources/flat_white/scalable/instance-settings.svg
new file mode 100644
index 00000000..7dac7b14
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/instance-settings.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/jarmods.svg b/launcher/resources/flat_white/scalable/jarmods.svg
new file mode 100644
index 00000000..f0f298f3
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/jarmods.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M2,21H20V19H2M20,8H18V5h2m0-2H4V13a4,4,0,0,0,4,4h6a4,4,0,0,0,4-4V10h2a2,2,0,0,0,2-2V5A2,2,0,0,0,20,3ZM11,4.43l1.62,3.29,3.63.53-2.63,2.56.62,3.62L11,12.72,7.75,14.43l.62-3.62L5.74,8.25l3.63-.53Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/java.svg b/launcher/resources/flat_white/scalable/java.svg
new file mode 100644
index 00000000..56bb481f
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/java.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M2,21H20V19H2M20,8H18V5H20M20,3H4V13A4,4 0 0,0 8,17H14A4,4 0 0,0 18,13V10H20A2,2 0 0,0 22,8V5C22,3.89 21.1,3 20,3Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/language.svg b/launcher/resources/flat_white/scalable/language.svg
new file mode 100644
index 00000000..18c22efb
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/language.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ fill="#D8DEE9"
+ height="24"
+ viewBox="0 0 24 24"
+ width="24"
+ version="1.1"
+ id="svg4"
+ sodipodi:docname="language.svg"
+ inkscape:version="0.92.2 2405546, 2018-03-11">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="3840"
+ inkscape:window-height="2123"
+ id="namedview6"
+ showgrid="true"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:zoom="6.9532167"
+ inkscape:cx="-18.49351"
+ inkscape:cy="-12.477971"
+ inkscape:window-x="1200"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg4">
+ <inkscape:grid
+ type="xygrid"
+ id="grid981" />
+ <sodipodi:guide
+ position="-8,11.440678"
+ orientation="1,0"
+ id="guide1060"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="-28.34375,24"
+ orientation="0,1"
+ id="guide1062"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <path
+ d="M 5,3 C 3.89,3 3,3.89 3,5 v 14 c 0,1.104569 0.895431,2 2,2 h 14 c 1.104569,0 2,-0.895431 2,-2 V 5 C 21,3.89 20.1,3 19,3 Z m 10.359375,4.505859 c 0.400344,0 0.726563,0.326845 0.726563,0.728516 v 0.724609 h 2.21875 c 0.400344,0 0.726562,0.326845 0.726562,0.728516 0,0.401669 -0.326217,0.726562 -0.726562,0.726562 h -0.191407 c -0.412128,1.326612 -1.066893,2.363281 -1.746093,3.181641 0.53207,0.488052 1.100334,0.887517 1.666015,1.335938 0.311924,0.250518 0.365651,0.709744 0.115235,1.023437 -0.249259,0.313205 -0.708226,0.362473 -1.019532,0.111328 -0.614642,-0.486742 -1.192601,-0.892661 -1.769531,-1.423828 -0.576929,0.531167 -1.104107,0.937086 -1.71875,1.423828 -0.311303,0.251148 -0.768322,0.201879 -1.017578,-0.111328 -0.250416,-0.313693 -0.200604,-0.772919 0.111328,-1.023437 0.565677,-0.448421 1.087072,-0.847886 1.619141,-1.335938 -0.679199,-0.818312 -1.283234,-1.854981 -1.695313,-3.181641 h -0.197265 c -0.400344,0 -0.720704,-0.324893 -0.720704,-0.726562 0,-0.401671 0.320361,-0.728516 0.720704,-0.728516 h 2.173828 V 8.234375 c 0,-0.401671 0.324264,-0.728516 0.724609,-0.728516 z M 7.142578,7.800781 h 1.496094 c 0.345155,0 0.643047,0.243927 0.710937,0.582031 l 1.447266,7.244141 c 0.07851,0.39257 -0.174512,0.773053 -0.566406,0.851563 -0.384074,0.07905 -0.774336,-0.168718 -0.853516,-0.566407 L 8.914062,13.595703 H 6.867188 L 6.402344,15.912109 C 6.324551,16.303955 5.947553,16.559826 5.550781,16.478516 5.158934,16.400005 4.905865,16.019523 4.984375,15.626953 L 6.431641,8.382812 C 6.499536,8.044708 6.797425,7.800781 7.142578,7.800781 Z m 0.4375,1.632813 -0.578125,2.898437 H 8.46875 L 7.890625,9.433594 Z m 6.589844,0.980468 c 0.312752,0.842923 0.729088,1.524886 1.189453,2.105469 0.460366,-0.580583 0.925527,-1.262594 1.238281,-2.105469 z"
+ id="path1072"
+ inkscape:connector-curvature="0" />
+ <g
+ style="fill:#000000"
+ id="g821"
+ transform="matrix(0.0322459,0,0,0.0322459,-17.878956,30.647558)">
+ <g
+ style="fill:#000000"
+ id="g819" />
+ </g>
+</svg>
diff --git a/launcher/resources/flat_white/scalable/launch.svg b/launcher/resources/flat_white/scalable/launch.svg
new file mode 100644
index 00000000..9e759431
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/launch.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ fill="#D8DEE9"
+ height="48"
+ width="48"
+ version="1.1"
+ id="svg24108"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs24112" />
+ <path
+ d="M 11.674384,43.35533 V 4.3446706 L 42.325617,23.850001 Z"
+ id="path24106"
+ style="stroke-width:1" />
+</svg>
diff --git a/launcher/resources/flat_white/scalable/launcher.svg b/launcher/resources/flat_white/scalable/launcher.svg
new file mode 100644
index 00000000..d7ad0dd3
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/launcher.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24" height="24" fill="#D8DEE9" version="1.1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m20 4h-16v16h16zm0 18h-16c-1.1046 0-2-0.89543-2-2v-16c0-1.1046 0.89543-2 2-2h16c1.1046 0 2 0.89543 2 2v16c0 1.1046-0.89543 2-2 2z"/><path d="m7.2 18c-0.225 0-0.45-0.075-0.6-0.15-0.375-0.225-0.6-0.6-0.6-1.05v-9.6c0-0.45 0.225-0.825 0.6-1.05 0.225-0.15 0.375-0.15 0.6-0.15 0.15 0 0.375 0.075 0.525 0.15l9.6 4.8c0.375 0.225 0.675 0.6 0.675 1.05 0 0.45-0.225 0.9-0.675 1.05l-9.6 4.8c-0.15 0.075-0.375 0.15-0.525 0.15z" clip-rule="evenodd" fill="#D8DEE9" fill-rule="evenodd" stroke-width=".99999"/></svg>
diff --git a/launcher/resources/flat_white/scalable/loadermods.svg b/launcher/resources/flat_white/scalable/loadermods.svg
new file mode 100644
index 00000000..100f7a93
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/loadermods.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M16.23,18l-1.12-4.82,3.73-3.23-4.92-.42L12,5,10.08,9.54,5.16,10l3.73,3.23L7.77,18,12,15.45,16.23,18M20,4H4V20H20Zm0,18H4a2,2,0,0,1-2-2V4A2,2,0,0,1,4,2H20a2,2,0,0,1,2,2V20A2,2,0,0,1,20,22Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/log.svg b/launcher/resources/flat_white/scalable/log.svg
new file mode 100644
index 00000000..69b7c1dc
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/log.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zm2 16H8v-2h8v2zm0-4H8v-2h8v2zm-3-5V3.5L18.5 9H13z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/minecraft.svg b/launcher/resources/flat_white/scalable/minecraft.svg
new file mode 100644
index 00000000..a0348e79
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/minecraft.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M21,16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V7.5C3,7.12 3.21,6.79 3.53,6.62L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.79,6.79 21,7.12 21,7.5V16.5M12,4.15L6.04,7.5L12,10.85L17.96,7.5L12,4.15M5,15.91L11,19.29V12.58L5,9.21V15.91M19,15.91V9.21L13,12.58V19.29L19,15.91Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/multimc.svg b/launcher/resources/flat_white/scalable/multimc.svg
new file mode 100644
index 00000000..3dce2699
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/multimc.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M0,2A2,2,0,0,1,2,0H22a2,2,0,0,1,2,2V8L22,8V6H20V8H18v2H16V8H14V6H12V8H10V6H8v4H6V8H4V6H2V8H0ZM0,22a2,2,0,0,0,2,2H22a2,2,0,0,0,2-2V10H22V22H2V10H0Zm18.71-3.29a3.83,3.83,0,0,0-5.41-5.41L12,14.59l-1.29-1.29a3.83,3.83,0,1,0,0,5.41L12,17.41l1.29,1.29a3.83,3.83,0,0,0,5.41,0Zm-4-4a1.83,1.83,0,1,1,0,2.59L13.41,16Zm-5.41,0L10.59,16,9.29,17.29a1.83,1.83,0,1,1,0-2.59Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/new.svg b/launcher/resources/flat_white/scalable/new.svg
new file mode 100644
index 00000000..46dc3361
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/new.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-2 10h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/news.svg b/launcher/resources/flat_white/scalable/news.svg
new file mode 100644
index 00000000..414e5454
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/news.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M20,11H4V8H20M20,15H13V13H20M20,19H13V17H20M11,19H4V13H11M20.33,4.67L18.67,3L17,4.67L15.33,3L13.67,4.67L12,3L10.33,4.67L8.67,3L7,4.67L5.33,3L3.67,4.67L2,3V19A2,2 0 0,0 4,21H20A2,2 0 0,0 22,19V3L20.33,4.67Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/notes.svg b/launcher/resources/flat_white/scalable/notes.svg
new file mode 100644
index 00000000..4ce5f6f1
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/notes.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M14,17H7V15H14M17,13H7V11H17M17,9H7V7H17M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/packages.svg b/launcher/resources/flat_white/scalable/packages.svg
new file mode 100644
index 00000000..909ad0b2
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/packages.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M5.12,5l.81-1h12l.94,1m1.67.23L19.15,3.55A1.45,1.45,0,0,0,18,3H6a1.49,1.49,0,0,0-1.16.55L3.46,5.23A1.92,1.92,0,0,0,3,6.5V19a2,2,0,0,0,2,2H19a2,2,0,0,0,2-2V6.5A1.92,1.92,0,0,0,20.54,5.23Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/patreon.svg b/launcher/resources/flat_white/scalable/patreon.svg
new file mode 100644
index 00000000..b745765b
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/patreon.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12,3h0a9,9,0,0,0-9,9v9H5.09V12a6.91,6.91,0,1,1,7.23,6.9,5.9,5.9,0,0,1-2.59-.47v-3A4.13,4.13,0,1,0,7.85,12v9H12A9,9,0,1,0,12,3Zm0,15.91h0Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/proxy.svg b/launcher/resources/flat_white/scalable/proxy.svg
new file mode 100644
index 00000000..a86703f4
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/proxy.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M22 4v-.5C22 2.12 20.88 1 19.5 1S17 2.12 17 3.5V4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h5c.55 0 1-.45 1-1V5c0-.55-.45-1-1-1zm-.8 0h-3.4v-.5c0-.94.76-1.7 1.7-1.7s1.7.76 1.7 1.7V4zm-2.28 8c.04.33.08.66.08 1 0 2.08-.8 3.97-2.1 5.39-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H7v-2h2c.55 0 1-.45 1-1V8h2c1.1 0 2-.9 2-2V3.46c-.95-.3-1.95-.46-3-.46C5.48 3 1 7.48 1 13s4.48 10 10 10 10-4.48 10-10c0-.34-.02-.67-.05-1h-2.03zM10 20.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L8 16v1c0 1.1.9 2 2 2v1.93z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/quickmods.svg b/launcher/resources/flat_white/scalable/quickmods.svg
new file mode 100644
index 00000000..9e0045b2
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/quickmods.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M8.75,5.5v7.15H10.7V18.5l4.55-7.8h-2.6l2.6-5.2ZM20,4H4V20H20Zm0,18H4a2,2,0,0,1-2-2V4A2,2,0,0,1,4,2H20a2,2,0,0,1,2,2V20A2,2,0,0,1,20,22Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/reddit-alien.svg b/launcher/resources/flat_white/scalable/reddit-alien.svg
new file mode 100644
index 00000000..be22148c
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/reddit-alien.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M20,11.86a1.76,1.76,0,0,0-1.75-1.75,1.73,1.73,0,0,0-1.22.51,9,9,0,0,0-4.67-1.38l1-3.16L16,6.71s0,0,0,0a1.46,1.46,0,1,0,.1-.53l-2.89-.68a.25.25,0,0,0-.29.17L11.83,9.23a9.16,9.16,0,0,0-4.88,1.36,1.75,1.75,0,1,0-2.07,2.79,3,3,0,0,0-.06.58C4.82,16.58,8,18.7,12,18.7s7.14-2.13,7.14-4.74a2.94,2.94,0,0,0-.05-.55A1.74,1.74,0,0,0,20,11.86ZM8.51,13.08a1.06,1.06,0,1,1,1.06,1.06A1.06,1.06,0,0,1,8.51,13.08Zm6.06,3.14A3.48,3.48,0,0,1,12,17h0a3.48,3.48,0,0,1-2.56-.79.25.25,0,0,1,.35-.35,3,3,0,0,0,2.2.65h0a3,3,0,0,0,2.2-.65.25.25,0,1,1,.35.35Zm-.13-2.08a1.06,1.06,0,1,1,1.06-1.06A1.06,1.06,0,0,1,14.44,14.14Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/refresh.svg b/launcher/resources/flat_white/scalable/refresh.svg
new file mode 100644
index 00000000..08c63bdf
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/refresh.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M17.65,6.35C16.2,4.9 14.21,4 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20C15.73,20 18.84,17.45 19.73,14H17.65C16.83,16.33 14.61,18 12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6C13.66,6 15.14,6.69 16.22,7.78L13,11H20V4L17.65,6.35Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/rename.svg b/launcher/resources/flat_white/scalable/rename.svg
new file mode 100644
index 00000000..f2067c16
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/rename.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" version="1.1" id="svg4" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><defs id="defs6"/>
+
+<path id="rect345" style="stroke-width:1.40001;stroke-linecap:square" d="m 16.944458,1.2305698 -2.249239,2.2492384 5.824973,5.8249729 2.249239,-2.2492385 a 0.74206194,0.74206194 90.000002 0 0 0,-1.0494341 L 17.993892,1.2305699 a 0.74206211,0.74206211 2.5523302e-6 0 0 -1.049434,-1e-7 z M 13.645389,4.5296385 3.5726925,14.602335 9.3976653,20.427306 19.470362,10.35461 Z M 2.5228612,15.652165 1.0244287,22.411695 a 0.47276304,0.47276304 44.999993 0 0 0.5638754,0.563875 l 6.75953,-1.498434 z"/></svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/resourcepacks.svg b/launcher/resources/flat_white/scalable/resourcepacks.svg
new file mode 100644
index 00000000..9dd73c3a
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/resourcepacks.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M19.51 3.08L3.08 19.51c.09.34.27.65.51.9.25.24.56.42.9.51L20.93 4.49c-.19-.69-.73-1.23-1.42-1.41zM11.88 3L3 11.88v2.83L14.71 3h-2.83zM5 3c-1.1 0-2 .9-2 2v2l4-4H5zm14 18c.55 0 1.05-.22 1.41-.59.37-.36.59-.86.59-1.41v-2l-4 4h2zm-9.71 0h2.83L21 12.12V9.29L9.29 21z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/screenshot-placeholder.svg b/launcher/resources/flat_white/scalable/screenshot-placeholder.svg
new file mode 100644
index 00000000..41eb6fcf
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/screenshot-placeholder.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M21 15h2v2h-2v-2zm0-4h2v2h-2v-2zm2 8h-2v2c1 0 2-1 2-2zM13 3h2v2h-2V3zm8 4h2v2h-2V7zm0-4v2h2c0-1-1-2-2-2zM1 7h2v2H1V7zm16-4h2v2h-2V3zm0 16h2v2h-2v-2zM3 3C2 3 1 4 1 5h2V3zm6 0h2v2H9V3zM5 3h2v2H5V3zm-4 8v8c0 1.1.9 2 2 2h12V11H1zm2 8l2.5-3.21 1.79 2.15 2.5-3.22L13 19H3z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/screenshots.svg b/launcher/resources/flat_white/scalable/screenshots.svg
new file mode 100644
index 00000000..68cf8969
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/screenshots.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M21 3H3C2 3 1 4 1 5v14c0 1.1.9 2 2 2h18c1 0 2-1 2-2V5c0-1-1-2-2-2zM5 17l3.5-4.5 2.5 3.01L14.5 11l4.5 6H5z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/settings.svg b/launcher/resources/flat_white/scalable/settings.svg
new file mode 100644
index 00000000..7dac7b14
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/settings.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/shaderpacks.svg b/launcher/resources/flat_white/scalable/shaderpacks.svg
new file mode 100644
index 00000000..ccae221c
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/shaderpacks.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ fill="#D8DEE9"
+ height="24"
+ viewBox="0 0 24 24"
+ width="24"
+ version="1.1"
+ id="svg4"
+ sodipodi:docname="shaderpacks.svg"
+ inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ id="namedview6"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ showgrid="false"
+ inkscape:zoom="9.7227182"
+ inkscape:cx="16.302025"
+ inkscape:cy="3.1884088"
+ inkscape:window-width="3840"
+ inkscape:window-height="2129"
+ inkscape:window-x="1200"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg4">
+ <inkscape:grid
+ type="xygrid"
+ id="grid974" />
+ </sodipodi:namedview>
+ <path
+ id="path2"
+ d="M 5 3 C 3.9 3 3 3.9 3 5 L 3 7 L 5 5 L 7 3 L 5 3 z M 11.880859 3 L 9.8808594 5 L 12.710938 5 L 14.710938 3 L 11.880859 3 z M 19.509766 3.0800781 L 17.589844 5 L 19 5 L 19 6.4179688 L 20.929688 4.4902344 C 20.739687 3.8002344 20.199766 3.2600781 19.509766 3.0800781 z M 21 9.2890625 L 19 11.289062 L 19 14.119141 L 21 12.119141 L 21 9.2890625 z M 5 9.8808594 L 3 11.880859 L 3 14.710938 L 5 12.710938 L 5 9.8808594 z M 21 17 L 19 19 L 17 21 L 19 21 C 19.55 21 20.050156 20.780156 20.410156 20.410156 C 20.780156 20.050156 21 19.55 21 19 L 21 17 z M 5 17.589844 L 3.0800781 19.509766 C 3.1700781 19.849766 3.3498438 20.160156 3.5898438 20.410156 C 3.8398438 20.650156 4.1502344 20.829922 4.4902344 20.919922 L 6.4121094 19 L 5 19 L 5 17.589844 z M 11.289062 19 L 9.2890625 21 L 12.119141 21 L 14.119141 19 L 11.289062 19 z " />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#D8DEE9;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ d="m 7,9 v 8 h 8 V 9 Z"
+ id="path6727"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#D8DEE9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ d="M 7,9 9,7 h 8 l -2,2 z"
+ id="path7008" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#D8DEE9;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ d="m 17,7 v 8 l -2,2 V 9 Z"
+ id="path7010"
+ sodipodi:nodetypes="ccccc" />
+</svg>
diff --git a/launcher/resources/flat_white/scalable/star.svg b/launcher/resources/flat_white/scalable/star.svg
new file mode 100644
index 00000000..116f952e
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/star.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/status-bad.svg b/launcher/resources/flat_white/scalable/status-bad.svg
new file mode 100644
index 00000000..5a121c09
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/status-bad.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12,2A10,10,0,1,0,22,12,10,10,0,0,0,12,2Zm4.24,7.17L13.41,12l2.83,2.83-1.41,1.41L12,13.41,9.17,16.24,7.76,14.83,10.59,12,7.76,9.17,9.17,7.76,12,10.59l2.83-2.83Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/status-good.svg b/launcher/resources/flat_white/scalable/status-good.svg
new file mode 100644
index 00000000..ccb732ab
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/status-good.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/status-running.svg b/launcher/resources/flat_white/scalable/status-running.svg
new file mode 100644
index 00000000..aa2d5fbf
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/status-running.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/status-yellow.svg b/launcher/resources/flat_white/scalable/status-yellow.svg
new file mode 100644
index 00000000..772699d3
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/status-yellow.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/tag.svg b/launcher/resources/flat_white/scalable/tag.svg
new file mode 100644
index 00000000..f91fb0b4
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/tag.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" version="1.1" id="svg4" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
+ <path style="fill:#D8DEE9;fill-opacity:1;stroke:none;stroke-width:0.999999" d="M 12,2.4960934 2.5451968,2.5451969 2.4960933,12 12.791992,21.503907 21.503907,12.791992 Z M 8.0400388,5.6640622 c 1.3115393,0 2.3759772,1.0644375 2.3759772,2.3759766 0,1.3115391 -1.0644379,2.3759772 -2.3759772,2.3759772 -1.3115392,0 -2.3759767,-1.0644381 -2.3759767,-2.3759772 0,-1.3115391 1.0644375,-2.3759766 2.3759767,-2.3759766" class="ColorScheme-Text" id="path4838"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/viewfolder.svg b/launcher/resources/flat_white/scalable/viewfolder.svg
new file mode 100644
index 00000000..145f8624
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/viewfolder.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/flat_white/scalable/worlds.svg b/launcher/resources/flat_white/scalable/worlds.svg
new file mode 100644
index 00000000..cea30cf8
--- /dev/null
+++ b/launcher/resources/flat_white/scalable/worlds.svg
@@ -0,0 +1,3 @@
+<svg fill="#D8DEE9" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
+ <path d="M18.2,13a3.18,3.18,0,0,1-.84,2.16.8.8,0,0,0-.76-.56h-.4V13.4a.4.4,0,0,0-.4-.4H13.4v-.8h.8a.4.4,0,0,0,.4-.4V11h.8a.8.8,0,0,0,.8-.8V10A3.19,3.19,0,0,1,18.2,13Zm-4.4,1.6v-.4l-1.92-1.92a3.18,3.18,0,0,0,2.72,3.89V15.4A.8.8,0,0,1,13.8,14.6ZM22,8V18a2,2,0,0,1-2,2H4a2,2,0,0,1-2-2V6A2,2,0,0,1,4,4h6l2,2h8A2,2,0,0,1,22,8Zm-3,5a4,4,0,1,0-4,4A4,4,0,0,0,19,13Z"/>
+</svg> \ No newline at end of file
diff --git a/launcher/resources/iOS/iOS.qrc b/launcher/resources/iOS/iOS.qrc
index 1d752042..aa08d811 100644
--- a/launcher/resources/iOS/iOS.qrc
+++ b/launcher/resources/iOS/iOS.qrc
@@ -38,5 +38,6 @@
<file>scalable/tag.svg</file>
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
+ <file>scalable/launch.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/iOS/scalable/launch.svg b/launcher/resources/iOS/scalable/launch.svg
new file mode 100644
index 00000000..c16d5c37
--- /dev/null
+++ b/launcher/resources/iOS/scalable/launch.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ id="Calque_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 32 32"
+ enable-background="new 0 0 32 32"
+ xml:space="preserve"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs45" />
+
+<path
+ id="path11889"
+ style="color:#000000;fill:#3366cc;fill-opacity:1;stroke-width:0.999996;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
+ d="M 9.3515625 1.5410156 C 9.2434917 1.5379599 9.1351284 1.5389257 9.0273438 1.5429688 C 6.4405102 1.6400023 3.9843749 3.7548369 3.984375 6.5449219 L 3.984375 24.701172 C 3.9843742 28.421285 8.3520988 30.94086 11.572266 29.078125 L 27.259766 20.003906 C 30.478726 18.141866 30.478727 13.104225 27.259766 11.242188 L 11.572266 2.1679688 C 10.867854 1.7604958 10.108058 1.5624055 9.3515625 1.5410156 z M 9.0429688 3.5957031 C 9.5568946 3.5959458 10.065401 3.7305695 10.515625 3.9902344 A 1.50015 1.50015 0 0 0 10.517578 3.9902344 L 26.205078 13.064453 C 28.113387 14.165162 28.113387 17.080931 26.205078 18.181641 L 10.517578 27.255859 A 1.50015 1.50015 0 0 0 10.515625 27.255859 C 8.6111878 28.356592 6.0892988 26.90083 6.0898438 24.701172 L 6.0898438 6.5449219 C 6.090352 5.1229119 7.128734 3.8866658 8.5292969 3.640625 C 8.6999053 3.6105103 8.87166 3.5956222 9.0429688 3.5957031 z " /></svg>
diff --git a/launcher/resources/iOS/scalable/launcher.svg b/launcher/resources/iOS/scalable/launcher.svg
index 69dd84b1..aeee8433 100644
--- a/launcher/resources/iOS/scalable/launcher.svg
+++ b/launcher/resources/iOS/scalable/launcher.svg
@@ -37,17 +37,21 @@
</cc:Agent>
</dc:contributor>
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
- <dc:rights>
- <cc:Agent>
- <dc:title>CC BY-SA 4.0</dc:title>
- </cc:Agent>
- </dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>Prism Launcher</dc:title>
</cc:Agent>
</dc:publisher>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
</cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
+ </cc:License>
</rdf:RDF>
</metadata>
</svg>
diff --git a/launcher/resources/multimc/scalable/launcher.svg b/launcher/resources/multimc/scalable/launcher.svg
index 69dd84b1..aeee8433 100644
--- a/launcher/resources/multimc/scalable/launcher.svg
+++ b/launcher/resources/multimc/scalable/launcher.svg
@@ -37,17 +37,21 @@
</cc:Agent>
</dc:contributor>
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
- <dc:rights>
- <cc:Agent>
- <dc:title>CC BY-SA 4.0</dc:title>
- </cc:Agent>
- </dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>Prism Launcher</dc:title>
</cc:Agent>
</dc:publisher>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
</cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
+ </cc:License>
</rdf:RDF>
</metadata>
</svg>
diff --git a/launcher/resources/pe_blue/pe_blue.qrc b/launcher/resources/pe_blue/pe_blue.qrc
index 3d385713..3121ffe6 100644
--- a/launcher/resources/pe_blue/pe_blue.qrc
+++ b/launcher/resources/pe_blue/pe_blue.qrc
@@ -38,5 +38,6 @@
<file>scalable/tag.svg</file>
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
+ <file>scalable/launch.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/pe_blue/scalable/launch.svg b/launcher/resources/pe_blue/scalable/launch.svg
new file mode 100644
index 00000000..b3bd124f
--- /dev/null
+++ b/launcher/resources/pe_blue/scalable/launch.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ id="Calque_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 32 32"
+ enable-background="new 0 0 32 32"
+ xml:space="preserve"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs45" />
+
+<path
+ style="color:#000000;fill:#3366cc;fill-opacity:1;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill;stroke:#3366cc;stroke-opacity:1"
+ d="M 25.454197,16.881861 9.7664963,25.956555 A 1.4501236,1.4501236 0 0 1 7.5902672,24.701314 V 6.544692 A 1.4501239,1.4501239 0 0 1 9.7664965,5.2894509 L 25.454196,14.364142 a 1.4543042,1.4543042 0 0 1 1e-6,2.517719 z"
+ id="path11891" /><path
+ style="color:#000000;fill:#daeeff;fill-opacity:1;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
+ d="M 25.454197,16.881861 9.7664962,25.956555 A 1.4501236,1.4501236 0 0 1 7.5902671,24.701314 V 6.544692 A 1.4501239,1.4501239 0 0 1 9.7664964,5.289451 l 15.6876996,9.074691 a 1.4543042,1.4543042 0 0 1 1e-6,2.517719 z"
+ id="path11897" /></svg>
diff --git a/launcher/resources/pe_blue/scalable/launcher.svg b/launcher/resources/pe_blue/scalable/launcher.svg
index 69dd84b1..aeee8433 100644
--- a/launcher/resources/pe_blue/scalable/launcher.svg
+++ b/launcher/resources/pe_blue/scalable/launcher.svg
@@ -37,17 +37,21 @@
</cc:Agent>
</dc:contributor>
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
- <dc:rights>
- <cc:Agent>
- <dc:title>CC BY-SA 4.0</dc:title>
- </cc:Agent>
- </dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>Prism Launcher</dc:title>
</cc:Agent>
</dc:publisher>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
</cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
+ </cc:License>
</rdf:RDF>
</metadata>
</svg>
diff --git a/launcher/resources/pe_colored/pe_colored.qrc b/launcher/resources/pe_colored/pe_colored.qrc
index fa6cd9cd..ce5ad8e2 100644
--- a/launcher/resources/pe_colored/pe_colored.qrc
+++ b/launcher/resources/pe_colored/pe_colored.qrc
@@ -38,5 +38,6 @@
<file>scalable/tag.svg</file>
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
+ <file>scalable/launch.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/pe_colored/scalable/launch.svg b/launcher/resources/pe_colored/scalable/launch.svg
new file mode 100644
index 00000000..76713387
--- /dev/null
+++ b/launcher/resources/pe_colored/scalable/launch.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ id="Calque_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 32 32"
+ enable-background="new 0 0 32 32"
+ xml:space="preserve"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs45" />
+
+<path
+ style="color:#000000;fill:#8c6239;fill-opacity:1;stroke-width:0.999996;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
+ d="M 9.0277705,1.5430089 C 6.4409319,1.6400426 3.9852419,3.7549517 3.985242,6.5450423 V 24.700962 c -8e-7,3.720121 4.3665092,6.239738 7.586682,4.376999 l 15.687475,-9.074438 c 3.218968,-1.862044 3.218969,-6.899 0,-8.761041 L 11.571924,2.1680429 C 10.766881,1.7023586 9.8900501,1.5106643 9.0277705,1.5430089 Z m 2.1691325,8.7399131 9.231137,5.34008 -9.231137,5.34008 z"
+ id="path11889" /><path
+ id="path11895"
+ style="color:#000000;fill:#39b54a;fill-opacity:1;stroke-width:0.999996;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
+ d="M 9.3517318,1.541286 C 9.2436609,1.5382303 9.1355552,1.5390036 9.0277705,1.5430466 6.4409344,1.6400802 3.9852418,3.7549923 3.9852419,6.54508 V 9.6526439 H 24.511009 L 11.571923,2.1680807 C 10.867511,1.7606073 10.108228,1.5626759 9.3517318,1.541286 Z" /><path
+ style="color:#000000;fill:#f2f2f2;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:markers stroke fill"
+ d="M 25.454197,16.881861 9.7664962,25.956555 A 1.4501236,1.4501236 0 0 1 7.5902671,24.701314 V 6.544692 A 1.4501239,1.4501239 0 0 1 9.7664964,5.289451 l 15.6876996,9.074691 a 1.4543042,1.4543042 0 0 1 1e-6,2.517719 z"
+ id="path11897" /></svg>
diff --git a/launcher/resources/pe_colored/scalable/launcher.svg b/launcher/resources/pe_colored/scalable/launcher.svg
index 69dd84b1..aeee8433 100644
--- a/launcher/resources/pe_colored/scalable/launcher.svg
+++ b/launcher/resources/pe_colored/scalable/launcher.svg
@@ -37,17 +37,21 @@
</cc:Agent>
</dc:contributor>
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
- <dc:rights>
- <cc:Agent>
- <dc:title>CC BY-SA 4.0</dc:title>
- </cc:Agent>
- </dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>Prism Launcher</dc:title>
</cc:Agent>
</dc:publisher>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
</cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
+ </cc:License>
</rdf:RDF>
</metadata>
</svg>
diff --git a/launcher/resources/pe_dark/pe_dark.qrc b/launcher/resources/pe_dark/pe_dark.qrc
index 6b9c7cb6..156d8f8b 100644
--- a/launcher/resources/pe_dark/pe_dark.qrc
+++ b/launcher/resources/pe_dark/pe_dark.qrc
@@ -38,5 +38,6 @@
<file>scalable/tag.svg</file>
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
+ <file>scalable/launch.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/pe_dark/scalable/launch.svg b/launcher/resources/pe_dark/scalable/launch.svg
new file mode 100644
index 00000000..3746e2dd
--- /dev/null
+++ b/launcher/resources/pe_dark/scalable/launch.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ id="Calque_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 32 32"
+ enable-background="new 0 0 32 32"
+ xml:space="preserve"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs45" />
+
+<path
+ id="path11889"
+ style="color:#000000;fill:#000000;fill-opacity:1;stroke-width:0.999996;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
+ d="M 9.3515625,1.5410156 C 9.2434916,1.5379599 9.1351286,1.5389257 9.0273438,1.5429688 6.4405077,1.6400024 3.9843749,3.7548341 3.984375,6.5449219 V 24.701172 c -8e-7,3.720117 4.367721,6.23969 7.587891,4.376953 l 15.6875,-9.074219 c 3.218964,-1.862042 3.218965,-6.899679 0,-8.761718 L 11.572266,2.1679688 C 10.867854,1.7604954 10.108059,1.5624055 9.3515625,1.5410156 Z m -0.5625,3.5761719 a 1.4501239,1.4501239 0 0 1 0.9765625,0.171875 l 15.689453,9.0742185 a 1.4543042,1.4543042 0 0 1 0,2.519531 L 9.765625,25.957031 A 1.4501236,1.4501236 0 0 1 7.5898438,24.701172 V 6.5449219 A 1.4501239,1.4501239 0 0 1 8.7890625,5.1171875 Z" /></svg>
diff --git a/launcher/resources/pe_dark/scalable/launcher.svg b/launcher/resources/pe_dark/scalable/launcher.svg
index 69dd84b1..aeee8433 100644
--- a/launcher/resources/pe_dark/scalable/launcher.svg
+++ b/launcher/resources/pe_dark/scalable/launcher.svg
@@ -37,17 +37,21 @@
</cc:Agent>
</dc:contributor>
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
- <dc:rights>
- <cc:Agent>
- <dc:title>CC BY-SA 4.0</dc:title>
- </cc:Agent>
- </dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>Prism Launcher</dc:title>
</cc:Agent>
</dc:publisher>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
</cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
+ </cc:License>
</rdf:RDF>
</metadata>
</svg>
diff --git a/launcher/resources/pe_light/pe_light.qrc b/launcher/resources/pe_light/pe_light.qrc
index 963bfcde..d8e4a1bd 100644
--- a/launcher/resources/pe_light/pe_light.qrc
+++ b/launcher/resources/pe_light/pe_light.qrc
@@ -38,5 +38,6 @@
<file>scalable/tag.svg</file>
<file>scalable/export.svg</file>
<file>scalable/rename.svg</file>
+ <file>scalable/launch.svg</file>
</qresource>
</RCC>
diff --git a/launcher/resources/pe_light/scalable/launch.svg b/launcher/resources/pe_light/scalable/launch.svg
new file mode 100644
index 00000000..6c27b7e0
--- /dev/null
+++ b/launcher/resources/pe_light/scalable/launch.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ id="Calque_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 32 32"
+ enable-background="new 0 0 32 32"
+ xml:space="preserve"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs45" />
+
+<path
+ id="path11889"
+ style="color:#000000;fill:#f2f2f2;fill-opacity:1;stroke-width:0.999996;stroke-linecap:round;stroke-linejoin:round;paint-order:markers stroke fill"
+ d="M 9.3515625,1.5410156 C 9.2434916,1.5379599 9.1351286,1.5389257 9.0273438,1.5429688 6.4405077,1.6400024 3.9843749,3.7548341 3.984375,6.5449219 V 24.701172 c -8e-7,3.720117 4.367721,6.23969 7.587891,4.376953 l 15.6875,-9.074219 c 3.218964,-1.862042 3.218965,-6.899679 0,-8.761718 L 11.572266,2.1679688 C 10.867854,1.7604954 10.108059,1.5624055 9.3515625,1.5410156 Z m -0.5625,3.5761719 a 1.4501239,1.4501239 0 0 1 0.9765625,0.171875 l 15.689453,9.0742185 a 1.4543042,1.4543042 0 0 1 0,2.519531 L 9.765625,25.957031 A 1.4501236,1.4501236 0 0 1 7.5898438,24.701172 V 6.5449219 A 1.4501239,1.4501239 0 0 1 8.7890625,5.1171875 Z" /></svg>
diff --git a/launcher/resources/pe_light/scalable/launcher.svg b/launcher/resources/pe_light/scalable/launcher.svg
index 69dd84b1..aeee8433 100644
--- a/launcher/resources/pe_light/scalable/launcher.svg
+++ b/launcher/resources/pe_light/scalable/launcher.svg
@@ -37,17 +37,21 @@
</cc:Agent>
</dc:contributor>
<dc:source>https://github.com/PrismLauncher/PrismLauncher</dc:source>
- <dc:rights>
- <cc:Agent>
- <dc:title>CC BY-SA 4.0</dc:title>
- </cc:Agent>
- </dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>Prism Launcher</dc:title>
</cc:Agent>
</dc:publisher>
+ <cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/"/>
</cc:Work>
+ <cc:License rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Notice"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#Attribution"/>
+ <cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
+ <cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike"/>
+ </cc:License>
</rdf:RDF>
</metadata>
</svg>
diff --git a/launcher/tasks/Task.cpp b/launcher/tasks/Task.cpp
index b4babdd4..9ea1bb26 100644
--- a/launcher/tasks/Task.cpp
+++ b/launcher/tasks/Task.cpp
@@ -153,7 +153,7 @@ QString Task::describe()
auto name = objectName();
if(name.isEmpty())
{
- out << QString("0x%1").arg((quintptr)this, 0, 16);
+ out << QString("0x%1").arg(reinterpret_cast<quintptr>(this), 0, 16);
}
else
{
diff --git a/launcher/translations/TranslationsModel.cpp b/launcher/translations/TranslationsModel.cpp
index 2f57de3a..20aa6d04 100644
--- a/launcher/translations/TranslationsModel.cpp
+++ b/launcher/translations/TranslationsModel.cpp
@@ -83,6 +83,12 @@ struct Language
else if(key == "es_UY") {
result = u8"español de Latinoamérica";
}
+ else if(key == "en@pirate") {
+ result = u8"Tongue of the High Seas";
+ }
+ else if(key == "en@uwu") {
+ result = u8"Cute Engwish";
+ }
else {
result = locale.nativeLanguageName();
}
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 97152a48..28eaa741 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -335,11 +335,10 @@ public:
all_actions.append(&actionSettings);
actionUndoTrashInstance = TranslatedAction(MainWindow);
- connect(actionUndoTrashInstance, SIGNAL(triggered(bool)), MainWindow, SLOT(undoTrashInstance()));
actionUndoTrashInstance->setObjectName(QStringLiteral("actionUndoTrashInstance"));
actionUndoTrashInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Undo Last Instance Deletion"));
actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething());
- actionUndoTrashInstance->setShortcut(QKeySequence("Ctrl+Z"));
+ actionUndoTrashInstance->setShortcut(QKeySequence::Undo);
all_actions.append(&actionUndoTrashInstance);
actionClearMetadata = TranslatedAction(MainWindow);
@@ -527,7 +526,7 @@ public:
menuBar->addMenu(foldersMenu);
- profileMenu = menuBar->addMenu(tr("&Profiles"));
+ profileMenu = menuBar->addMenu(tr("&Accounts"));
profileMenu->setSeparatorsCollapsible(false);
profileMenu->addAction(actionManageAccounts);
@@ -656,6 +655,7 @@ public:
actionLaunchInstance->setObjectName(QStringLiteral("actionLaunchInstance"));
actionLaunchInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Launch"));
actionLaunchInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance."));
+ actionLaunchInstance->setIcon(APPLICATION->getThemedIcon("launch"));
all_actions.append(&actionLaunchInstance);
actionLaunchInstanceOffline = TranslatedAction(MainWindow);
@@ -741,7 +741,9 @@ public:
// See https://github.com/PolyMC/PolyMC/issues/493
connect(instanceToolBar, &QToolBar::orientationChanged, [=](Qt::Orientation){ instanceToolBar->setOrientation(Qt::Vertical); });
instanceToolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
- instanceToolBar->setToolButtonStyle(Qt::ToolButtonTextOnly);
+ instanceToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ instanceToolBar->setIconSize(QSize(16, 16));
+
instanceToolBar->setFloatable(false);
instanceToolBar->setWindowTitle(QT_TRANSLATE_NOOP("MainWindow", "Instance Toolbar"));
@@ -761,8 +763,18 @@ public:
instanceToolBar->addAction(actionViewSelectedInstFolder);
instanceToolBar->addAction(actionExportInstance);
- instanceToolBar->addAction(actionDeleteInstance);
instanceToolBar->addAction(actionCopyInstance);
+ instanceToolBar->addAction(actionDeleteInstance);
+
+ QLayout * lay = instanceToolBar->layout();
+ for(int i = 0; i < lay->count(); i++)
+ {
+ QLayoutItem * item = lay->itemAt(i);
+ if (item->widget()->metaObject()->className() == QString("QToolButton"))
+ {
+ item->setAlignment(Qt::AlignLeft);
+ }
+ }
all_toolbars.append(&instanceToolBar);
MainWindow->addToolBar(Qt::RightToolBarArea, instanceToolBar);
@@ -1010,6 +1022,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow
}
}
+ connect(ui->actionUndoTrashInstance.operator->(), &QAction::triggered, this, &MainWindow::undoTrashInstance);
+
setSelectedInstanceById(APPLICATION->settings()->get("SelectedInstance").toString());
// removing this looks stupid
@@ -1039,7 +1053,7 @@ void MainWindow::retranslateUi()
accountMenuButton->setText(profileLabel);
}
else {
- accountMenuButton->setText(tr("Profiles"));
+ accountMenuButton->setText(tr("Accounts"));
}
if (m_selectedInstance) {
@@ -1121,11 +1135,6 @@ void MainWindow::showInstanceContextMenu(const QPoint &pos)
connect(actionDeleteGroup, SIGNAL(triggered(bool)), SLOT(deleteGroup()));
actions.append(actionDeleteGroup);
}
-
- QAction *actionUndoTrashInstance = new QAction("Undo last trash instance", this);
- connect(actionUndoTrashInstance, SIGNAL(triggered(bool)), SLOT(undoTrashInstance()));
- actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething());
- actions.append(actionUndoTrashInstance);
}
QMenu myMenu;
myMenu.addActions(actions);
@@ -1382,7 +1391,7 @@ void MainWindow::defaultAccountChanged()
// Set the icon to the "no account" icon.
accountMenuButton->setIcon(APPLICATION->getThemedIcon("noaccount"));
- accountMenuButton->setText(tr("Profiles"));
+ accountMenuButton->setText(tr("Accounts"));
}
bool MainWindow::eventFilter(QObject *obj, QEvent *ev)
@@ -1551,15 +1560,13 @@ void MainWindow::setCatBackground(bool enabled)
QDateTime now = QDateTime::currentDateTime();
QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0));
QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
- QString cat;
+ QString cat = APPLICATION->settings()->get("BackgroundCat").toString();
+
if(non_stupid_abs(now.daysTo(xmas)) <= 4) {
- cat = "catmas";
+ cat += "-xmas";
}
else if (non_stupid_abs(now.daysTo(birthday)) <= 12) {
- cat = "cattiversary";
- }
- else {
- cat = "kitteh";
+ cat += "-bday";
}
view->setStyleSheet(QString(R"(
InstanceView
@@ -1567,10 +1574,11 @@ InstanceView
background-image: url(:/backgrounds/%1);
background-attachment: fixed;
background-clip: padding;
- background-position: top right;
+ background-position: bottom left;
background-repeat: none;
background-color:palette(base);
-})").arg(cat));
+})")
+ .arg(cat));
}
else
{
@@ -1821,6 +1829,7 @@ void MainWindow::deleteGroup()
void MainWindow::undoTrashInstance()
{
APPLICATION->instances()->undoTrashInstance();
+ ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething());
}
void MainWindow::on_actionViewInstanceFolder_triggered()
@@ -1927,6 +1936,7 @@ void MainWindow::on_actionDeleteInstance_triggered()
auto id = m_selectedInstance->id();
if (APPLICATION->instances()->trashInstance(id)) {
+ ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething());
return;
}
diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp
index cecda1df..a36e4a3d 100644
--- a/launcher/ui/dialogs/AboutDialog.cpp
+++ b/launcher/ui/dialogs/AboutDialog.cpp
@@ -73,17 +73,12 @@ QString getCreditsHtml()
stream << "<h3>" << QObject::tr("%1 Developers", "About Credits").arg(BuildConfig.LAUNCHER_DISPLAYNAME) << "</h3>\n";
stream << QString("<p>Sefa Eyeoglu (Scrumplex) %1</p>\n") .arg(getWebsite("https://scrumplex.net"));
stream << QString("<p>dada513 %1</p>\n") .arg(getGitHub("dada513"));
- stream << QString("<p>txtsd %1</p>\n") .arg(getGitHub("txtsd"));
+ stream << QString("<p>txtsd %1</p>\n") .arg(getWebsite("https://ihavea.quest"));
stream << QString("<p>timoreo %1</p>\n") .arg(getGitHub("timoreo22"));
stream << QString("<p>Ezekiel Smith (ZekeSmith) %1</p>\n") .arg(getGitHub("ZekeSmith"));
stream << QString("<p>cozyGalvinism %1</p>\n") .arg(getGitHub("cozyGalvinism"));
- stream << "<br />\n";
-
- //: %1 is the name of the launcher, determined at build time, e.g. "Prism Launcher Contributors"
- stream << "<h3>" << QObject::tr("%1 Contributors", "About Credits").arg(BuildConfig.LAUNCHER_DISPLAYNAME) << "</h3>\n";
stream << QString("<p>DioEgizio %1</p>\n") .arg(getGitHub("DioEgizio"));
stream << QString("<p>flowln %1</p>\n") .arg(getGitHub("flowln"));
- stream << QString("<p>swirl %1</p>\n") .arg(getWebsite("https://swurl.xyz/"));
stream << "<br />\n";
// TODO: possibly retrieve from git history at build time?
@@ -97,7 +92,7 @@ QString getCreditsHtml()
stream << "<br />\n";
stream << "<h3>" << QObject::tr("With thanks to", "About Credits") << "</h3>\n";
- stream << QString("<p>Boba %1</p>\n") .arg(getWebsite("https://cmdplusv.neocities.org/"));
+ stream << QString("<p>Boba %1</p>\n") .arg(getWebsite("https://bobaonline.neocities.org/"));
stream << QString("<p>Davi Rafael %1</p>\n") .arg(getWebsite("https://auti.one/"));
stream << QString("<p>Fulmine %1</p>\n") .arg(getWebsite("https://www.fulmine.xyz/"));
stream << QString("<p>ely %1</p>\n") .arg(getGitHub("elyrodso"));
diff --git a/launcher/ui/dialogs/AboutDialog.ui b/launcher/ui/dialogs/AboutDialog.ui
index e0429321..4a9eef08 100644
--- a/launcher/ui/dialogs/AboutDialog.ui
+++ b/launcher/ui/dialogs/AboutDialog.ui
@@ -87,14 +87,11 @@
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="versionLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByMouse</set>
</property>
@@ -167,7 +164,7 @@
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="platformLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -183,7 +180,7 @@
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="buildDateLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -199,7 +196,7 @@
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="commitLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@@ -215,7 +212,7 @@
</property>
</widget>
</item>
- <item>
+ <item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="channelLabel">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp
index 4171586e..cedd4a96 100644
--- a/launcher/ui/dialogs/ModUpdateDialog.cpp
+++ b/launcher/ui/dialogs/ModUpdateDialog.cpp
@@ -366,33 +366,28 @@ void ModUpdateDialog::appendMod(CheckUpdateTask::UpdatableMod const& info)
auto changelog = new QTreeWidgetItem(changelog_item);
auto changelog_area = new QTextBrowser();
+ QString text = info.changelog;
switch (info.provider) {
case ModPlatform::Provider::MODRINTH: {
HoeDown h;
// HoeDown bug?: \n aren't converted to <br>
- auto text = h.process(info.changelog.toUtf8());
+ text = h.process(info.changelog.toUtf8());
// Don't convert if there's an HTML tag right after (Qt rendering weirdness)
text.remove(QRegularExpression("(\n+)(?=<)"));
text.replace('\n', "<br>");
- changelog_area->setHtml(text);
break;
}
- case ModPlatform::Provider::FLAME: {
- changelog_area->setHtml(info.changelog);
+ default:
break;
- }
}
+ changelog_area->setHtml(text);
changelog_area->setOpenExternalLinks(true);
- changelog_area->setLineWrapMode(QTextBrowser::LineWrapMode::NoWrap);
+ changelog_area->setLineWrapMode(QTextBrowser::LineWrapMode::WidgetWidth);
changelog_area->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded);
- // HACK: Is there a better way of achieving this?
- auto font_height = QFontMetrics(changelog_area->font()).height();
- changelog_area->setMaximumHeight((changelog_area->toPlainText().count(QRegularExpression("\n|<br>")) + 2) * font_height);
-
ui->modTreeWidget->setItemWidget(changelog, 0, changelog_area);
ui->modTreeWidget->addTopLevelItem(item_top);
diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp
index 68dd4d17..05269f62 100644
--- a/launcher/ui/dialogs/ProgressDialog.cpp
+++ b/launcher/ui/dialogs/ProgressDialog.cpp
@@ -136,11 +136,13 @@ void ProgressDialog::onTaskStarted() {}
void ProgressDialog::onTaskFailed(QString failure)
{
reject();
+ hide();
}
void ProgressDialog::onTaskSucceeded()
{
accept();
+ hide();
}
void ProgressDialog::changeStatus(const QString& status)
diff --git a/launcher/ui/dialogs/VersionSelectDialog.cpp b/launcher/ui/dialogs/VersionSelectDialog.cpp
index 70ef72d6..d7880334 100644
--- a/launcher/ui/dialogs/VersionSelectDialog.cpp
+++ b/launcher/ui/dialogs/VersionSelectDialog.cpp
@@ -120,7 +120,7 @@ void VersionSelectDialog::selectRecommended()
m_versionWidget->selectRecommended();
}
-BaseVersionPtr VersionSelectDialog::selectedVersion() const
+BaseVersion::Ptr VersionSelectDialog::selectedVersion() const
{
return m_versionWidget->selectedVersion();
}
diff --git a/launcher/ui/dialogs/VersionSelectDialog.h b/launcher/ui/dialogs/VersionSelectDialog.h
index ed30d3f3..18a50cdb 100644
--- a/launcher/ui/dialogs/VersionSelectDialog.h
+++ b/launcher/ui/dialogs/VersionSelectDialog.h
@@ -44,7 +44,7 @@ public:
int exec() override;
- BaseVersionPtr selectedVersion() const;
+ BaseVersion::Ptr selectedVersion() const;
void setCurrentVersion(const QString & version);
void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter);
diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui
index 1ae788c7..d56a9ef6 100644
--- a/launcher/ui/pages/global/APIPage.ui
+++ b/launcher/ui/pages/global/APIPage.ui
@@ -179,7 +179,7 @@
<item>
<widget class="QLabel" name="label_4">
<property name="text">
- <string>Enter a custom client ID for Microsoft Authentication here. </string>
+ <string>Enter a custom client ID for Microsoft Authentication here.</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp
index b8431e8c..822c69b0 100644
--- a/launcher/ui/pages/global/LauncherPage.cpp
+++ b/launcher/ui/pages/global/LauncherPage.cpp
@@ -49,6 +49,7 @@
#include <FileSystem.h>
#include "Application.h"
#include "BuildConfig.h"
+#include "DesktopServices.h"
#include "ui/themes/ITheme.h"
#include <QApplication>
@@ -143,7 +144,7 @@ void LauncherPage::on_instDirBrowseBtn_clicked()
ui->instDirTextBox->setText(cooked_dir);
}
}
- else if(APPLICATION->isFlatpak() && raw_dir.startsWith("/run/user"))
+ else if(DesktopServices::isFlatpak() && raw_dir.startsWith("/run/user"))
{
QMessageBox warning;
warning.setText(tr("You're trying to specify an instance folder "
@@ -310,9 +311,12 @@ void LauncherPage::applySettings()
s->set("IconTheme", "flat");
break;
case 7:
- s->set("IconTheme", "multimc");
+ s->set("IconTheme", "flat_white");
break;
case 8:
+ s->set("IconTheme", "multimc");
+ break;
+ case 9:
s->set("IconTheme", "custom");
break;
}
@@ -330,6 +334,18 @@ void LauncherPage::applySettings()
APPLICATION->setApplicationTheme(newAppTheme, false);
}
+ switch (ui->themeBackgroundCat->currentIndex()) {
+ case 0: // original cat
+ s->set("BackgroundCat", "kitteh");
+ break;
+ case 1: // rory the cat
+ s->set("BackgroundCat", "rory");
+ break;
+ case 2: // rory the cat flat edition
+ s->set("BackgroundCat", "rory-flat");
+ break;
+ }
+
s->set("MenuBarInsteadOfToolBar", ui->preferMenuBarCheckBox->isChecked());
// Console settings
@@ -408,14 +424,27 @@ void LauncherPage::loadSettings()
{
ui->themeComboBox->setCurrentIndex(6);
}
- else if (theme == "multimc")
+ else if (theme == "flat_white")
{
ui->themeComboBox->setCurrentIndex(7);
}
- else if (theme == "custom")
+ else if (theme == "multimc")
{
ui->themeComboBox->setCurrentIndex(8);
}
+ else if (theme == "custom")
+ {
+ ui->themeComboBox->setCurrentIndex(9);
+ }
+
+ auto cat = s->get("BackgroundCat").toString();
+ if (cat == "kitteh") {
+ ui->themeBackgroundCat->setCurrentIndex(0);
+ } else if (cat == "rory") {
+ ui->themeBackgroundCat->setCurrentIndex(1);
+ } else if (cat == "rory-flat") {
+ ui->themeBackgroundCat->setCurrentIndex(2);
+ }
{
auto currentTheme = s->get("ApplicationTheme").toString();
diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui
index 0d14f147..6de644ee 100644
--- a/launcher/ui/pages/global/LauncherPage.ui
+++ b/launcher/ui/pages/global/LauncherPage.ui
@@ -302,6 +302,11 @@
</item>
<item>
<property name="text">
+ <string>Flat (White)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
<string>Legacy</string>
</property>
</item>
@@ -335,6 +340,44 @@
</property>
</widget>
</item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>C&amp;at</string>
+ </property>
+ <property name="buddy">
+ <cstring>themeBackgroundCat</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QComboBox" name="themeBackgroundCat">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <item>
+ <property name="text">
+ <string>Background Cat (from MultiMC)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Rory ID 11 (drawn by Ashtaka)</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Rory ID 11 (flat edition, drawn by Ashtaka)</string>
+ </property>
+ </item>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp
index 49766fa6..ed58eb32 100644
--- a/launcher/ui/pages/modplatform/ModModel.cpp
+++ b/launcher/ui/pages/modplatform/ModModel.cpp
@@ -267,18 +267,25 @@ void ListModel::searchRequestFailed(QString reason)
.arg(m_parent->displayName())
.arg(tr("API version too old!\nPlease update %1!").arg(BuildConfig.LAUNCHER_DISPLAYNAME)));
}
+
jobPtr.reset();
+ searchState = Finished;
+}
- if (searchState == ResetRequested) {
- beginResetModel();
- modpacks.clear();
- endResetModel();
+void ListModel::searchRequestAborted()
+{
+ if (searchState != ResetRequested)
+ qCritical() << "Search task in ModModel aborted by an unknown reason!";
- nextSearchOffset = 0;
- performPaginatedSearch();
- } else {
- searchState = Finished;
- }
+ // Retry fetching
+ jobPtr.reset();
+
+ beginResetModel();
+ modpacks.clear();
+ endResetModel();
+
+ nextSearchOffset = 0;
+ performPaginatedSearch();
}
void ListModel::infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index)
diff --git a/launcher/ui/pages/modplatform/ModModel.h b/launcher/ui/pages/modplatform/ModModel.h
index a58c7c55..d2636d87 100644
--- a/launcher/ui/pages/modplatform/ModModel.h
+++ b/launcher/ui/pages/modplatform/ModModel.h
@@ -51,6 +51,7 @@ class ListModel : public QAbstractListModel {
public slots:
void searchRequestFinished(QJsonDocument& doc);
void searchRequestFailed(QString reason);
+ void searchRequestAborted();
void infoRequestFinished(QJsonDocument& doc, ModPlatform::IndexedPack& pack, const QModelIndex& index);
diff --git a/launcher/ui/pages/modplatform/VanillaPage.cpp b/launcher/ui/pages/modplatform/VanillaPage.cpp
index 99190f31..29fecb85 100644
--- a/launcher/ui/pages/modplatform/VanillaPage.cpp
+++ b/launcher/ui/pages/modplatform/VanillaPage.cpp
@@ -187,12 +187,12 @@ void VanillaPage::retranslate()
ui->retranslateUi(this);
}
-BaseVersionPtr VanillaPage::selectedVersion() const
+BaseVersion::Ptr VanillaPage::selectedVersion() const
{
return m_selectedVersion;
}
-BaseVersionPtr VanillaPage::selectedLoaderVersion() const
+BaseVersion::Ptr VanillaPage::selectedLoaderVersion() const
{
return m_selectedLoaderVersion;
}
@@ -227,14 +227,14 @@ void VanillaPage::suggestCurrent()
dialog->setSuggestedIcon("default");
}
-void VanillaPage::setSelectedVersion(BaseVersionPtr version)
+void VanillaPage::setSelectedVersion(BaseVersion::Ptr version)
{
m_selectedVersion = version;
suggestCurrent();
loaderFilterChanged();
}
-void VanillaPage::setSelectedLoaderVersion(BaseVersionPtr version)
+void VanillaPage::setSelectedLoaderVersion(BaseVersion::Ptr version)
{
m_selectedLoaderVersion = version;
suggestCurrent();
diff --git a/launcher/ui/pages/modplatform/VanillaPage.h b/launcher/ui/pages/modplatform/VanillaPage.h
index 7193597d..39aba760 100644
--- a/launcher/ui/pages/modplatform/VanillaPage.h
+++ b/launcher/ui/pages/modplatform/VanillaPage.h
@@ -76,13 +76,13 @@ public:
void openedImpl() override;
- BaseVersionPtr selectedVersion() const;
- BaseVersionPtr selectedLoaderVersion() const;
+ BaseVersion::Ptr selectedVersion() const;
+ BaseVersion::Ptr selectedLoaderVersion() const;
QString selectedLoader() const;
public slots:
- void setSelectedVersion(BaseVersionPtr version);
- void setSelectedLoaderVersion(BaseVersionPtr version);
+ void setSelectedVersion(BaseVersion::Ptr version);
+ void setSelectedLoaderVersion(BaseVersion::Ptr version);
private slots:
void filterChanged();
@@ -98,7 +98,7 @@ private:
NewInstanceDialog *dialog = nullptr;
Ui::VanillaPage *ui = nullptr;
bool m_versionSetByUser = false;
- BaseVersionPtr m_selectedVersion;
- BaseVersionPtr m_selectedLoaderVersion;
+ BaseVersion::Ptr m_selectedVersion;
+ BaseVersion::Ptr m_selectedLoaderVersion;
QString m_selectedLoader;
};
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
index 004fdc57..9138dcbb 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
@@ -331,7 +331,7 @@ AtlOptionalModDialog::AtlOptionalModDialog(QWidget* parent, ATLauncher::PackVers
connect(ui->clearAllButton, &QPushButton::clicked,
listModel, &AtlOptionalModListModel::clearAll);
connect(ui->installButton, &QPushButton::clicked,
- this, &QDialog::close);
+ this, &QDialog::accept);
}
AtlOptionalModDialog::~AtlOptionalModDialog() {
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp
index 03196685..f5f50cae 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.cpp
@@ -43,14 +43,17 @@ AtlUserInteractionSupportImpl::AtlUserInteractionSupportImpl(QWidget *parent) :
{
}
-QVector<QString> AtlUserInteractionSupportImpl::chooseOptionalMods(ATLauncher::PackVersion version, QVector<ATLauncher::VersionMod> mods)
+std::optional<QVector<QString>> AtlUserInteractionSupportImpl::chooseOptionalMods(ATLauncher::PackVersion version, QVector<ATLauncher::VersionMod> mods)
{
AtlOptionalModDialog optionalModDialog(m_parent, version, mods);
- optionalModDialog.exec();
+ auto result = optionalModDialog.exec();
+ if (result == QDialog::Rejected) {
+ return {};
+ }
return optionalModDialog.getResult();
}
-QString AtlUserInteractionSupportImpl::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion)
+QString AtlUserInteractionSupportImpl::chooseVersion(Meta::VersionList::Ptr vlist, QString minecraftVersion)
{
VersionSelectDialog vselect(vlist.get(), "Choose Version", m_parent, false);
if (minecraftVersion != nullptr) {
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h
index aa22fc73..37010b3f 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlUserInteractionSupportImpl.h
@@ -46,8 +46,8 @@ public:
AtlUserInteractionSupportImpl(QWidget* parent);
private:
- QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) override;
- QVector<QString> chooseOptionalMods(ATLauncher::PackVersion version, QVector<ATLauncher::VersionMod> mods) override;
+ QString chooseVersion(Meta::VersionList::Ptr vlist, QString minecraftVersion) override;
+ std::optional<QVector<QString>> chooseOptionalMods(ATLauncher::PackVersion version, QVector<ATLauncher::VersionMod> mods) override;
void displayMessage(QString message) override;
private:
diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp
index b9804681..9f8605eb 100644
--- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp
@@ -1,6 +1,7 @@
#include "FlameModel.h"
#include <Json.h>
#include "Application.h"
+#include "ui/widgets/ProjectItem.h"
#include <MMCStrings.h>
#include <Version.h>
@@ -31,29 +32,38 @@ QVariant ListModel::data(const QModelIndex& index, int role) const
}
IndexedPack pack = modpacks.at(pos);
- if (role == Qt::DisplayRole) {
- return pack.name;
- } else if (role == Qt::ToolTipRole) {
- if (pack.description.length() > 100) {
- // some magic to prevent to long tooltips and replace html linebreaks
- QString edit = pack.description.left(97);
- edit = edit.left(edit.lastIndexOf("<br>")).left(edit.lastIndexOf(" ")).append("...");
- return edit;
+ switch (role) {
+ case Qt::ToolTipRole: {
+ if (pack.description.length() > 100) {
+ // some magic to prevent to long tooltips and replace html linebreaks
+ QString edit = pack.description.left(97);
+ edit = edit.left(edit.lastIndexOf("<br>")).left(edit.lastIndexOf(" ")).append("...");
+ return edit;
+ }
+ return pack.description;
+ } case Qt::DecorationRole: {
+ if (m_logoMap.contains(pack.logoName)) {
+ return (m_logoMap.value(pack.logoName));
+ }
+ QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder");
+ ((ListModel*)this)->requestLogo(pack.logoName, pack.logoUrl);
+ return icon;
+ } case Qt::UserRole: {
+ QVariant v;
+ v.setValue(pack);
+ return v;
}
- return pack.description;
- } else if (role == Qt::DecorationRole) {
- if (m_logoMap.contains(pack.logoName)) {
- return (m_logoMap.value(pack.logoName));
- }
- QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder");
- ((ListModel*)this)->requestLogo(pack.logoName, pack.logoUrl);
- return icon;
- } else if (role == Qt::UserRole) {
- QVariant v;
- v.setValue(pack);
- return v;
+ case Qt::SizeHintRole:
+ return QSize(0, 58);
+ case UserDataTypes::TITLE:
+ return pack.name;
+ case UserDataTypes::DESCRIPTION:
+ return pack.description;
+ case UserDataTypes::SELECTED:
+ return false;
+ default:
+ break;
}
-
return QVariant();
}
diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp
index 7d2ba2e2..a65b6585 100644
--- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp
@@ -43,6 +43,10 @@
#include "InstanceImportTask.h"
#include "Json.h"
#include "ui/dialogs/NewInstanceDialog.h"
+#include "ui/widgets/ProjectItem.h"
+#include "modplatform/flame/FlameAPI.h"
+
+static FlameAPI api;
FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(parent), ui(new Ui::FlamePage), dialog(dialog)
{
@@ -66,6 +70,9 @@ FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget* parent) : QWidget(paren
connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch()));
connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlamePage::onSelectionChanged);
connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FlamePage::onVersionSelectionChanged);
+
+ ui->packView->setItemDelegate(new ProjectItemDelegate(this));
+ ui->packDescription->setMetaEntry("FlamePacks");
}
FlamePage::~FlamePage()
@@ -250,7 +257,10 @@ void FlamePage::updateUi()
text += "- " + tr("Source code: <a href=%1>%1</a>").arg(current.extra.sourceUrl) + "<br>";
}
+
text += "<hr>";
+ text += api.getModDescription(current.addonId).toUtf8();
ui->packDescription->setHtml(text + current.description);
+ ui->packDescription->flush();
}
diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.ui b/launcher/ui/pages/modplatform/flame/FlamePage.ui
index 1a3d0225..71d19513 100644
--- a/launcher/ui/pages/modplatform/flame/FlamePage.ui
+++ b/launcher/ui/pages/modplatform/flame/FlamePage.ui
@@ -66,7 +66,7 @@
</widget>
</item>
<item>
- <widget class="QTextBrowser" name="packDescription">
+ <widget class="ProjectDescriptionPage" name="packDescription">
<property name="openExternalLinks">
<bool>true</bool>
</property>
@@ -99,6 +99,13 @@
</item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>ProjectDescriptionPage</class>
+ <extends>QTextBrowser</extends>
+ <header>ui/widgets/ProjectDescriptionPage.h</header>
+ </customwidget>
+ </customwidgets>
<tabstops>
<tabstop>packView</tabstop>
<tabstop>packDescription</tabstop>
diff --git a/launcher/ui/themes/DarkTheme.cpp b/launcher/ui/themes/DarkTheme.cpp
index 07a2efd2..48231b53 100644
--- a/launcher/ui/themes/DarkTheme.cpp
+++ b/launcher/ui/themes/DarkTheme.cpp
@@ -31,7 +31,7 @@ QPalette DarkTheme::colorScheme()
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::BrightText, Qt::red);
darkPalette.setColor(QPalette::Link, QColor(47,163,198));
- darkPalette.setColor(QPalette::Highlight, QColor(145,205,92));
+ darkPalette.setColor(QPalette::Highlight, QColor(150,219,89));
darkPalette.setColor(QPalette::HighlightedText, Qt::black);
darkPalette.setColor(QPalette::PlaceholderText, Qt::darkGray);
return fadeInactive(darkPalette, fadeAmount(), fadeColor());
diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp
index 314a126e..c7c4dbbd 100644
--- a/launcher/ui/widgets/JavaSettingsWidget.cpp
+++ b/launcher/ui/widgets/JavaSettingsWidget.cpp
@@ -245,7 +245,7 @@ void JavaSettingsWidget::memoryValueChanged(int)
}
}
-void JavaSettingsWidget::javaVersionSelected(BaseVersionPtr version)
+void JavaSettingsWidget::javaVersionSelected(BaseVersion::Ptr version)
{
auto java = std::dynamic_pointer_cast<JavaInstall>(version);
if(!java)
diff --git a/launcher/ui/widgets/JavaSettingsWidget.h b/launcher/ui/widgets/JavaSettingsWidget.h
index 0d280daf..5344e2cd 100644
--- a/launcher/ui/widgets/JavaSettingsWidget.h
+++ b/launcher/ui/widgets/JavaSettingsWidget.h
@@ -60,7 +60,7 @@ public:
protected slots:
void memoryValueChanged(int);
void javaPathEdited(const QString &path);
- void javaVersionSelected(BaseVersionPtr version);
+ void javaVersionSelected(BaseVersion::Ptr version);
void on_javaBrowseBtn_clicked();
void on_javaStatusBtn_clicked();
void checkFinished(JavaCheckResult result);
diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h
index 958a1e2b..706ffd21 100644
--- a/launcher/ui/widgets/ModFilterWidget.h
+++ b/launcher/ui/widgets/ModFilterWidget.h
@@ -49,7 +49,7 @@ public:
auto getFilter() -> std::shared_ptr<Filter>;
auto changed() const -> bool { return m_last_version_id != m_version_id; }
- Meta::VersionListPtr versionList() { return m_version_list; }
+ Meta::VersionList::Ptr versionList() { return m_version_list; }
private:
ModFilterWidget(Version def, QWidget* parent = nullptr);
@@ -73,7 +73,7 @@ private:
/* Version stuff */
QButtonGroup m_mcVersion_buttons;
- Meta::VersionListPtr m_version_list;
+ Meta::VersionList::Ptr m_version_list;
/* Used to tell if the filter was changed since the last getFilter() call */
VersionButtonID m_last_version_id = VersionButtonID::Strict;
diff --git a/launcher/ui/widgets/VersionSelectWidget.cpp b/launcher/ui/widgets/VersionSelectWidget.cpp
index cc4fc6a2..404860d9 100644
--- a/launcher/ui/widgets/VersionSelectWidget.cpp
+++ b/launcher/ui/widgets/VersionSelectWidget.cpp
@@ -142,7 +142,7 @@ void VersionSelectWidget::changeProgress(qint64 current, qint64 total)
void VersionSelectWidget::currentRowChanged(const QModelIndex& current, const QModelIndex&)
{
auto variant = m_proxyModel->data(current, BaseVersionList::VersionPointerRole);
- emit selectedVersionChanged(variant.value<BaseVersionPtr>());
+ emit selectedVersionChanged(variant.value<BaseVersion::Ptr>());
}
void VersionSelectWidget::preselect()
@@ -186,11 +186,11 @@ bool VersionSelectWidget::hasVersions() const
return m_proxyModel->rowCount(QModelIndex()) != 0;
}
-BaseVersionPtr VersionSelectWidget::selectedVersion() const
+BaseVersion::Ptr VersionSelectWidget::selectedVersion() const
{
auto currentIndex = listView->selectionModel()->currentIndex();
auto variant = m_proxyModel->data(currentIndex, BaseVersionList::VersionPointerRole);
- return variant.value<BaseVersionPtr>();
+ return variant.value<BaseVersion::Ptr>();
}
void VersionSelectWidget::setExactFilter(BaseVersionList::ModelRoles role, QString filter)
diff --git a/launcher/ui/widgets/VersionSelectWidget.h b/launcher/ui/widgets/VersionSelectWidget.h
index f56daa8a..e75efc6f 100644
--- a/launcher/ui/widgets/VersionSelectWidget.h
+++ b/launcher/ui/widgets/VersionSelectWidget.h
@@ -40,7 +40,7 @@ public:
void loadList();
bool hasVersions() const;
- BaseVersionPtr selectedVersion() const;
+ BaseVersion::Ptr selectedVersion() const;
void selectRecommended();
void selectCurrent();
@@ -54,7 +54,7 @@ public:
void setResizeOn(int column);
signals:
- void selectedVersionChanged(BaseVersionPtr version);
+ void selectedVersionChanged(BaseVersion::Ptr version);
protected:
virtual void closeEvent ( QCloseEvent* );