From 277de4120052b2630850a18969a56ee92e8c2c63 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 14 Apr 2022 10:27:03 -0300 Subject: rework: make the filter as a tabbed widget in the dialog itself Still needs a clear indication that the filter only applies after you click the search button... --- launcher/ui/widgets/ModFilterWidget.cpp | 99 +++++++++++++++++++++++++++++++++ launcher/ui/widgets/ModFilterWidget.h | 65 ++++++++++++++++++++++ launcher/ui/widgets/ModFilterWidget.ui | 54 ++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 launcher/ui/widgets/ModFilterWidget.cpp create mode 100644 launcher/ui/widgets/ModFilterWidget.h create mode 100644 launcher/ui/widgets/ModFilterWidget.ui (limited to 'launcher/ui/widgets') diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp new file mode 100644 index 00000000..339ecb4b --- /dev/null +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -0,0 +1,99 @@ +#include "ModFilterWidget.h" +#include "ui_ModFilterWidget.h" + +ModFilterWidget::ModFilterWidget(Version def, QWidget* parent) + : QTabWidget(parent), m_filter(new Filter()), ui(new Ui::ModFilterWidget) +{ + ui->setupUi(this); + + m_mcVersion_buttons.addButton(ui->strictVersionButton, VersionButtonID::Strict); + ui->strictVersionButton->click(); + m_mcVersion_buttons.addButton(ui->majorVersionButton, VersionButtonID::Major); + m_mcVersion_buttons.addButton(ui->allVersionsButton, VersionButtonID::All); + //m_mcVersion_buttons.addButton(ui->betweenVersionsButton, VersionButtonID::Between); + + connect(&m_mcVersion_buttons, SIGNAL(idClicked(int)), this, SLOT(onVersionFilterChanged(int))); + + m_filter->versions.push_front(def); + + setHidden(true); +} + +void ModFilterWidget::setInstance(MinecraftInstance* instance) +{ + m_instance = instance; + + auto mcVersionSplit = mcVersionStr().split("."); + + ui->strictVersionButton->setText( + tr("Strict match (= %1)").arg(mcVersionStr())); + ui->majorVersionButton->setText( + tr("Major version match (= %1.%2.x)").arg(mcVersionSplit[0], mcVersionSplit[1])); + ui->allVersionsButton->setText( + tr("Any version")); + //ui->betweenVersionsButton->setText( + // tr("Between two versions")); +} + +auto ModFilterWidget::getFilter() -> std::shared_ptr +{ + m_last_version_id = m_version_id; + return m_filter; +} + +void ModFilterWidget::disableVersionButton(VersionButtonID id) +{ + switch(id){ + case(VersionButtonID::Strict): + ui->strictVersionButton->setEnabled(false); + break; + case(VersionButtonID::Major): + ui->majorVersionButton->setEnabled(false); + break; + case(VersionButtonID::All): + ui->allVersionsButton->setEnabled(false); + break; + case(VersionButtonID::Between): + // ui->betweenVersionsButton->setEnabled(false); + break; + default: + break; + } +} + +void ModFilterWidget::onVersionFilterChanged(int id) +{ + //ui->lowerVersionComboBox->setEnabled(id == VersionButtonID::Between); + //ui->upperVersionComboBox->setEnabled(id == VersionButtonID::Between); + + auto versionSplit = mcVersionStr().split("."); + int index = 0; + + auto cast_id = (VersionButtonID) id; + m_version_id = cast_id; + + m_filter->versions.clear(); + + switch(cast_id){ + case(VersionButtonID::Strict): + m_filter->versions.push_front(mcVersion()); + break; + case(VersionButtonID::Major): + for(auto i = Version(QString("%1.%2").arg(versionSplit[0], versionSplit[1])); i <= mcVersion(); index++){ + m_filter->versions.push_front(i); + i = Version(QString("%1.%2.%3").arg(versionSplit[0], versionSplit[1], QString("%1").arg(index))); + } + break; + case(VersionButtonID::All): + // Empty list to avoid enumerating all versions :P + break; + case(VersionButtonID::Between): + // TODO + break; + } +} + +ModFilterWidget::~ModFilterWidget() +{ + delete ui; +} diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h new file mode 100644 index 00000000..5348882f --- /dev/null +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include + +#include "Version.h" +#include "minecraft/MinecraftInstance.h" +#include "minecraft/PackProfile.h" + +class MinecraftInstance; + +namespace Ui { +class ModFilterWidget; +} + +class ModFilterWidget : public QTabWidget +{ + Q_OBJECT +public: + enum VersionButtonID { + Strict = 0, + Major = 1, + All = 2, + Between = 3 + }; + + struct Filter { + std::list versions; + + bool operator==(const Filter& other) const { return versions == other.versions; } + bool operator!=(const Filter& other) const { return !(*this == other); } + }; + + std::shared_ptr m_filter; + +public: + explicit ModFilterWidget(Version def, QWidget* parent = nullptr); + ~ModFilterWidget(); + + void setInstance(MinecraftInstance* instance); + + /// By default all buttons are enabled + void disableVersionButton(VersionButtonID); + + auto getFilter() -> std::shared_ptr; + auto changed() const -> bool { return m_last_version_id != m_version_id; } + +private: + inline auto mcVersionStr() const -> QString { return m_instance ? m_instance->getPackProfile()->getComponentVersion("net.minecraft") : ""; } + inline auto mcVersion() const -> Version { return { mcVersionStr() }; } + +private slots: + void onVersionFilterChanged(int id); + +private: + Ui::ModFilterWidget* ui; + + MinecraftInstance* m_instance = nullptr; + + QButtonGroup m_mcVersion_buttons; + + /* Used to tell if the filter was changed since the last getFilter() call */ + VersionButtonID m_last_version_id = VersionButtonID::Strict; + VersionButtonID m_version_id = VersionButtonID::Strict; +}; diff --git a/launcher/ui/widgets/ModFilterWidget.ui b/launcher/ui/widgets/ModFilterWidget.ui new file mode 100644 index 00000000..ad1090e2 --- /dev/null +++ b/launcher/ui/widgets/ModFilterWidget.ui @@ -0,0 +1,54 @@ + + + ModFilterWidget + + + + 0 + 0 + 400 + 300 + + + + + 0 + 0 + + + + + Minecraft versions + + + + + + + + allVersions + + + + + + + strictVersion + + + + + + + majorVersion + + + + + + + + + + + -- cgit From 5f15f51610f861521afdb295df0de6d9407ba951 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 14 Apr 2022 10:52:23 -0300 Subject: ui: underline search button text when changing filters This hopefully makes it easier to the user to know that their changes will only apply after hitting the search button. I tried setting the background color, but it seems more unreliable on cross-platform than underlining. Also, it could be worse for daltonic people, so I don't know what to do :( --- launcher/CMakeLists.txt | 7 +++---- launcher/ui/pages/modplatform/ModPage.cpp | 7 +++++++ launcher/ui/widgets/ModFilterWidget.cpp | 12 +++++++++++- launcher/ui/widgets/ModFilterWidget.h | 4 ++++ 4 files changed, 25 insertions(+), 5 deletions(-) (limited to 'launcher/ui/widgets') diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 8579071a..0ab398e8 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -824,9 +824,6 @@ SET(LAUNCHER_SOURCES ui/dialogs/SkinUploadDialog.h ui/dialogs/ModDownloadDialog.cpp ui/dialogs/ModDownloadDialog.h - ui/dialogs/FilterModsDialog.cpp - ui/dialogs/FilterModsDialog.h - # GUI - widgets ui/widgets/Common.cpp @@ -851,6 +848,8 @@ SET(LAUNCHER_SOURCES ui/widgets/LogView.h ui/widgets/MCModInfoFrame.cpp ui/widgets/MCModInfoFrame.h + ui/widgets/ModFilterWidget.cpp + ui/widgets/ModFilterWidget.h ui/widgets/ModListView.cpp ui/widgets/ModListView.h ui/widgets/PageContainer.cpp @@ -909,6 +908,7 @@ qt5_wrap_ui(LAUNCHER_UI ui/widgets/InstanceCardWidget.ui ui/widgets/CustomCommands.ui ui/widgets/MCModInfoFrame.ui + ui/widgets/ModFilterWidget.ui ui/dialogs/CopyInstanceDialog.ui ui/dialogs/ProfileSetupDialog.ui ui/dialogs/ProgressDialog.ui @@ -925,7 +925,6 @@ qt5_wrap_ui(LAUNCHER_UI ui/dialogs/LoginDialog.ui ui/dialogs/EditAccountDialog.ui ui/dialogs/ReviewMessageBox.ui - ui/dialogs/FilterModsDialog.ui ) qt5_add_resources(LAUNCHER_RESOURCES diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 57c2e45d..29f6b601 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -28,6 +28,13 @@ ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance* instance, ModAPI* api) filter_widget.setInstance(static_cast(m_instance)); m_filter = filter_widget.getFilter(); + + connect(&filter_widget, &ModFilterWidget::filterChanged, this, [&]{ + ui->searchButton->setStyleSheet("text-decoration: underline"); + }); + connect(&filter_widget, &ModFilterWidget::filterUnchanged, this, [&]{ + ui->searchButton->setStyleSheet("text-decoration: none"); + }); } ModPage::~ModPage() diff --git a/launcher/ui/widgets/ModFilterWidget.cpp b/launcher/ui/widgets/ModFilterWidget.cpp index 339ecb4b..ffc8d05d 100644 --- a/launcher/ui/widgets/ModFilterWidget.cpp +++ b/launcher/ui/widgets/ModFilterWidget.cpp @@ -38,6 +38,7 @@ void ModFilterWidget::setInstance(MinecraftInstance* instance) auto ModFilterWidget::getFilter() -> std::shared_ptr { m_last_version_id = m_version_id; + emit filterUnchanged(); return m_filter; } @@ -70,7 +71,11 @@ void ModFilterWidget::onVersionFilterChanged(int id) int index = 0; auto cast_id = (VersionButtonID) id; - m_version_id = cast_id; + if (cast_id != m_version_id) { + m_version_id = cast_id; + } else { + return; + } m_filter->versions.clear(); @@ -91,6 +96,11 @@ void ModFilterWidget::onVersionFilterChanged(int id) // TODO break; } + + if(changed()) + emit filterChanged(); + else + emit filterUnchanged(); } ModFilterWidget::~ModFilterWidget() diff --git a/launcher/ui/widgets/ModFilterWidget.h b/launcher/ui/widgets/ModFilterWidget.h index 5348882f..334fc672 100644 --- a/launcher/ui/widgets/ModFilterWidget.h +++ b/launcher/ui/widgets/ModFilterWidget.h @@ -52,6 +52,10 @@ private: private slots: void onVersionFilterChanged(int id); +public: signals: + void filterChanged(); + void filterUnchanged(); + private: Ui::ModFilterWidget* ui; -- cgit