Added categories filter
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
parent
35d62cc5f2
commit
41c9ca4f8a
@ -191,6 +191,11 @@ constexpr bool hasSingleModLoaderSelected(ModLoaderTypes l) noexcept
|
|||||||
return x && !(x & (x - 1));
|
return x && !(x & (x - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Category {
|
||||||
|
QString name;
|
||||||
|
QString id;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace ModPlatform
|
} // namespace ModPlatform
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ModPlatform::IndexedPack)
|
Q_DECLARE_METATYPE(ModPlatform::IndexedPack)
|
||||||
|
@ -74,6 +74,7 @@ class ResourceAPI {
|
|||||||
std::optional<ModPlatform::ModLoaderTypes> loaders;
|
std::optional<ModPlatform::ModLoaderTypes> loaders;
|
||||||
std::optional<std::list<Version> > versions;
|
std::optional<std::list<Version> > versions;
|
||||||
std::optional<QString> side;
|
std::optional<QString> side;
|
||||||
|
std::optional<QStringList> categoryIds;
|
||||||
};
|
};
|
||||||
struct SearchCallbacks {
|
struct SearchCallbacks {
|
||||||
std::function<void(QJsonDocument&)> on_succeed;
|
std::function<void(QJsonDocument&)> on_succeed;
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
// SPDX-License-Identifier: GPL-3.0-only
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
#include "FlameAPI.h"
|
#include "FlameAPI.h"
|
||||||
|
#include <memory>
|
||||||
#include "FlameModIndex.h"
|
#include "FlameModIndex.h"
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "Json.h"
|
#include "Json.h"
|
||||||
|
#include "modplatform/ModIndex.h"
|
||||||
#include "net/ApiDownload.h"
|
#include "net/ApiDownload.h"
|
||||||
#include "net/ApiUpload.h"
|
#include "net/ApiUpload.h"
|
||||||
#include "net/NetJob.h"
|
#include "net/NetJob.h"
|
||||||
@ -222,3 +224,42 @@ QList<ResourceAPI::SortingMethod> FlameAPI::getSortingMethods() const
|
|||||||
{
|
{
|
||||||
return s_sorts;
|
return s_sorts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Task::Ptr FlameAPI::getModCategories(std::shared_ptr<QByteArray> response)
|
||||||
|
{
|
||||||
|
auto netJob = makeShared<NetJob>(QString("Flame::GetCategories"), APPLICATION->network());
|
||||||
|
netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl("https://api.curseforge.com/v1/categories?gameId=432&classId=6"), response));
|
||||||
|
QObject::connect(netJob.get(), &Task::failed, [](QString msg) { qDebug() << "Flame failed to get categories:" << msg; });
|
||||||
|
return netJob;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ModPlatform::Category> FlameAPI::loadModCategories(std::shared_ptr<QByteArray> response)
|
||||||
|
{
|
||||||
|
QList<ModPlatform::Category> categories;
|
||||||
|
QJsonParseError parse_error{};
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
|
||||||
|
if (parse_error.error != QJsonParseError::NoError) {
|
||||||
|
qWarning() << "Error while parsing JSON response from categories at " << parse_error.offset
|
||||||
|
<< " reason: " << parse_error.errorString();
|
||||||
|
qWarning() << *response;
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto obj = Json::requireObject(doc);
|
||||||
|
auto arr = Json::requireArray(obj, "data");
|
||||||
|
|
||||||
|
for (auto val : arr) {
|
||||||
|
auto cat = Json::requireObject(val);
|
||||||
|
auto id = Json::requireInteger(cat, "id");
|
||||||
|
auto name = Json::requireString(cat, "name");
|
||||||
|
categories.push_back({ name, QString::number(id) });
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Json::JsonException& e) {
|
||||||
|
qCritical() << "Failed to parse response from a version request.";
|
||||||
|
qCritical() << e.what();
|
||||||
|
qDebug() << doc;
|
||||||
|
}
|
||||||
|
return categories;
|
||||||
|
};
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "modplatform/ModIndex.h"
|
#include "modplatform/ModIndex.h"
|
||||||
@ -22,6 +23,9 @@ class FlameAPI : public NetworkResourceAPI {
|
|||||||
Task::Ptr getFiles(const QStringList& fileIds, std::shared_ptr<QByteArray> response) const;
|
Task::Ptr getFiles(const QStringList& fileIds, std::shared_ptr<QByteArray> response) const;
|
||||||
Task::Ptr getFile(const QString& addonId, const QString& fileId, std::shared_ptr<QByteArray> response) const;
|
Task::Ptr getFile(const QString& addonId, const QString& fileId, std::shared_ptr<QByteArray> response) const;
|
||||||
|
|
||||||
|
static Task::Ptr getModCategories(std::shared_ptr<QByteArray> response);
|
||||||
|
static QList<ModPlatform::Category> loadModCategories(std::shared_ptr<QByteArray> response);
|
||||||
|
|
||||||
[[nodiscard]] auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
|
[[nodiscard]] auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
|
||||||
|
|
||||||
static inline auto validateModLoaders(ModPlatform::ModLoaderTypes loaders) -> bool
|
static inline auto validateModLoaders(ModPlatform::ModLoaderTypes loaders) -> bool
|
||||||
@ -96,6 +100,9 @@ class FlameAPI : public NetworkResourceAPI {
|
|||||||
get_arguments.append("sortOrder=desc");
|
get_arguments.append("sortOrder=desc");
|
||||||
if (args.loaders.has_value())
|
if (args.loaders.has_value())
|
||||||
get_arguments.append(QString("modLoaderTypes=%1").arg(getModLoaderFilters(args.loaders.value())));
|
get_arguments.append(QString("modLoaderTypes=%1").arg(getModLoaderFilters(args.loaders.value())));
|
||||||
|
if (args.categoryIds.has_value() && !args.categoryIds->empty())
|
||||||
|
get_arguments.append(QString("categoryIds=[%1]").arg(args.categoryIds->join(",")));
|
||||||
|
|
||||||
get_arguments.append(gameVersionStr);
|
get_arguments.append(gameVersionStr);
|
||||||
|
|
||||||
return "https://api.curseforge.com/v1/mods/search?gameId=432&" + get_arguments.join('&');
|
return "https://api.curseforge.com/v1/mods/search?gameId=432&" + get_arguments.join('&');
|
||||||
|
@ -122,3 +122,41 @@ QList<ResourceAPI::SortingMethod> ModrinthAPI::getSortingMethods() const
|
|||||||
{
|
{
|
||||||
return s_sorts;
|
return s_sorts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Task::Ptr ModrinthAPI::getModCategories(std::shared_ptr<QByteArray> response)
|
||||||
|
{
|
||||||
|
auto netJob = makeShared<NetJob>(QString("Modrinth::GetCategories"), APPLICATION->network());
|
||||||
|
netJob->addNetAction(Net::ApiDownload::makeByteArray(QUrl(BuildConfig.MODRINTH_PROD_URL + "/tag/category"), response));
|
||||||
|
QObject::connect(netJob.get(), &Task::failed, [](QString msg) { qDebug() << "Modrinth failed to get categories:" << msg; });
|
||||||
|
return netJob;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<ModPlatform::Category> ModrinthAPI::loadModCategories(std::shared_ptr<QByteArray> response)
|
||||||
|
{
|
||||||
|
QList<ModPlatform::Category> categories;
|
||||||
|
QJsonParseError parse_error{};
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
|
||||||
|
if (parse_error.error != QJsonParseError::NoError) {
|
||||||
|
qWarning() << "Error while parsing JSON response from categories at " << parse_error.offset
|
||||||
|
<< " reason: " << parse_error.errorString();
|
||||||
|
qWarning() << *response;
|
||||||
|
return categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto arr = Json::requireArray(doc);
|
||||||
|
|
||||||
|
for (auto val : arr) {
|
||||||
|
auto cat = Json::requireObject(val);
|
||||||
|
auto name = Json::requireString(cat, "name");
|
||||||
|
if (Json::ensureString(cat, "project_type", "") == "mod")
|
||||||
|
categories.push_back({ name, name });
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Json::JsonException& e) {
|
||||||
|
qCritical() << "Failed to parse response from a version request.";
|
||||||
|
qCritical() << e.what();
|
||||||
|
qDebug() << doc;
|
||||||
|
}
|
||||||
|
return categories;
|
||||||
|
};
|
@ -30,6 +30,9 @@ class ModrinthAPI : public NetworkResourceAPI {
|
|||||||
|
|
||||||
Task::Ptr getProjects(QStringList addonIds, std::shared_ptr<QByteArray> response) const override;
|
Task::Ptr getProjects(QStringList addonIds, std::shared_ptr<QByteArray> response) const override;
|
||||||
|
|
||||||
|
static Task::Ptr getModCategories(std::shared_ptr<QByteArray> response);
|
||||||
|
static QList<ModPlatform::Category> loadModCategories(std::shared_ptr<QByteArray> response);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
|
[[nodiscard]] auto getSortingMethods() const -> QList<ResourceAPI::SortingMethod> override;
|
||||||
|
|
||||||
@ -56,6 +59,15 @@ class ModrinthAPI : public NetworkResourceAPI {
|
|||||||
return l.join(',');
|
return l.join(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static auto getCategoriesFilters(QStringList categories) -> const QString
|
||||||
|
{
|
||||||
|
QStringList l;
|
||||||
|
for (auto cat : categories) {
|
||||||
|
l << QString("\"categories:%1\"").arg(cat);
|
||||||
|
}
|
||||||
|
return l.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
static auto getSideFilters(QString side) -> const QString
|
static auto getSideFilters(QString side) -> const QString
|
||||||
{
|
{
|
||||||
if (side.isEmpty() || side == "both") {
|
if (side.isEmpty() || side == "both") {
|
||||||
@ -99,6 +111,9 @@ class ModrinthAPI : public NetworkResourceAPI {
|
|||||||
if (!side.isEmpty())
|
if (!side.isEmpty())
|
||||||
facets_list.append(QString("[%1]").arg(side));
|
facets_list.append(QString("[%1]").arg(side));
|
||||||
}
|
}
|
||||||
|
if (args.categoryIds.has_value() && !args.categoryIds->empty())
|
||||||
|
facets_list.append(QString("[%1]").arg(getCategoriesFilters(args.categoryIds.value())));
|
||||||
|
|
||||||
facets_list.append(QString("[\"project_type:%1\"]").arg(resourceTypeParameter(args.type)));
|
facets_list.append(QString("[\"project_type:%1\"]").arg(resourceTypeParameter(args.type)));
|
||||||
|
|
||||||
return QString("[%1]").arg(facets_list.join(','));
|
return QString("[%1]").arg(facets_list.join(','));
|
||||||
|
@ -25,6 +25,7 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments()
|
|||||||
Q_ASSERT(m_filter);
|
Q_ASSERT(m_filter);
|
||||||
|
|
||||||
std::optional<std::list<Version>> versions{};
|
std::optional<std::list<Version>> versions{};
|
||||||
|
std::optional<QStringList> categories{};
|
||||||
auto loaders = profile->getSupportedModLoaders();
|
auto loaders = profile->getSupportedModLoaders();
|
||||||
|
|
||||||
// Version filter
|
// Version filter
|
||||||
@ -32,11 +33,13 @@ ResourceAPI::SearchArgs ModModel::createSearchArguments()
|
|||||||
versions = m_filter->versions;
|
versions = m_filter->versions;
|
||||||
if (m_filter->loaders)
|
if (m_filter->loaders)
|
||||||
loaders = m_filter->loaders;
|
loaders = m_filter->loaders;
|
||||||
|
if (!m_filter->categoryIds.empty())
|
||||||
|
categories = m_filter->categoryIds;
|
||||||
auto side = m_filter->side;
|
auto side = m_filter->side;
|
||||||
|
|
||||||
auto sort = getCurrentSortingMethodByIndex();
|
auto sort = getCurrentSortingMethodByIndex();
|
||||||
|
|
||||||
return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term, sort, loaders, versions, side };
|
return { ModPlatform::ResourceType::MOD, m_next_search_offset, m_search_term, sort, loaders, versions, side, categories };
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& entry)
|
ResourceAPI::VersionSearchArgs ModModel::createVersionsArguments(QModelIndex& entry)
|
||||||
|
@ -78,6 +78,7 @@ void ModPage::setFilterWidget(unique_qobject_ptr<ModFilterWidget>& widget)
|
|||||||
[&] { m_ui->searchButton->setStyleSheet("text-decoration: underline"); });
|
[&] { m_ui->searchButton->setStyleSheet("text-decoration: underline"); });
|
||||||
connect(m_filter_widget.get(), &ModFilterWidget::filterUnchanged, this,
|
connect(m_filter_widget.get(), &ModFilterWidget::filterUnchanged, this,
|
||||||
[&] { m_ui->searchButton->setStyleSheet("text-decoration: none"); });
|
[&] { m_ui->searchButton->setStyleSheet("text-decoration: none"); });
|
||||||
|
prepareProviderCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
/******** Callbacks to events in the UI (set up in the derived classes) ********/
|
/******** Callbacks to events in the UI (set up in the derived classes) ********/
|
||||||
|
@ -61,6 +61,8 @@ class ModPage : public ResourcePage {
|
|||||||
protected:
|
protected:
|
||||||
ModPage(ModDownloadDialog* dialog, BaseInstance& instance);
|
ModPage(ModDownloadDialog* dialog, BaseInstance& instance);
|
||||||
|
|
||||||
|
virtual void prepareProviderCategories(){};
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void filterMods();
|
virtual void filterMods();
|
||||||
void triggerSearch() override;
|
void triggerSearch() override;
|
||||||
|
@ -37,6 +37,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FlameResourcePages.h"
|
#include "FlameResourcePages.h"
|
||||||
|
#include <QList>
|
||||||
|
#include <memory>
|
||||||
|
#include "modplatform/ModIndex.h"
|
||||||
|
#include "modplatform/flame/FlameAPI.h"
|
||||||
#include "ui_ResourcePage.h"
|
#include "ui_ResourcePage.h"
|
||||||
|
|
||||||
#include "FlameResourceModels.h"
|
#include "FlameResourceModels.h"
|
||||||
@ -204,4 +208,14 @@ unique_qobject_ptr<ModFilterWidget> FlameModPage::createFilterWidget()
|
|||||||
return ModFilterWidget::create(&static_cast<MinecraftInstance&>(m_base_instance), false, this);
|
return ModFilterWidget::create(&static_cast<MinecraftInstance&>(m_base_instance), false, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlameModPage::prepareProviderCategories()
|
||||||
|
{
|
||||||
|
auto response = std::make_shared<QByteArray>();
|
||||||
|
auto task = FlameAPI::getModCategories(response);
|
||||||
|
QObject::connect(task.get(), &Task::succeeded, [this, response]() {
|
||||||
|
auto categories = FlameAPI::loadModCategories(response);
|
||||||
|
m_filter_widget->setCategories(categories);
|
||||||
|
});
|
||||||
|
task->start();
|
||||||
|
};
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -96,6 +96,9 @@ class FlameModPage : public ModPage {
|
|||||||
|
|
||||||
void openUrl(const QUrl& url) override;
|
void openUrl(const QUrl& url) override;
|
||||||
unique_qobject_ptr<ModFilterWidget> createFilterWidget() override;
|
unique_qobject_ptr<ModFilterWidget> createFilterWidget() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void prepareProviderCategories() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlameResourcePackPage : public ResourcePackResourcePage {
|
class FlameResourcePackPage : public ResourcePackResourcePage {
|
||||||
|
@ -141,4 +141,15 @@ unique_qobject_ptr<ModFilterWidget> ModrinthModPage::createFilterWidget()
|
|||||||
{
|
{
|
||||||
return ModFilterWidget::create(&static_cast<MinecraftInstance&>(m_base_instance), true, this);
|
return ModFilterWidget::create(&static_cast<MinecraftInstance&>(m_base_instance), true, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModrinthModPage::prepareProviderCategories()
|
||||||
|
{
|
||||||
|
auto response = std::make_shared<QByteArray>();
|
||||||
|
auto task = ModrinthAPI::getModCategories(response);
|
||||||
|
QObject::connect(task.get(), &Task::succeeded, [this, response]() {
|
||||||
|
auto categories = ModrinthAPI::loadModCategories(response);
|
||||||
|
m_filter_widget->setCategories(categories);
|
||||||
|
});
|
||||||
|
task->start();
|
||||||
|
};
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -94,6 +94,9 @@ class ModrinthModPage : public ModPage {
|
|||||||
[[nodiscard]] inline auto helpPage() const -> QString override { return "Mod-platform"; }
|
[[nodiscard]] inline auto helpPage() const -> QString override { return "Mod-platform"; }
|
||||||
|
|
||||||
unique_qobject_ptr<ModFilterWidget> createFilterWidget() override;
|
unique_qobject_ptr<ModFilterWidget> createFilterWidget() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void prepareProviderCategories() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModrinthResourcePackPage : public ResourcePackResourcePage {
|
class ModrinthResourcePackPage : public ResourcePackResourcePage {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "ModFilterWidget.h"
|
#include "ModFilterWidget.h"
|
||||||
#include <qcheckbox.h>
|
#include <QCheckBox>
|
||||||
#include <qcombobox.h>
|
#include <QComboBox>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <algorithm>
|
||||||
#include "BaseVersionList.h"
|
#include "BaseVersionList.h"
|
||||||
#include "meta/Index.h"
|
#include "meta/Index.h"
|
||||||
#include "modplatform/ModIndex.h"
|
#include "modplatform/ModIndex.h"
|
||||||
@ -76,6 +78,8 @@ ModFilterWidget::ModFilterWidget(MinecraftInstance* instance, bool extendedSuppo
|
|||||||
connect(ui->alphaCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged);
|
connect(ui->alphaCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged);
|
||||||
connect(ui->unknownCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged);
|
connect(ui->unknownCb, &QCheckBox::stateChanged, this, &ModFilterWidget::onReleaseFilterChanged);
|
||||||
|
|
||||||
|
connect(ui->categoriesList, &QListWidget::itemClicked, this, &ModFilterWidget::onCategoryClicked);
|
||||||
|
|
||||||
setHidden(true);
|
setHidden(true);
|
||||||
loadVersionList();
|
loadVersionList();
|
||||||
prepareBasicFilter();
|
prepareBasicFilter();
|
||||||
@ -238,4 +242,33 @@ void ModFilterWidget::onVersionFilterTextChanged(QString version)
|
|||||||
emit filterChanged();
|
emit filterChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModFilterWidget::setCategories(QList<ModPlatform::Category> categories)
|
||||||
|
{
|
||||||
|
ui->categoriesList->clear();
|
||||||
|
m_categories = categories;
|
||||||
|
for (auto cat : categories) {
|
||||||
|
auto item = new QListWidgetItem(cat.name, ui->categoriesList);
|
||||||
|
item->setFlags(item->flags() & (~Qt::ItemIsUserCheckable));
|
||||||
|
item->setCheckState(Qt::Unchecked);
|
||||||
|
ui->categoriesList->addItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModFilterWidget::onCategoryClicked(QListWidgetItem* item)
|
||||||
|
{
|
||||||
|
if (item)
|
||||||
|
item->setCheckState(item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked);
|
||||||
|
m_filter->categoryIds.clear();
|
||||||
|
for (auto i = 0; i < ui->categoriesList->count(); i++) {
|
||||||
|
auto item = ui->categoriesList->item(i);
|
||||||
|
if (item->checkState() == Qt::Checked) {
|
||||||
|
auto c = std::find_if(m_categories.cbegin(), m_categories.cend(), [item](auto v) { return v.name == item->text(); });
|
||||||
|
if (c != m_categories.cend())
|
||||||
|
m_filter->categoryIds << c->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_filter_changed = true;
|
||||||
|
emit filterChanged();
|
||||||
|
};
|
||||||
|
|
||||||
#include "ModFilterWidget.moc"
|
#include "ModFilterWidget.moc"
|
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QButtonGroup>
|
#include <QButtonGroup>
|
||||||
|
#include <QList>
|
||||||
|
#include <QListWidgetItem>
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
|
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
@ -26,11 +28,12 @@ class ModFilterWidget : public QTabWidget {
|
|||||||
ModPlatform::ModLoaderTypes loaders;
|
ModPlatform::ModLoaderTypes loaders;
|
||||||
QString side;
|
QString side;
|
||||||
bool hideInstalled;
|
bool hideInstalled;
|
||||||
|
QStringList categoryIds;
|
||||||
|
|
||||||
bool operator==(const Filter& other) const
|
bool operator==(const Filter& other) const
|
||||||
{
|
{
|
||||||
return hideInstalled == other.hideInstalled && side == other.side && loaders == other.loaders && versions == other.versions &&
|
return hideInstalled == other.hideInstalled && side == other.side && loaders == other.loaders && versions == other.versions &&
|
||||||
releases == other.releases;
|
releases == other.releases && categoryIds == other.categoryIds;
|
||||||
}
|
}
|
||||||
bool operator!=(const Filter& other) const { return !(*this == other); }
|
bool operator!=(const Filter& other) const { return !(*this == other); }
|
||||||
};
|
};
|
||||||
@ -45,6 +48,9 @@ class ModFilterWidget : public QTabWidget {
|
|||||||
void filterChanged();
|
void filterChanged();
|
||||||
void filterUnchanged();
|
void filterUnchanged();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setCategories(QList<ModPlatform::Category>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ModFilterWidget(MinecraftInstance* instance, bool extendedSupport, QWidget* parent = nullptr);
|
ModFilterWidget(MinecraftInstance* instance, bool extendedSupport, QWidget* parent = nullptr);
|
||||||
|
|
||||||
@ -59,6 +65,7 @@ class ModFilterWidget : public QTabWidget {
|
|||||||
void onSideFilterChanged();
|
void onSideFilterChanged();
|
||||||
void onHideInstalledFilterChanged();
|
void onHideInstalledFilterChanged();
|
||||||
void onIncludeSnapshotsChanged();
|
void onIncludeSnapshotsChanged();
|
||||||
|
void onCategoryClicked(QListWidgetItem* item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::ModFilterWidget* ui;
|
Ui::ModFilterWidget* ui;
|
||||||
@ -69,4 +76,6 @@ class ModFilterWidget : public QTabWidget {
|
|||||||
|
|
||||||
Meta::VersionList::Ptr m_version_list;
|
Meta::VersionList::Ptr m_version_list;
|
||||||
VersionProxyModel* m_versions_proxy = nullptr;
|
VersionProxyModel* m_versions_proxy = nullptr;
|
||||||
|
|
||||||
|
QList<ModPlatform::Category> m_categories;
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>460</width>
|
<width>460</width>
|
||||||
<height>127</height>
|
<height>132</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -145,6 +145,44 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="CategoryPage">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Categories</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QListWidget" name="categoriesList">
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||||
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
|
<property name="showDropIndicator" stdset="0">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::NoSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollMode">
|
||||||
|
<enum>QAbstractItemView::ScrollPerItem</enum>
|
||||||
|
</property>
|
||||||
|
<property name="flow">
|
||||||
|
<enum>QListView::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="isWrapping" stdset="0">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="viewMode">
|
||||||
|
<enum>QListView::ListMode</enum>
|
||||||
|
</property>
|
||||||
|
<property name="modelColumn">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
<widget class="QWidget" name="ModPage">
|
<widget class="QWidget" name="ModPage">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Others</string>
|
<string>Others</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user