From 6b154634e57216af9f1e1468b72ac10be0bee444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Tue, 25 Feb 2025 18:27:17 +0100 Subject: [PATCH] Add a sub type filter. --- ...atabase_display_sub_type_filter_widget.cpp | 154 ++++++++++++++++++ ..._database_display_sub_type_filter_widget.h | 42 +++++ .../visual_database_display_widget.cpp | 4 + 3 files changed, 200 insertions(+) create mode 100644 cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.cpp create mode 100644 cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.h diff --git a/cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.cpp b/cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.cpp new file mode 100644 index 000000000..1adec9a99 --- /dev/null +++ b/cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.cpp @@ -0,0 +1,154 @@ +#include "visual_database_display_sub_type_filter_widget.h" + +#include "../../../../game/cards/card_database_manager.h" +#include "../../../../game/filters/filter_tree_model.h" + +#include +#include +#include + +VisualDatabaseDisplaySubTypeFilterWidget::VisualDatabaseDisplaySubTypeFilterWidget(QWidget *parent, + FilterTreeModel *_filterModel) + : QWidget(parent), filterModel(_filterModel) +{ + allSubCardTypesWithCount = CardDatabaseManager::getInstance()->getAllSubCardTypesWithCount(); + + setMinimumWidth(300); + + layout = new QVBoxLayout(this); + setLayout(layout); + + // Create the spinbox + spinBox = new QSpinBox(this); + spinBox->setMinimum(1); + spinBox->setMaximum(getMaxSubTypeCount()); + spinBox->setValue(150); + layout->addWidget(spinBox); + connect(spinBox, QOverload::of(&QSpinBox::valueChanged), this, + &VisualDatabaseDisplaySubTypeFilterWidget::updateSubTypeButtonsVisibility); + + // Create the search box + searchBox = new QLineEdit(this); + searchBox->setPlaceholderText(tr("Search subtypes...")); + layout->addWidget(searchBox); + connect(searchBox, &QLineEdit::textChanged, this, + &VisualDatabaseDisplaySubTypeFilterWidget::updateSubTypeButtonsVisibility); + + flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded); + flowWidget->setMaximumHeight(300); + layout->addWidget(flowWidget); + + // Create the toggle button for Exact Match/Includes mode + toggleButton = new QPushButton(this); + toggleButton->setCheckable(true); + layout->addWidget(toggleButton); + connect(toggleButton, &QPushButton::toggled, this, &VisualDatabaseDisplaySubTypeFilterWidget::updateFilterMode); + + createSubTypeButtons(); // Populate buttons initially + updateFilterMode(false); +} + +void VisualDatabaseDisplaySubTypeFilterWidget::createSubTypeButtons() +{ + // Iterate through main types and create buttons + for (auto it = allSubCardTypesWithCount.begin(); it != allSubCardTypesWithCount.end(); ++it) { + auto *button = new QPushButton(it.key(), flowWidget); + button->setCheckable(true); + button->setStyleSheet("QPushButton { background-color: lightgray; border: 1px solid gray; padding: 5px; }" + "QPushButton:checked { background-color: green; color: white; }"); + + flowWidget->addWidget(button); + typeButtons[it.key()] = button; + + // Connect toggle signal + connect(button, &QPushButton::toggled, this, + [this, mainType = it.key()](bool checked) { handleSubTypeToggled(mainType, checked); }); + } + updateSubTypeButtonsVisibility(); // Ensure visibility is updated initially +} + +void VisualDatabaseDisplaySubTypeFilterWidget::updateSubTypeButtonsVisibility() +{ + int threshold = spinBox->value(); + QString filterText = searchBox->text().trimmed().toLower(); + + for (auto it = typeButtons.begin(); it != typeButtons.end(); ++it) { + QString subType = it.key().toLower(); + bool isActive = activeSubTypes.value(it.key(), false); + bool visible = isActive || (allSubCardTypesWithCount[it.key()] >= threshold && + (filterText.isEmpty() || subType.contains(filterText))); + + it.value()->setVisible(visible); + it.value()->setEnabled(visible); + } +} + +int VisualDatabaseDisplaySubTypeFilterWidget::getMaxSubTypeCount() const +{ + int maxCount = 1; + for (auto it = allSubCardTypesWithCount.begin(); it != allSubCardTypesWithCount.end(); ++it) { + maxCount = qMax(maxCount, it.value()); + } + return maxCount; +} + +void VisualDatabaseDisplaySubTypeFilterWidget::handleSubTypeToggled(const QString &mainType, bool active) +{ + activeSubTypes[mainType] = active; + + if (typeButtons.contains(mainType)) { + typeButtons[mainType]->setChecked(active); + } + + updateSubTypeFilter(); +} + +void VisualDatabaseDisplaySubTypeFilterWidget::updateSubTypeFilter() +{ + // Clear existing filters related to main type + filterModel->clearFiltersOfType(CardFilter::Attr::AttrType); + + if (exactMatchMode) { + // Exact Match: Only selected main types are allowed + QSet selectedTypes; + for (const auto &type : activeSubTypes.keys()) { + if (activeSubTypes[type]) { + selectedTypes.insert(type); + } + } + + if (!selectedTypes.isEmpty()) { + // Require all selected types (TypeAnd) + for (const auto &type : selectedTypes) { + QString typeString = type; + filterModel->addFilter( + new CardFilter(typeString, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrType)); + } + + // Exclude any other types (TypeAndNot) + for (const auto &type : typeButtons.keys()) { + if (!selectedTypes.contains(type)) { + QString typeString = type; + filterModel->addFilter( + new CardFilter(typeString, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrType)); + } + } + } + } else { + // Default Includes Mode (TypeOr) - match any selected main types + for (const auto &type : activeSubTypes.keys()) { + if (activeSubTypes[type]) { + QString typeString = type; + filterModel->addFilter( + new CardFilter(typeString, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrType)); + } + } + } +} + +void VisualDatabaseDisplaySubTypeFilterWidget::updateFilterMode(bool checked) +{ + exactMatchMode = checked; + toggleButton->setText(exactMatchMode ? tr("Mode: Exact Match") : tr("Mode: Includes")); + updateSubTypeFilter(); +} diff --git a/cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.h b/cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.h new file mode 100644 index 000000000..9a6148625 --- /dev/null +++ b/cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_sub_type_filter_widget.h @@ -0,0 +1,42 @@ +#ifndef VISUAL_DATABASE_DISPLAY_SUB_TYPE_FILTER_WIDGET_H +#define VISUAL_DATABASE_DISPLAY_SUB_TYPE_FILTER_WIDGET_H + +#include "../../../../game/filters/filter_tree_model.h" +#include "../general/layout_containers/flow_widget.h" + +#include +#include +#include +#include +#include +#include + +class VisualDatabaseDisplaySubTypeFilterWidget : public QWidget +{ + Q_OBJECT +public: + explicit VisualDatabaseDisplaySubTypeFilterWidget(QWidget *parent, FilterTreeModel *filterModel); + void createSubTypeButtons(); + void updateSubTypeButtonsVisibility(); + int getMaxSubTypeCount() const; + + void handleSubTypeToggled(const QString &mainType, bool active); + void updateSubTypeFilter(); + void updateFilterMode(bool checked); + +private: + FilterTreeModel *filterModel; + QMap allSubCardTypesWithCount; + QSpinBox *spinBox; + QVBoxLayout *layout; + QLineEdit *searchBox; + FlowWidget *flowWidget; + QPushButton *toggleButton; // Mode switch button + + QMap activeSubTypes; // Track active filters + QMap typeButtons; // Store toggle buttons + + bool exactMatchMode = false; // Toggle between "Exact Match" and "Includes" +}; + +#endif // VISUAL_DATABASE_DISPLAY_SUB_TYPE_FILTER_WIDGET_H diff --git a/cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_widget.cpp b/cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_widget.cpp index 81e402656..e81aead78 100644 --- a/cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_widget.cpp +++ b/cockatrice/src/client/ui/widgets/visual_database_display/visual_database_display_widget.cpp @@ -11,6 +11,7 @@ #include "visual_database_display_color_filter_widget.h" #include "visual_database_display_main_type_filter_widget.h" #include "visual_database_display_set_filter_widget.h" +#include "visual_database_display_sub_type_filter_widget.h" #include #include @@ -54,6 +55,9 @@ VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent, auto mainTypeFilterWidget = new VisualDatabaseDisplayMainTypeFilterWidget(this, filterModel); quickFilterWidget->addSettingsWidget(mainTypeFilterWidget); + auto subTypeFilterWidget = new VisualDatabaseDisplaySubTypeFilterWidget(this, filterModel); + quickFilterWidget->addSettingsWidget(subTypeFilterWidget); + auto setFilterWidget = new VisualDatabaseDisplaySetFilterWidget(this, filterModel); quickFilterWidget->addSettingsWidget(setFilterWidget);