aboutsummaryrefslogtreecommitdiff
path: root/launcher/ui
diff options
context:
space:
mode:
Diffstat (limited to 'launcher/ui')
-rw-r--r--launcher/ui/MainWindow.cpp4
-rw-r--r--launcher/ui/dialogs/NewInstanceDialog.cpp28
-rw-r--r--launcher/ui/dialogs/NewInstanceDialog.h6
-rw-r--r--launcher/ui/dialogs/ProgressDialog.cpp6
-rw-r--r--launcher/ui/pages/global/LauncherPage.ui2
-rw-r--r--launcher/ui/pages/instance/TexturePackPage.h12
-rw-r--r--launcher/ui/pages/modplatform/ModModel.cpp8
-rw-r--r--launcher/ui/pages/modplatform/ModPage.cpp1
-rw-r--r--launcher/ui/pages/modplatform/VanillaPage.cpp10
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp2
-rw-r--r--launcher/ui/pages/modplatform/ftb/FtbPage.cpp2
-rw-r--r--launcher/ui/pages/modplatform/legacy_ftb/Page.cpp10
-rw-r--r--launcher/ui/pages/modplatform/legacy_ftb/Page.h1
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp58
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp6
-rw-r--r--launcher/ui/pages/modplatform/technic/TechnicPage.cpp4
-rw-r--r--launcher/ui/themes/BrightTheme.cpp28
-rw-r--r--launcher/ui/themes/DarkTheme.cpp16
-rw-r--r--launcher/ui/widgets/InfoFrame.cpp98
-rw-r--r--launcher/ui/widgets/InfoFrame.h4
-rw-r--r--launcher/ui/widgets/ProjectItem.cpp37
21 files changed, 225 insertions, 118 deletions
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 58b1ae80..5729b44d 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -1656,6 +1656,10 @@ void MainWindow::runModalTask(Task *task)
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show();
}
});
+ connect(task, &Task::aborted, [this]
+ {
+ CustomMessageBox::selectable(this, tr("Task aborted"), tr("The task has been aborted by the user."), QMessageBox::Information)->show();
+ });
ProgressDialog loadDialog(this);
loadDialog.setSkipButton(true, tr("Abort"));
loadDialog.execWithTask(task);
diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp
index 675f8b15..d203795a 100644
--- a/launcher/ui/dialogs/NewInstanceDialog.cpp
+++ b/launcher/ui/dialogs/NewInstanceDialog.cpp
@@ -51,6 +51,7 @@
#include <QFileDialog>
#include <QValidator>
#include <QDialogButtonBox>
+#include <utility>
#include "ui/widgets/PageContainer.h"
#include "ui/pages/modplatform/VanillaPage.h"
@@ -180,10 +181,27 @@ NewInstanceDialog::~NewInstanceDialog()
void NewInstanceDialog::setSuggestedPack(const QString& name, InstanceTask* task)
{
creationTask.reset(task);
+
ui->instNameTextBox->setPlaceholderText(name);
+ importVersion.clear();
- if(!task)
- {
+ if (!task) {
+ ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default"));
+ importIcon = false;
+ }
+
+ auto allowOK = task && !instName().isEmpty();
+ m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK);
+}
+
+void NewInstanceDialog::setSuggestedPack(const QString& name, QString version, InstanceTask* task)
+{
+ creationTask.reset(task);
+
+ ui->instNameTextBox->setPlaceholderText(name);
+ importVersion = std::move(version);
+
+ if (!task) {
ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default"));
importIcon = false;
}
@@ -214,7 +232,11 @@ InstanceTask * NewInstanceDialog::extractTask()
{
InstanceTask * extracted = creationTask.get();
creationTask.release();
- extracted->setName(instName());
+
+ InstanceName inst_name(ui->instNameTextBox->placeholderText().trimmed(), importVersion);
+ inst_name.setName(ui->instNameTextBox->text().trimmed());
+ extracted->setName(inst_name);
+
extracted->setGroup(instGroup());
extracted->setIcon(iconKey());
return extracted;
diff --git a/launcher/ui/dialogs/NewInstanceDialog.h b/launcher/ui/dialogs/NewInstanceDialog.h
index a3c8cd1c..961f512e 100644
--- a/launcher/ui/dialogs/NewInstanceDialog.h
+++ b/launcher/ui/dialogs/NewInstanceDialog.h
@@ -37,7 +37,6 @@
#include <QDialog>
-#include "BaseVersion.h"
#include "ui/pages/BasePageProvider.h"
#include "InstanceTask.h"
@@ -61,7 +60,8 @@ public:
void updateDialogState();
- void setSuggestedPack(const QString & name = QString(), InstanceTask * task = nullptr);
+ void setSuggestedPack(const QString& name = QString(), InstanceTask * task = nullptr);
+ void setSuggestedPack(const QString& name, QString version, InstanceTask * task = nullptr);
void setSuggestedIconFromFile(const QString &path, const QString &name);
void setSuggestedIcon(const QString &key);
@@ -95,5 +95,7 @@ private:
QString importIconPath;
QString importIconName;
+ QString importVersion;
+
void importIconNow();
};
diff --git a/launcher/ui/dialogs/ProgressDialog.cpp b/launcher/ui/dialogs/ProgressDialog.cpp
index 3c7f53d3..258a32e4 100644
--- a/launcher/ui/dialogs/ProgressDialog.cpp
+++ b/launcher/ui/dialogs/ProgressDialog.cpp
@@ -43,8 +43,7 @@ void ProgressDialog::setSkipButton(bool present, QString label)
void ProgressDialog::on_skipButton_clicked(bool checked)
{
Q_UNUSED(checked);
- if (task->abort())
- QDialog::reject();
+ task->abort();
}
ProgressDialog::~ProgressDialog()
@@ -81,7 +80,8 @@ int ProgressDialog::execWithTask(Task* task)
connect(task, &Task::stepStatus, this, &ProgressDialog::changeStatus);
connect(task, &Task::progress, this, &ProgressDialog::changeProgress);
- connect(task, &Task::aborted, [this] { onTaskFailed(tr("Aborted by user")); });
+ connect(task, &Task::aborted, [this] { QDialog::reject(); });
+ connect(task, &Task::abortStatusChanged, ui->skipButton, &QPushButton::setEnabled);
m_is_multi_step = task->isMultiStep();
if (!m_is_multi_step) {
diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui
index 645f7ef6..0d14f147 100644
--- a/launcher/ui/pages/global/LauncherPage.ui
+++ b/launcher/ui/pages/global/LauncherPage.ui
@@ -176,7 +176,7 @@
<item>
<widget class="QLabel" name="metadataWarningLabel">
<property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; color:#f5c211;&quot;&gt;Warning&lt;/span&gt;&lt;span style=&quot; color:#f5c211;&quot;&gt;: Disabling mod metadata may also disable some upcoming QoL features, such as mod updating!&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600; color:#f5c211;&quot;&gt;Warning&lt;/span&gt;&lt;span style=&quot; color:#f5c211;&quot;&gt;: Disabling mod metadata may also disable some QoL features, such as mod updating!&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
diff --git a/launcher/ui/pages/instance/TexturePackPage.h b/launcher/ui/pages/instance/TexturePackPage.h
index fa219eda..69b836ca 100644
--- a/launcher/ui/pages/instance/TexturePackPage.h
+++ b/launcher/ui/pages/instance/TexturePackPage.h
@@ -39,6 +39,7 @@
#include "ui_ExternalResourcesPage.h"
#include "minecraft/mod/TexturePackFolderModel.h"
+#include "minecraft/mod/TexturePack.h"
class TexturePackPage : public ExternalResourcesPage
{
@@ -60,4 +61,15 @@ public:
{
return m_instance->traits().contains("texturepacks");
}
+
+ public slots:
+ bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override
+ {
+ auto sourceCurrent = m_filterModel->mapToSource(current);
+ int row = sourceCurrent.row();
+ auto& rp = static_cast<TexturePack&>(m_model->at(row));
+ ui->frame->updateWithTexturePack(rp);
+
+ return true;
+ }
};
diff --git a/launcher/ui/pages/modplatform/ModModel.cpp b/launcher/ui/pages/modplatform/ModModel.cpp
index 029e2be0..8961fadd 100644
--- a/launcher/ui/pages/modplatform/ModModel.cpp
+++ b/launcher/ui/pages/modplatform/ModModel.cpp
@@ -62,11 +62,7 @@ auto ListModel::data(const QModelIndex& index, int role) const -> QVariant
}
case Qt::DecorationRole: {
if (m_logoMap.contains(pack.logoName)) {
- auto icon = m_logoMap.value(pack.logoName);
- // FIXME: This doesn't really belong here, but Qt doesn't offer a good way right now ;(
- auto icon_scaled = QIcon(icon.pixmap(48, 48).scaledToWidth(48));
-
- return icon_scaled;
+ return m_logoMap.value(pack.logoName);
}
QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder");
// un-const-ify this
@@ -175,7 +171,7 @@ void ListModel::getLogo(const QString& logo, const QString& logoUrl, LogoCallbac
void ListModel::requestLogo(QString logo, QString url)
{
- if (m_loadingLogos.contains(logo) || m_failedLogos.contains(logo)) {
+ if (m_loadingLogos.contains(logo) || m_failedLogos.contains(logo) || url.isEmpty()) {
return;
}
diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp
index 986caa77..4fce0242 100644
--- a/launcher/ui/pages/modplatform/ModPage.cpp
+++ b/launcher/ui/pages/modplatform/ModPage.cpp
@@ -60,6 +60,7 @@ ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance* instance, ModAPI* api)
connect(ui->searchButton, &QPushButton::clicked, this, &ModPage::triggerSearch);
connect(ui->modFilterButton, &QPushButton::clicked, this, &ModPage::filterMods);
+ connect(ui->packView, &QListView::doubleClicked, this, &ModPage::onModSelected);
m_search_timer.setTimerType(Qt::TimerType::CoarseTimer);
m_search_timer.setSingleShot(true);
diff --git a/launcher/ui/pages/modplatform/VanillaPage.cpp b/launcher/ui/pages/modplatform/VanillaPage.cpp
index a026947f..99190f31 100644
--- a/launcher/ui/pages/modplatform/VanillaPage.cpp
+++ b/launcher/ui/pages/modplatform/VanillaPage.cpp
@@ -39,12 +39,12 @@
#include <QTabBar>
#include "Application.h"
+#include "Filter.h"
+#include "Version.h"
#include "meta/Index.h"
#include "meta/VersionList.h"
+#include "minecraft/VanillaInstanceCreationTask.h"
#include "ui/dialogs/NewInstanceDialog.h"
-#include "Filter.h"
-#include "InstanceCreationTask.h"
-#include "Version.h"
VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent)
: QWidget(parent), dialog(dialog), ui(new Ui::VanillaPage)
@@ -217,11 +217,11 @@ void VanillaPage::suggestCurrent()
// There isn't a selected version if the version list is empty
if(ui->loaderVersionList->selectedVersion() == nullptr)
- dialog->setSuggestedPack(m_selectedVersion->descriptor(), new InstanceCreationTask(m_selectedVersion));
+ dialog->setSuggestedPack(m_selectedVersion->descriptor(), new VanillaCreationTask(m_selectedVersion));
else
{
dialog->setSuggestedPack(m_selectedVersion->descriptor(),
- new InstanceCreationTask(m_selectedVersion, m_selectedLoader,
+ new VanillaCreationTask(m_selectedVersion, m_selectedLoader,
m_selectedLoaderVersion));
}
dialog->setSuggestedIcon("default");
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp
index 7901b90b..87544445 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp
@@ -117,7 +117,7 @@ void AtlPage::suggestCurrent()
}
auto uiSupport = new AtlUserInteractionSupportImpl(this);
- dialog->setSuggestedPack(selected.name + " " + selectedVersion, new ATLauncher::PackInstallTask(uiSupport, selected.name, selectedVersion));
+ dialog->setSuggestedPack(selected.name, selectedVersion, new ATLauncher::PackInstallTask(uiSupport, selected.name, selectedVersion));
auto editedLogoName = selected.safeName;
auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/images/%1.png").arg(selected.safeName.toLower());
diff --git a/launcher/ui/pages/modplatform/ftb/FtbPage.cpp b/launcher/ui/pages/modplatform/ftb/FtbPage.cpp
index 504d7f7b..8975d74e 100644
--- a/launcher/ui/pages/modplatform/ftb/FtbPage.cpp
+++ b/launcher/ui/pages/modplatform/ftb/FtbPage.cpp
@@ -127,7 +127,7 @@ void FtbPage::suggestCurrent()
return;
}
- dialog->setSuggestedPack(selected.name + " " + selectedVersion, new ModpacksCH::PackInstallTask(selected, selectedVersion, this));
+ dialog->setSuggestedPack(selected.name, selectedVersion, new ModpacksCH::PackInstallTask(selected, selectedVersion, this));
for(auto art : selected.art) {
if(art.type == "square") {
QString editedLogoName;
diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp
index 6ffbd312..98ab8799 100644
--- a/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp
+++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.cpp
@@ -146,6 +146,7 @@ void Page::openedImpl()
{
connect(ftbFetchTask.get(), &PackFetchTask::finished, this, &Page::ftbPackDataDownloadSuccessfully);
connect(ftbFetchTask.get(), &PackFetchTask::failed, this, &Page::ftbPackDataDownloadFailed);
+ connect(ftbFetchTask.get(), &PackFetchTask::aborted, this, &Page::ftbPackDataDownloadAborted);
connect(ftbFetchTask.get(), &PackFetchTask::privateFileDownloadFinished, this, &Page::ftbPrivatePackDataDownloadSuccessfully);
connect(ftbFetchTask.get(), &PackFetchTask::privateFileDownloadFailed, this, &Page::ftbPrivatePackDataDownloadFailed);
@@ -176,7 +177,7 @@ void Page::suggestCurrent()
return;
}
- dialog->setSuggestedPack(selected.name + " " + selectedVersion, new PackInstallTask(APPLICATION->network(), selected, selectedVersion));
+ dialog->setSuggestedPack(selected.name, selectedVersion, new PackInstallTask(APPLICATION->network(), selected, selectedVersion));
QString editedLogoName;
if(selected.logo.toLower().startsWith("ftb"))
{
@@ -220,7 +221,12 @@ void Page::ftbPackDataDownloadSuccessfully(ModpackList publicPacks, ModpackList
void Page::ftbPackDataDownloadFailed(QString reason)
{
- //TODO: Display the error
+ CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
+}
+
+void Page::ftbPackDataDownloadAborted()
+{
+ CustomMessageBox::selectable(this, tr("Task aborted"), tr("The task has been aborted by the user."), QMessageBox::Information)->show();
}
void Page::ftbPrivatePackDataDownloadSuccessfully(Modpack pack)
diff --git a/launcher/ui/pages/modplatform/legacy_ftb/Page.h b/launcher/ui/pages/modplatform/legacy_ftb/Page.h
index 52db7d91..1de8b40a 100644
--- a/launcher/ui/pages/modplatform/legacy_ftb/Page.h
+++ b/launcher/ui/pages/modplatform/legacy_ftb/Page.h
@@ -95,6 +95,7 @@ private:
private slots:
void ftbPackDataDownloadSuccessfully(ModpackList publicPacks, ModpackList thirdPartyPacks);
void ftbPackDataDownloadFailed(QString reason);
+ void ftbPackDataDownloadAborted();
void ftbPrivatePackDataDownloadSuccessfully(Modpack pack);
void ftbPrivatePackDataDownloadFailed(QString reason, QString packCode);
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp
index 614be434..fd7a3537 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp
@@ -41,6 +41,7 @@
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
#include "ui/dialogs/ModDownloadDialog.h"
+#include "ui/widgets/ProjectItem.h"
#include <QMessageBox>
@@ -74,31 +75,40 @@ auto ModpackListModel::data(const QModelIndex& index, int role) const -> QVarian
}
Modrinth::Modpack 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;
}
- return pack.description;
- } else if (role == Qt::DecorationRole) {
- if (m_logoMap.contains(pack.iconName)) {
- auto icon = m_logoMap.value(pack.iconName);
- // FIXME: This doesn't really belong here, but Qt doesn't offer a good way right now ;(
- auto icon_scaled = QIcon(icon.pixmap(48, 48).scaledToWidth(48));
-
- return icon_scaled;
+ case Qt::DecorationRole: {
+ if (m_logoMap.contains(pack.iconName))
+ return m_logoMap.value(pack.iconName);
+
+ QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder");
+ ((ModpackListModel*)this)->requestLogo(pack.iconName, pack.iconUrl.toString());
+ return icon;
+ }
+ case Qt::UserRole: {
+ QVariant v;
+ v.setValue(pack);
+ return v;
}
- QIcon icon = APPLICATION->getThemedIcon("screenshot-placeholder");
- ((ModpackListModel*)this)->requestLogo(pack.iconName, pack.iconUrl.toString());
- return icon;
- } else if (role == Qt::UserRole) {
- QVariant v;
- v.setValue(pack);
- return v;
+ case Qt::SizeHintRole:
+ return QSize(0, 58);
+ // Custom data
+ case UserDataTypes::TITLE:
+ return pack.name;
+ case UserDataTypes::DESCRIPTION:
+ return pack.description;
+ case UserDataTypes::SELECTED:
+ return false;
+ default:
+ break;
}
return {};
@@ -217,7 +227,7 @@ void ModpackListModel::getLogo(const QString& logo, const QString& logoUrl, Logo
void ModpackListModel::requestLogo(QString logo, QString url)
{
- if (m_loadingLogos.contains(logo) || m_failedLogos.contains(logo)) {
+ if (m_loadingLogos.contains(logo) || m_failedLogos.contains(logo) || url.isEmpty()) {
return;
}
diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp
index df29c0c3..cea6cdee 100644
--- a/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp
+++ b/launcher/ui/pages/modplatform/modrinth/ModrinthPage.cpp
@@ -43,6 +43,8 @@
#include "InstanceImportTask.h"
#include "Json.h"
+#include "ui/widgets/ProjectItem.h"
+
#include <HoeDown.h>
#include <QComboBox>
@@ -70,6 +72,8 @@ ModrinthPage::ModrinthPage(NewInstanceDialog* dialog, QWidget* parent) : QWidget
connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch()));
connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthPage::onSelectionChanged);
connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &ModrinthPage::onVersionSelectionChanged);
+
+ ui->packView->setItemDelegate(new ProjectItemDelegate(this));
}
ModrinthPage::~ModrinthPage()
@@ -294,7 +298,7 @@ void ModrinthPage::suggestCurrent()
for (auto& ver : current.versions) {
if (ver.id == selectedVersion) {
- dialog->setSuggestedPack(current.name + " " + ver.version, new InstanceImportTask(ver.download_url, this));
+ dialog->setSuggestedPack(current.name, ver.version, new InstanceImportTask(ver.download_url, this));
auto iconName = current.iconName;
m_model->getLogo(iconName, current.iconUrl.toString(),
[this, iconName](QString logo) { dialog->setSuggestedIconFromFile(logo, iconName); });
diff --git a/launcher/ui/pages/modplatform/technic/TechnicPage.cpp b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp
index b8c1e00a..b15af244 100644
--- a/launcher/ui/pages/modplatform/technic/TechnicPage.cpp
+++ b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp
@@ -271,11 +271,11 @@ void TechnicPage::selectVersion() {
if (!current.isSolder)
{
- dialog->setSuggestedPack(current.name + " " + selectedVersion, new Technic::SingleZipPackInstallTask(current.url, current.minecraftVersion));
+ dialog->setSuggestedPack(current.name, selectedVersion, new Technic::SingleZipPackInstallTask(current.url, current.minecraftVersion));
}
else
{
- dialog->setSuggestedPack(current.name + " " + selectedVersion, new Technic::SolderPackInstallTask(APPLICATION->network(), current.url, current.slug, selectedVersion, current.minecraftVersion));
+ dialog->setSuggestedPack(current.name, selectedVersion, new Technic::SolderPackInstallTask(APPLICATION->network(), current.url, current.slug, selectedVersion, current.minecraftVersion));
}
}
diff --git a/launcher/ui/themes/BrightTheme.cpp b/launcher/ui/themes/BrightTheme.cpp
index b9188bdd..696ffdfb 100644
--- a/launcher/ui/themes/BrightTheme.cpp
+++ b/launcher/ui/themes/BrightTheme.cpp
@@ -1,5 +1,7 @@
#include "BrightTheme.h"
+#include <QObject>
+
QString BrightTheme::id()
{
return "bright";
@@ -18,19 +20,19 @@ bool BrightTheme::hasColorScheme()
QPalette BrightTheme::colorScheme()
{
QPalette brightPalette;
- brightPalette.setColor(QPalette::Window, QColor(239,240,241));
- brightPalette.setColor(QPalette::WindowText, QColor(49,54,59));
- brightPalette.setColor(QPalette::Base, QColor(252,252,252));
- brightPalette.setColor(QPalette::AlternateBase, QColor(239,240,241));
- brightPalette.setColor(QPalette::ToolTipBase, QColor(49,54,59));
- brightPalette.setColor(QPalette::ToolTipText, QColor(239,240,241));
- brightPalette.setColor(QPalette::Text, QColor(49,54,59));
- brightPalette.setColor(QPalette::Button, QColor(239,240,241));
- brightPalette.setColor(QPalette::ButtonText, QColor(49,54,59));
+ brightPalette.setColor(QPalette::Window, QColor(255,255,255));
+ brightPalette.setColor(QPalette::WindowText, QColor(17,17,17));
+ brightPalette.setColor(QPalette::Base, QColor(250,250,250));
+ brightPalette.setColor(QPalette::AlternateBase, QColor(240,240,240));
+ brightPalette.setColor(QPalette::ToolTipBase, QColor(17,17,17));
+ brightPalette.setColor(QPalette::ToolTipText, QColor(255,255,255));
+ brightPalette.setColor(QPalette::Text, Qt::black);
+ brightPalette.setColor(QPalette::Button, QColor(249,249,249));
+ brightPalette.setColor(QPalette::ButtonText, Qt::black);
brightPalette.setColor(QPalette::BrightText, Qt::red);
- brightPalette.setColor(QPalette::Link, QColor(41, 128, 185));
- brightPalette.setColor(QPalette::Highlight, QColor(61, 174, 233));
- brightPalette.setColor(QPalette::HighlightedText, QColor(239,240,241));
+ brightPalette.setColor(QPalette::Link, QColor(37,137,164));
+ brightPalette.setColor(QPalette::Highlight, QColor(137,207,84));
+ brightPalette.setColor(QPalette::HighlightedText, Qt::black);
return fadeInactive(brightPalette, fadeAmount(), fadeColor());
}
@@ -41,7 +43,7 @@ double BrightTheme::fadeAmount()
QColor BrightTheme::fadeColor()
{
- return QColor(239,240,241);
+ return QColor(255,255,255);
}
bool BrightTheme::hasStyleSheet()
diff --git a/launcher/ui/themes/DarkTheme.cpp b/launcher/ui/themes/DarkTheme.cpp
index 712a9d3e..07a2efd2 100644
--- a/launcher/ui/themes/DarkTheme.cpp
+++ b/launcher/ui/themes/DarkTheme.cpp
@@ -1,5 +1,7 @@
#include "DarkTheme.h"
+#include <QObject>
+
QString DarkTheme::id()
{
return "dark";
@@ -18,18 +20,18 @@ bool DarkTheme::hasColorScheme()
QPalette DarkTheme::colorScheme()
{
QPalette darkPalette;
- darkPalette.setColor(QPalette::Window, QColor(49,54,59));
+ darkPalette.setColor(QPalette::Window, QColor(49,49,49));
darkPalette.setColor(QPalette::WindowText, Qt::white);
- darkPalette.setColor(QPalette::Base, QColor(35,38,41));
- darkPalette.setColor(QPalette::AlternateBase, QColor(49,54,59));
+ darkPalette.setColor(QPalette::Base, QColor(34,34,34));
+ darkPalette.setColor(QPalette::AlternateBase, QColor(42,42,42));
darkPalette.setColor(QPalette::ToolTipBase, Qt::white);
darkPalette.setColor(QPalette::ToolTipText, Qt::white);
darkPalette.setColor(QPalette::Text, Qt::white);
- darkPalette.setColor(QPalette::Button, QColor(49,54,59));
+ darkPalette.setColor(QPalette::Button, QColor(48,48,48));
darkPalette.setColor(QPalette::ButtonText, Qt::white);
darkPalette.setColor(QPalette::BrightText, Qt::red);
- darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
- darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
+ darkPalette.setColor(QPalette::Link, QColor(47,163,198));
+ darkPalette.setColor(QPalette::Highlight, QColor(145,205,92));
darkPalette.setColor(QPalette::HighlightedText, Qt::black);
darkPalette.setColor(QPalette::PlaceholderText, Qt::darkGray);
return fadeInactive(darkPalette, fadeAmount(), fadeColor());
@@ -42,7 +44,7 @@ double DarkTheme::fadeAmount()
QColor DarkTheme::fadeColor()
{
- return QColor(49,54,59);
+ return QColor(49,49,49);
}
bool DarkTheme::hasStyleSheet()
diff --git a/launcher/ui/widgets/InfoFrame.cpp b/launcher/ui/widgets/InfoFrame.cpp
index 9e0553f8..fdc581b4 100644
--- a/launcher/ui/widgets/InfoFrame.cpp
+++ b/launcher/ui/widgets/InfoFrame.cpp
@@ -97,18 +97,7 @@ void InfoFrame::updateWithResource(const Resource& resource)
setImage();
}
-// https://www.sportskeeda.com/minecraft-wiki/color-codes
-static const QMap<QChar, QString> s_value_to_color = {
- {'0', "#000000"}, {'1', "#0000AA"}, {'2', "#00AA00"}, {'3', "#00AAAA"}, {'4', "#AA0000"},
- {'5', "#AA00AA"}, {'6', "#FFAA00"}, {'7', "#AAAAAA"}, {'8', "#555555"}, {'9', "#5555FF"},
- {'a', "#55FF55"}, {'b', "#55FFFF"}, {'c', "#FF5555"}, {'d', "#FF55FF"}, {'e', "#FFFF55"},
- {'f', "#FFFFFF"}
-};
-
-void InfoFrame::updateWithResourcePack(ResourcePack& resource_pack)
-{
- setName(resource_pack.name());
-
+QString InfoFrame::renderColorCodes(QString input) {
// We have to manually set the colors for use.
//
// A color is set using §x, with x = a hex number from 0 to f.
@@ -116,42 +105,73 @@ void InfoFrame::updateWithResourcePack(ResourcePack& resource_pack)
// We traverse the description and, when one of those is found, we create
// a span element with that color set.
//
- // TODO: Make the same logic for font formatting too.
// TODO: Wrap links inside <a> tags
- auto description = resource_pack.description();
-
- QString description_parsed("<html>");
- bool in_div = false;
-
- auto desc_it = description.constBegin();
- while (desc_it != description.constEnd()) {
- if (*desc_it == u'§') {
- if (in_div)
- description_parsed += "</span>";
-
- auto const& num = *(++desc_it);
- description_parsed += QString("<span style=\"color: %1;\">").arg(s_value_to_color.constFind(num).value());
-
- in_div = true;
-
- desc_it++;
+ // https://minecraft.fandom.com/wiki/Formatting_codes#Color_codes
+ const QMap<QChar, QString> color_codes_map = {
+ {'0', "#000000"}, {'1', "#0000AA"}, {'2', "#00AA00"}, {'3', "#00AAAA"}, {'4', "#AA0000"},
+ {'5', "#AA00AA"}, {'6', "#FFAA00"}, {'7', "#AAAAAA"}, {'8', "#555555"}, {'9', "#5555FF"},
+ {'a', "#55FF55"}, {'b', "#55FFFF"}, {'c', "#FF5555"}, {'d', "#FF55FF"}, {'e', "#FFFF55"},
+ {'f', "#FFFFFF"}
+ };
+ // https://minecraft.fandom.com/wiki/Formatting_codes#Formatting_codes
+ const QMap<QChar, QString> formatting_codes_map = {
+ {'l', "b"}, {'m', "s"}, {'n', "u"}, {'o', "i"}
+ };
+
+ QString html("<html>");
+ QList<QString> tags{};
+
+ auto it = input.constBegin();
+ while (it != input.constEnd()) {
+ // is current char § and is there a following char
+ if (*it == u'§' && (it + 1) != input.constEnd()) {
+ auto const& code = *(++it); // incrementing here!
+
+ auto const color_entry = color_codes_map.constFind(code);
+ auto const tag_entry = formatting_codes_map.constFind(code);
+
+ if (color_entry != color_codes_map.constEnd()) { // color code
+ html += QString("<span style=\"color: %1;\">").arg(color_entry.value());
+ tags << "span";
+ } else if (tag_entry != formatting_codes_map.constEnd()) { // formatting code
+ html += QString("<%1>").arg(tag_entry.value());
+ tags << tag_entry.value();
+ } else if (code == 'r') { // reset all formatting
+ while (!tags.isEmpty()) {
+ html += QString("</%1>").arg(tags.takeLast());
+ }
+ } else { // pass unknown codes through
+ html += QString("§%1").arg(code);
+ }
+ } else {
+ html += *it;
}
-
- description_parsed += *desc_it;
- desc_it++;
+ it++;
}
+ while (!tags.isEmpty()) {
+ html += QString("</%1>").arg(tags.takeLast());
+ }
+ html += "</html>";
- if (in_div)
- description_parsed += "</span>";
- description_parsed += "</html>";
-
- description_parsed.replace("\n", "<br>");
+ html.replace("\n", "<br>");
+ return html;
+}
- setDescription(description_parsed);
+void InfoFrame::updateWithResourcePack(ResourcePack& resource_pack)
+{
+ setName(renderColorCodes(resource_pack.name()));
+ setDescription(renderColorCodes(resource_pack.description()));
setImage(resource_pack.image({64, 64}));
}
+void InfoFrame::updateWithTexturePack(TexturePack& texture_pack)
+{
+ setName(renderColorCodes(texture_pack.name()));
+ setDescription(renderColorCodes(texture_pack.description()));
+ setImage(texture_pack.image({64, 64}));
+}
+
void InfoFrame::clear()
{
setName();
diff --git a/launcher/ui/widgets/InfoFrame.h b/launcher/ui/widgets/InfoFrame.h
index 70d15b1e..84523e28 100644
--- a/launcher/ui/widgets/InfoFrame.h
+++ b/launcher/ui/widgets/InfoFrame.h
@@ -19,6 +19,7 @@
#include "minecraft/mod/Mod.h"
#include "minecraft/mod/ResourcePack.h"
+#include "minecraft/mod/TexturePack.h"
namespace Ui
{
@@ -41,6 +42,9 @@ class InfoFrame : public QFrame {
void updateWithMod(Mod const& m);
void updateWithResource(Resource const& resource);
void updateWithResourcePack(ResourcePack& rp);
+ void updateWithTexturePack(TexturePack& tp);
+
+ static QString renderColorCodes(QString input);
public slots:
void descriptionEllipsisHandler(QString link);
diff --git a/launcher/ui/widgets/ProjectItem.cpp b/launcher/ui/widgets/ProjectItem.cpp
index 56ae35fb..01be88d9 100644
--- a/launcher/ui/widgets/ProjectItem.cpp
+++ b/launcher/ui/widgets/ProjectItem.cpp
@@ -14,9 +14,7 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
QStyleOptionViewItem opt(option);
initStyleOption(&opt, index);
- auto& rect = opt.rect;
- auto icon_width = rect.height(), icon_height = rect.height();
- auto remaining_width = rect.width() - icon_width;
+ auto rect = opt.rect;
if (opt.state & QStyle::State_Selected) {
painter->fillRect(rect, opt.palette.highlight());
@@ -25,11 +23,34 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
painter->fillRect(rect, opt.palette.window());
}
- { // Icon painting
- // Square-sized, occupying the left portion
- opt.icon.paint(painter, rect.x(), rect.y(), icon_width, icon_height);
+ // The default icon size will be a square (and height is usually the lower value).
+ auto icon_width = rect.height(), icon_height = rect.height();
+ int icon_x_margin = (rect.height() - icon_width) / 2;
+ int icon_y_margin = (rect.height() - icon_height) / 2;
+
+ if (!opt.icon.isNull()) { // Icon painting
+ {
+ auto icon_size = opt.decorationSize;
+ icon_width = icon_size.width();
+ icon_height = icon_size.height();
+
+ icon_x_margin = (rect.height() - icon_width) / 2;
+ icon_y_margin = (rect.height() - icon_height) / 2;
+ }
+
+ // Centralize icon with a margin to separate from the other elements
+ int x = rect.x() + icon_x_margin;
+ int y = rect.y() + icon_y_margin;
+
+ // Prevent 'scaling null pixmap' warnings
+ if (icon_width > 0 && icon_height > 0)
+ opt.icon.paint(painter, x, y, icon_width, icon_height);
}
+ // Change the rect so that funther painting is easier
+ auto remaining_width = rect.width() - icon_width - 2 * icon_x_margin;
+ rect.setRect(rect.x() + icon_width + 2 * icon_x_margin, rect.y(), remaining_width, rect.height());
+
{ // Title painting
auto title = index.data(UserDataTypes::TITLE).toString();
@@ -46,7 +67,7 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
painter->setFont(font);
// On the top, aligned to the left after the icon
- painter->drawText(rect.x() + icon_width, rect.y() + QFontMetrics(font).height(), title);
+ painter->drawText(rect.x(), rect.y() + QFontMetrics(font).height(), title);
painter->restore();
}
@@ -70,7 +91,7 @@ void ProjectItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& o
}
// On the bottom, aligned to the left after the icon, and featuring at most two lines of text (with some margin space to spare)
- painter->drawText(rect.x() + icon_width, rect.y() + rect.height() - 2.2 * opt.fontMetrics.height(), remaining_width,
+ painter->drawText(rect.x(), rect.y() + rect.height() - 2.2 * opt.fontMetrics.height(), remaining_width,
2 * opt.fontMetrics.height(), Qt::TextWordWrap, description);
}