mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-29 10:03:55 -07:00
[VDS] Allow tags to toggle to a NOT state to hide non-matching decks (#5920)
* Allow excluding tags. * Lint. * My linter is broken, don't ask. * Zzz. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
f16ba6861b
commit
46e146b34a
3 changed files with 82 additions and 41 deletions
|
|
@ -6,7 +6,7 @@
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
|
|
||||||
DeckPreviewTagDisplayWidget::DeckPreviewTagDisplayWidget(QWidget *parent, const QString &_tagName)
|
DeckPreviewTagDisplayWidget::DeckPreviewTagDisplayWidget(QWidget *parent, const QString &_tagName)
|
||||||
: QWidget(parent), tagName(_tagName), isSelected(false)
|
: QWidget(parent), tagName(_tagName), state(TagState::NotSelected)
|
||||||
{
|
{
|
||||||
// Create layout
|
// Create layout
|
||||||
auto *layout = new QHBoxLayout(this);
|
auto *layout = new QHBoxLayout(this);
|
||||||
|
|
@ -48,36 +48,58 @@ QSize DeckPreviewTagDisplayWidget::sizeHint() const
|
||||||
|
|
||||||
void DeckPreviewTagDisplayWidget::mousePressEvent(QMouseEvent *event)
|
void DeckPreviewTagDisplayWidget::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (event->button() == Qt::LeftButton) {
|
switch (event->button()) {
|
||||||
setSelected(!isSelected);
|
case Qt::LeftButton:
|
||||||
emit tagClicked();
|
setState(TagState::Selected);
|
||||||
|
break;
|
||||||
|
case Qt::RightButton:
|
||||||
|
setState(TagState::Excluded);
|
||||||
|
break;
|
||||||
|
case Qt::MiddleButton:
|
||||||
|
setState(TagState::NotSelected);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
QWidget::mousePressEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeckPreviewTagDisplayWidget::setSelected(bool selected)
|
emit tagClicked();
|
||||||
{
|
QWidget::mousePressEvent(event);
|
||||||
isSelected = selected;
|
|
||||||
update(); // Trigger a repaint
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckPreviewTagDisplayWidget::paintEvent(QPaintEvent *event)
|
void DeckPreviewTagDisplayWidget::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
|
|
||||||
// Set background color
|
QColor backgroundColor;
|
||||||
QColor backgroundColor = isSelected ? QColor(173, 216, 230) : Qt::white;
|
QColor borderColor;
|
||||||
|
int borderWidth;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case TagState::Selected:
|
||||||
|
backgroundColor = QColor(173, 216, 230); // Light blue
|
||||||
|
borderColor = Qt::blue;
|
||||||
|
borderWidth = 2;
|
||||||
|
break;
|
||||||
|
case TagState::Excluded:
|
||||||
|
backgroundColor = QColor(255, 182, 193); // Light red/pink
|
||||||
|
borderColor = Qt::red;
|
||||||
|
borderWidth = 2;
|
||||||
|
break;
|
||||||
|
case TagState::NotSelected:
|
||||||
|
default:
|
||||||
|
backgroundColor = Qt::white;
|
||||||
|
borderColor = Qt::gray;
|
||||||
|
borderWidth = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
painter.setBrush(backgroundColor);
|
painter.setBrush(backgroundColor);
|
||||||
painter.setPen(Qt::NoPen);
|
painter.setPen(Qt::NoPen);
|
||||||
|
|
||||||
// Draw background
|
|
||||||
painter.drawRect(rect());
|
painter.drawRect(rect());
|
||||||
|
|
||||||
// Draw border
|
QPen borderPen(borderColor, borderWidth);
|
||||||
QColor borderColor = isSelected ? Qt::blue : Qt::gray;
|
|
||||||
QPen borderPen(borderColor, isSelected ? 2 : 1);
|
|
||||||
painter.setPen(borderPen);
|
painter.setPen(borderPen);
|
||||||
painter.drawRect(rect().adjusted(0, 0, -1, -1)); // Adjust for pen width
|
painter.drawRect(rect().adjusted(0, 0, -1, -1));
|
||||||
|
|
||||||
// Calculate font size based on widget height
|
// Calculate font size based on widget height
|
||||||
QFont font = painter.font();
|
QFont font = painter.font();
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,13 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
enum class TagState
|
||||||
|
{
|
||||||
|
NotSelected,
|
||||||
|
Selected,
|
||||||
|
Excluded
|
||||||
|
};
|
||||||
|
|
||||||
class DeckPreviewTagDisplayWidget : public QWidget
|
class DeckPreviewTagDisplayWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -22,16 +29,16 @@ public:
|
||||||
{
|
{
|
||||||
return tagName;
|
return tagName;
|
||||||
}
|
}
|
||||||
bool getSelected() const
|
TagState getState() const
|
||||||
{
|
{
|
||||||
return isSelected;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void setState(const TagState newState)
|
||||||
* @brief Sets the selected state of the tag.
|
{
|
||||||
* @param selected True if the tag is selected, false otherwise.
|
state = newState;
|
||||||
*/
|
update();
|
||||||
void setSelected(bool selected);
|
};
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
|
|
@ -61,7 +68,7 @@ private:
|
||||||
QLabel *tagLabel; ///< Label for displaying the tag name.
|
QLabel *tagLabel; ///< Label for displaying the tag name.
|
||||||
QPushButton *closeButton; ///< Button to close/remove the tag.
|
QPushButton *closeButton; ///< Button to close/remove the tag.
|
||||||
QString tagName; ///< The name of the tag.
|
QString tagName; ///< The name of the tag.
|
||||||
bool isSelected; ///< Indicates whether the tag is selected.
|
TagState state; ///< Indicates whether the tag is unselected, selected, or excluded.
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DECK_PREVIEW_TAG_DISPLAY_WIDGET_H
|
#endif // DECK_PREVIEW_TAG_DISPLAY_WIDGET_H
|
||||||
|
|
|
||||||
|
|
@ -33,32 +33,42 @@ void VisualDeckStorageTagFilterWidget::showEvent(QShowEvent *event)
|
||||||
|
|
||||||
void VisualDeckStorageTagFilterWidget::filterDecksBySelectedTags(const QList<DeckPreviewWidget *> &deckPreviews) const
|
void VisualDeckStorageTagFilterWidget::filterDecksBySelectedTags(const QList<DeckPreviewWidget *> &deckPreviews) const
|
||||||
{
|
{
|
||||||
// Collect selected tags from DeckPreviewTagDisplayWidget
|
|
||||||
QStringList selectedTags;
|
QStringList selectedTags;
|
||||||
|
QStringList excludedTags;
|
||||||
|
|
||||||
|
// Collect selected and excluded tags
|
||||||
for (DeckPreviewTagDisplayWidget *tagWidget : findChildren<DeckPreviewTagDisplayWidget *>()) {
|
for (DeckPreviewTagDisplayWidget *tagWidget : findChildren<DeckPreviewTagDisplayWidget *>()) {
|
||||||
if (tagWidget->getSelected()) {
|
switch (tagWidget->getState()) {
|
||||||
selectedTags.append(tagWidget->getTagName());
|
case TagState::Selected:
|
||||||
|
selectedTags.append(tagWidget->getTagName());
|
||||||
|
break;
|
||||||
|
case TagState::Excluded:
|
||||||
|
excludedTags.append(tagWidget->getTagName());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no tags are selected, set all decks as visible
|
// If no tags are selected or excluded, show all
|
||||||
if (selectedTags.isEmpty()) {
|
if (selectedTags.isEmpty() && excludedTags.isEmpty()) {
|
||||||
for (DeckPreviewWidget *deckPreview : deckPreviews) {
|
for (DeckPreviewWidget *deckPreview : deckPreviews) {
|
||||||
deckPreview->filteredByTags = false;
|
deckPreview->filteredByTags = false;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter DeckPreviewWidgets that contain all of the selected tags
|
|
||||||
QList<DeckPreviewWidget *> filteredDecks;
|
|
||||||
for (DeckPreviewWidget *deckPreview : deckPreviews) {
|
for (DeckPreviewWidget *deckPreview : deckPreviews) {
|
||||||
QStringList deckTags = deckPreview->deckLoader->getTags();
|
QStringList deckTags = deckPreview->deckLoader->getTags();
|
||||||
|
|
||||||
// Check if all selectedTags are in deckTags
|
bool hasAllSelected = std::all_of(selectedTags.begin(), selectedTags.end(),
|
||||||
bool allTagsPresent = std::all_of(selectedTags.begin(), selectedTags.end(),
|
|
||||||
[&deckTags](const QString &tag) { return deckTags.contains(tag); });
|
[&deckTags](const QString &tag) { return deckTags.contains(tag); });
|
||||||
|
|
||||||
deckPreview->filteredByTags = !allTagsPresent;
|
bool hasAnyExcluded = std::any_of(excludedTags.begin(), excludedTags.end(),
|
||||||
|
[&deckTags](const QString &tag) { return deckTags.contains(tag); });
|
||||||
|
|
||||||
|
// Filter out if any excluded tag is present or if any selected tag is missing
|
||||||
|
deckPreview->filteredByTags = !(hasAllSelected && !hasAnyExcluded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,13 +82,15 @@ void VisualDeckStorageTagFilterWidget::refreshTags()
|
||||||
|
|
||||||
void VisualDeckStorageTagFilterWidget::removeTagsNotInList(const QSet<QString> &tags)
|
void VisualDeckStorageTagFilterWidget::removeTagsNotInList(const QSet<QString> &tags)
|
||||||
{
|
{
|
||||||
// Iterate through all DeckPreviewTagDisplayWidgets
|
auto *flowWidget = findChild<FlowWidget *>();
|
||||||
|
|
||||||
for (DeckPreviewTagDisplayWidget *tagWidget : findChildren<DeckPreviewTagDisplayWidget *>()) {
|
for (DeckPreviewTagDisplayWidget *tagWidget : findChildren<DeckPreviewTagDisplayWidget *>()) {
|
||||||
// If the tag is not in the provided tags list, remove the widget
|
const QString &tagName = tagWidget->getTagName();
|
||||||
if (!tags.contains(tagWidget->getTagName())) {
|
|
||||||
auto *flowWidget = findChild<FlowWidget *>();
|
// Keep the tag widget if it is either selected or excluded
|
||||||
|
if (!tags.contains(tagName) && tagWidget->getState() == TagState::NotSelected) {
|
||||||
flowWidget->removeWidget(tagWidget);
|
flowWidget->removeWidget(tagWidget);
|
||||||
tagWidget->deleteLater(); // Safely delete the widget
|
tagWidget->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue