mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-09 03:23:24 -08:00
Rederive the mode from saved filters, added Custom mode
This commit is contained in:
parent
e85e81ce85
commit
f2e4aa3c34
2 changed files with 130 additions and 83 deletions
|
|
@ -15,6 +15,39 @@
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <libcockatrice/filters/filter_tree.h>
|
#include <libcockatrice/filters/filter_tree.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Information about the filter mode.
|
||||||
|
*/
|
||||||
|
struct FilterModeInfo
|
||||||
|
{
|
||||||
|
CardFilter::Type includeType;
|
||||||
|
CardFilter::Type excludeType;
|
||||||
|
CardFilter::Attr attr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return information about the filter mode.
|
||||||
|
*/
|
||||||
|
static FilterModeInfo getFilterModeInfo(FilterMode filterMode)
|
||||||
|
{
|
||||||
|
switch (filterMode) {
|
||||||
|
case FilterMode::Includes:
|
||||||
|
return {CardFilter::TypeOr, CardFilter::TypeEnd, CardFilter::AttrColor};
|
||||||
|
case FilterMode::Excludes:
|
||||||
|
return {CardFilter::TypeAndNot, CardFilter::TypeEnd, CardFilter::AttrColor};
|
||||||
|
case FilterMode::IncludeExclude:
|
||||||
|
return {CardFilter::TypeOr, CardFilter::TypeAndNot, CardFilter::AttrColor};
|
||||||
|
case FilterMode::ExactMatch:
|
||||||
|
return {CardFilter::TypeAnd, CardFilter::TypeAndNot, CardFilter::AttrColor};
|
||||||
|
case FilterMode::ColorIdentity:
|
||||||
|
return {CardFilter::TypeEnd, CardFilter::TypeAndNot, CardFilter::AttrColorIdentity};
|
||||||
|
case FilterMode::Custom:
|
||||||
|
case FilterMode::End:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {CardFilter::TypeEnd, CardFilter::TypeEnd, CardFilter::AttrEnd};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This widget provides a graphical control element for the CardFilter::Attr::AttrColor filters applied to the filter
|
* This widget provides a graphical control element for the CardFilter::Attr::AttrColor filters applied to the filter
|
||||||
* model.
|
* model.
|
||||||
|
|
@ -59,16 +92,17 @@ void VisualDatabaseDisplayColorFilterWidget::retranslateUi()
|
||||||
modeComboBox->blockSignals(true);
|
modeComboBox->blockSignals(true);
|
||||||
modeComboBox->clear();
|
modeComboBox->clear();
|
||||||
|
|
||||||
modeComboBox->addItem(tr("Exact match"), QVariant::fromValue(FilterMode::ExactMatch));
|
|
||||||
modeComboBox->addItem(tr("Includes"), QVariant::fromValue(FilterMode::Includes));
|
modeComboBox->addItem(tr("Includes"), QVariant::fromValue(FilterMode::Includes));
|
||||||
modeComboBox->addItem(tr("Excludes"), QVariant::fromValue(FilterMode::Excludes));
|
modeComboBox->addItem(tr("Excludes"), QVariant::fromValue(FilterMode::Excludes));
|
||||||
modeComboBox->addItem(tr("Include / Exclude"), QVariant::fromValue(FilterMode::IncludeExclude));
|
modeComboBox->addItem(tr("Include / Exclude"), QVariant::fromValue(FilterMode::IncludeExclude));
|
||||||
|
modeComboBox->addItem(tr("Exact match"), QVariant::fromValue(FilterMode::ExactMatch));
|
||||||
modeComboBox->addItem(tr("Color identity"), QVariant::fromValue(FilterMode::ColorIdentity));
|
modeComboBox->addItem(tr("Color identity"), QVariant::fromValue(FilterMode::ColorIdentity));
|
||||||
|
|
||||||
modeComboBox->setItemData(0, tr("Cards being exactly of the selected colors"), Qt::ToolTipRole);
|
modeComboBox->setItemData(0, tr("Cards containing any of the selected colors"), Qt::ToolTipRole);
|
||||||
modeComboBox->setItemData(1, tr("Cards containing any of the selected colors"), Qt::ToolTipRole);
|
modeComboBox->setItemData(1, tr("Cards containing none of the selected colors"), Qt::ToolTipRole);
|
||||||
modeComboBox->setItemData(2, tr("Cards containing none of the selected colors"), Qt::ToolTipRole);
|
modeComboBox->setItemData(2, tr("Cards containing any of the selected colors and none of the unselected colors"),
|
||||||
modeComboBox->setItemData(3, tr("Cards containing any of the selected colors and none of the unselected colors"), Qt::ToolTipRole);
|
Qt::ToolTipRole);
|
||||||
|
modeComboBox->setItemData(3, tr("Cards being exactly of the selected colors"), Qt::ToolTipRole);
|
||||||
modeComboBox->setItemData(4, tr("Cards whose color identity fits within the selected colors"), Qt::ToolTipRole);
|
modeComboBox->setItemData(4, tr("Cards whose color identity fits within the selected colors"), Qt::ToolTipRole);
|
||||||
|
|
||||||
modeComboBox->setToolTip(tr("How selected and unselected colors are combined in the filter"));
|
modeComboBox->setToolTip(tr("How selected and unselected colors are combined in the filter"));
|
||||||
|
|
@ -91,6 +125,7 @@ void VisualDatabaseDisplayColorFilterWidget::handleColorToggled(QChar color, boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief TODO */
|
||||||
static void removeFilters(FilterTreeModel *filterModel, QChar color, CardFilter::Attr attr)
|
static void removeFilters(FilterTreeModel *filterModel, QChar color, CardFilter::Attr attr)
|
||||||
{
|
{
|
||||||
for (const CardFilter *filter : filterModel->getFiltersOfType(attr)) {
|
for (const CardFilter *filter : filterModel->getFiltersOfType(attr)) {
|
||||||
|
|
@ -102,59 +137,24 @@ static void removeFilters(FilterTreeModel *filterModel, QChar color, CardFilter:
|
||||||
|
|
||||||
void VisualDatabaseDisplayColorFilterWidget::addFilter(QChar color)
|
void VisualDatabaseDisplayColorFilterWidget::addFilter(QChar color)
|
||||||
{
|
{
|
||||||
switch (currentMode) {
|
FilterModeInfo info = getFilterModeInfo(currentMode);
|
||||||
case FilterMode::ExactMatch:
|
|
||||||
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
|
||||||
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrColor));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FilterMode::Includes:
|
removeFilters(filterModel, color, info.attr);
|
||||||
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
|
||||||
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeOr, CardFilter::Attr::AttrColor));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FilterMode::Excludes:
|
if (info.includeType != CardFilter::TypeEnd) {
|
||||||
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
filterModel->addFilter(new CardFilter(color, info.includeType, info.attr));
|
||||||
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColor));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FilterMode::IncludeExclude:
|
|
||||||
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
|
||||||
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeOr, CardFilter::Attr::AttrColor));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FilterMode::ColorIdentity:
|
|
||||||
removeFilters(filterModel, color, CardFilter::Attr::AttrColorIdentity);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualDatabaseDisplayColorFilterWidget::removeFilter(QChar color)
|
void VisualDatabaseDisplayColorFilterWidget::removeFilter(QChar color)
|
||||||
{
|
{
|
||||||
// Add exclusion filters if the mode demands it
|
FilterModeInfo info = getFilterModeInfo(currentMode);
|
||||||
switch (currentMode) {
|
|
||||||
case FilterMode::ExactMatch:
|
|
||||||
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
|
||||||
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColor));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FilterMode::Includes:
|
removeFilters(filterModel, color, info.attr);
|
||||||
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FilterMode::Excludes:
|
// Add exclusion filters if the mode demands it.
|
||||||
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
if (info.excludeType != CardFilter::TypeEnd) {
|
||||||
break;
|
filterModel->addFilter(new CardFilter(color, info.excludeType, info.attr));
|
||||||
|
|
||||||
case FilterMode::IncludeExclude:
|
|
||||||
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
|
||||||
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColor));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FilterMode::ColorIdentity:
|
|
||||||
removeFilters(filterModel, color, CardFilter::Attr::AttrColorIdentity);
|
|
||||||
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColorIdentity));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,42 +214,86 @@ QList<QChar> VisualDatabaseDisplayColorFilterWidget::getActiveColors()
|
||||||
|
|
||||||
void VisualDatabaseDisplayColorFilterWidget::syncWithFilterModel()
|
void VisualDatabaseDisplayColorFilterWidget::syncWithFilterModel()
|
||||||
{
|
{
|
||||||
QList<const CardFilter *> allColorFilters = filterModel->getFiltersOfType(
|
// Determine the correct currentMode from the filter model by finding which modes
|
||||||
currentMode == FilterMode::ColorIdentity
|
// are not possible due to the model containing filters that that mode cannot add.
|
||||||
? CardFilter::Attr::AttrColorIdentity
|
constexpr int modeCount = static_cast<int>(FilterMode::End);
|
||||||
: CardFilter::Attr::AttrColor);
|
bool modeImpossible[modeCount] = {};
|
||||||
|
|
||||||
QList<ManaSymbolWidget *> manaSymbolWidgets = findChildren<ManaSymbolWidget *>();
|
QList<const CardFilter *> filters;
|
||||||
|
filters.append(filterModel->getFiltersOfType(CardFilter::AttrColor));
|
||||||
|
filters.append(filterModel->getFiltersOfType(CardFilter::AttrColorIdentity));
|
||||||
|
|
||||||
for (ManaSymbolWidget *manaSymbolWidget : manaSymbolWidgets) {
|
if (filters.empty()) {
|
||||||
QChar symbol = manaSymbolWidget->getSymbolChar();
|
// Remove the modes that should always contain filters.
|
||||||
bool found = currentMode == FilterMode::ColorIdentity;
|
for (int i = 0; i < modeCount; ++i) {
|
||||||
for (const CardFilter *filter : allColorFilters) {
|
FilterModeInfo modeInfo = getFilterModeInfo(static_cast<FilterMode>(i));
|
||||||
if (symbol == filter->term()) {
|
if (modeInfo.includeType != CardFilter::TypeEnd && modeInfo.excludeType != CardFilter::TypeEnd) {
|
||||||
switch (currentMode) {
|
modeImpossible[i] = true;
|
||||||
case FilterMode::ExactMatch:
|
}
|
||||||
if (filter->type() == CardFilter::Type::TypeAnd)
|
}
|
||||||
found = true;
|
} else {
|
||||||
break;
|
// Remove the modes that cannot create one of the filters.
|
||||||
case FilterMode::Includes:
|
for (const CardFilter *filter : filters) {
|
||||||
case FilterMode::IncludeExclude:
|
for (int i = 0; i < modeCount; ++i) {
|
||||||
if (filter->type() == CardFilter::Type::TypeOr)
|
FilterModeInfo modeInfo = getFilterModeInfo(static_cast<FilterMode>(i));
|
||||||
found = true;
|
if (filter->attr() != modeInfo.attr ||
|
||||||
break;
|
(filter->type() != modeInfo.includeType && filter->type() != modeInfo.excludeType)) {
|
||||||
case FilterMode::Excludes:
|
modeImpossible[i] = true;
|
||||||
if (filter->type() == CardFilter::Type::TypeAndNot)
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
case FilterMode::ColorIdentity:
|
|
||||||
if (filter->type() == CardFilter::Type::TypeAndNot)
|
|
||||||
found = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (found)
|
}
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the current mode is not possible with the current filters, set it to the first
|
||||||
|
// one that is. Switching to and from the custom mode is always possible.
|
||||||
|
if (modeImpossible[static_cast<int>(currentMode)] || currentMode == FilterMode::Custom) {
|
||||||
|
for (int i = 0; i < modeCount; ++i) {
|
||||||
|
if (!modeImpossible[i] || i == static_cast<int>(FilterMode::Custom)) {
|
||||||
|
currentMode = static_cast<FilterMode>(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the combobox. Add a Custom item only if we have a custom filter mode.
|
||||||
|
int customIndex = modeComboBox->findData(QVariant::fromValue(FilterMode::Custom));
|
||||||
|
modeComboBox->blockSignals(true);
|
||||||
|
if (currentMode == FilterMode::Custom) {
|
||||||
|
if (customIndex < 0) {
|
||||||
|
customIndex = modeComboBox->count();
|
||||||
|
modeComboBox->addItem(tr("Custom"), QVariant::fromValue(FilterMode::Custom));
|
||||||
|
modeComboBox->setItemData(customIndex, tr("Cards matching an unknown combination of color filters"),
|
||||||
|
Qt::ToolTipRole);
|
||||||
|
}
|
||||||
|
modeComboBox->setCurrentIndex(customIndex);
|
||||||
|
} else {
|
||||||
|
if (customIndex >= 0) {
|
||||||
|
modeComboBox->removeItem(customIndex);
|
||||||
|
}
|
||||||
|
int index = modeComboBox->findData(QVariant::fromValue(currentMode));
|
||||||
|
if (index >= 0) {
|
||||||
|
modeComboBox->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
modeComboBox->blockSignals(false);
|
||||||
|
|
||||||
|
// Update the mana symbol widgets by looking for the current mode's include or exclude filters.
|
||||||
|
const FilterModeInfo modeInfo = getFilterModeInfo(currentMode);
|
||||||
|
|
||||||
|
const bool useExclude = modeInfo.includeType == CardFilter::TypeEnd && modeInfo.excludeType != CardFilter::TypeEnd;
|
||||||
|
const CardFilter::Type filterType = useExclude ? modeInfo.excludeType : modeInfo.includeType;
|
||||||
|
|
||||||
|
filters = filterModel->getFiltersOfType(modeInfo.attr);
|
||||||
|
|
||||||
|
for (ManaSymbolWidget *manaSymbolWidget : findChildren<ManaSymbolWidget *>()) {
|
||||||
|
bool found = false;
|
||||||
|
for (const CardFilter *filter : filters) {
|
||||||
|
if (filter->type() == filterType && manaSymbolWidget->getSymbolChar() == filter->term()) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setManaSymbolActive(manaSymbolWidget->getSymbolChar(), found);
|
manaSymbolWidget->setColorActive(useExclude ? !found : found);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,11 +40,14 @@ private:
|
||||||
|
|
||||||
enum class FilterMode
|
enum class FilterMode
|
||||||
{
|
{
|
||||||
ExactMatch, // Only selected colors are included, all others are excluded.
|
Includes = 0, // Include selected colors (OR condition).
|
||||||
Includes, // Include selected colors (OR condition).
|
|
||||||
Excludes, // Exclude selected colors (AND NOT).
|
Excludes, // Exclude selected colors (AND NOT).
|
||||||
IncludeExclude, // Include selected colors (OR) and exclude unselected colors (AND NOT).
|
IncludeExclude, // Include selected colors (OR) and exclude unselected colors (AND NOT).
|
||||||
ColorIdentity // Keep cards whose color identity is a subset of the selected colors (stored as ANDNOT for each unselected color).
|
ExactMatch, // Only selected colors are included, all others are excluded.
|
||||||
|
ColorIdentity, // Keep cards whose color identity is a subset of the selected colors (stored as ANDNOT for each
|
||||||
|
// unselected color).
|
||||||
|
Custom, // The filters do not match any of the modes. Not included in the combo box.
|
||||||
|
End
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(FilterMode)
|
Q_DECLARE_METATYPE(FilterMode)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue