mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2025-12-05 20:39:59 -08: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:
@@ -6,7 +6,7 @@
|
||||
#include <QPainter>
|
||||
|
||||
DeckPreviewTagDisplayWidget::DeckPreviewTagDisplayWidget(QWidget *parent, const QString &_tagName)
|
||||
: QWidget(parent), tagName(_tagName), isSelected(false)
|
||||
: QWidget(parent), tagName(_tagName), state(TagState::NotSelected)
|
||||
{
|
||||
// Create layout
|
||||
auto *layout = new QHBoxLayout(this);
|
||||
@@ -48,36 +48,58 @@ QSize DeckPreviewTagDisplayWidget::sizeHint() const
|
||||
|
||||
void DeckPreviewTagDisplayWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
setSelected(!isSelected);
|
||||
emit tagClicked();
|
||||
switch (event->button()) {
|
||||
case Qt::LeftButton:
|
||||
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)
|
||||
{
|
||||
isSelected = selected;
|
||||
update(); // Trigger a repaint
|
||||
emit tagClicked();
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void DeckPreviewTagDisplayWidget::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
// Set background color
|
||||
QColor backgroundColor = isSelected ? QColor(173, 216, 230) : Qt::white;
|
||||
QColor backgroundColor;
|
||||
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.setPen(Qt::NoPen);
|
||||
|
||||
// Draw background
|
||||
painter.drawRect(rect());
|
||||
|
||||
// Draw border
|
||||
QColor borderColor = isSelected ? Qt::blue : Qt::gray;
|
||||
QPen borderPen(borderColor, isSelected ? 2 : 1);
|
||||
QPen borderPen(borderColor, borderWidth);
|
||||
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
|
||||
QFont font = painter.font();
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
|
||||
enum class TagState
|
||||
{
|
||||
NotSelected,
|
||||
Selected,
|
||||
Excluded
|
||||
};
|
||||
|
||||
class DeckPreviewTagDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -22,16 +29,16 @@ public:
|
||||
{
|
||||
return tagName;
|
||||
}
|
||||
bool getSelected() const
|
||||
TagState getState() const
|
||||
{
|
||||
return isSelected;
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the selected state of the tag.
|
||||
* @param selected True if the tag is selected, false otherwise.
|
||||
*/
|
||||
void setSelected(bool selected);
|
||||
void setState(const TagState newState)
|
||||
{
|
||||
state = newState;
|
||||
update();
|
||||
};
|
||||
|
||||
signals:
|
||||
/**
|
||||
@@ -61,7 +68,7 @@ private:
|
||||
QLabel *tagLabel; ///< Label for displaying the tag name.
|
||||
QPushButton *closeButton; ///< Button to close/remove 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
|
||||
|
||||
@@ -33,32 +33,42 @@ void VisualDeckStorageTagFilterWidget::showEvent(QShowEvent *event)
|
||||
|
||||
void VisualDeckStorageTagFilterWidget::filterDecksBySelectedTags(const QList<DeckPreviewWidget *> &deckPreviews) const
|
||||
{
|
||||
// Collect selected tags from DeckPreviewTagDisplayWidget
|
||||
QStringList selectedTags;
|
||||
QStringList excludedTags;
|
||||
|
||||
// Collect selected and excluded tags
|
||||
for (DeckPreviewTagDisplayWidget *tagWidget : findChildren<DeckPreviewTagDisplayWidget *>()) {
|
||||
if (tagWidget->getSelected()) {
|
||||
selectedTags.append(tagWidget->getTagName());
|
||||
switch (tagWidget->getState()) {
|
||||
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 (selectedTags.isEmpty()) {
|
||||
// If no tags are selected or excluded, show all
|
||||
if (selectedTags.isEmpty() && excludedTags.isEmpty()) {
|
||||
for (DeckPreviewWidget *deckPreview : deckPreviews) {
|
||||
deckPreview->filteredByTags = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter DeckPreviewWidgets that contain all of the selected tags
|
||||
QList<DeckPreviewWidget *> filteredDecks;
|
||||
for (DeckPreviewWidget *deckPreview : deckPreviews) {
|
||||
QStringList deckTags = deckPreview->deckLoader->getTags();
|
||||
|
||||
// Check if all selectedTags are in deckTags
|
||||
bool allTagsPresent = std::all_of(selectedTags.begin(), selectedTags.end(),
|
||||
bool hasAllSelected = std::all_of(selectedTags.begin(), selectedTags.end(),
|
||||
[&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)
|
||||
{
|
||||
// Iterate through all DeckPreviewTagDisplayWidgets
|
||||
auto *flowWidget = findChild<FlowWidget *>();
|
||||
|
||||
for (DeckPreviewTagDisplayWidget *tagWidget : findChildren<DeckPreviewTagDisplayWidget *>()) {
|
||||
// If the tag is not in the provided tags list, remove the widget
|
||||
if (!tags.contains(tagWidget->getTagName())) {
|
||||
auto *flowWidget = findChild<FlowWidget *>();
|
||||
const QString &tagName = tagWidget->getTagName();
|
||||
|
||||
// Keep the tag widget if it is either selected or excluded
|
||||
if (!tags.contains(tagName) && tagWidget->getState() == TagState::NotSelected) {
|
||||
flowWidget->removeWidget(tagWidget);
|
||||
tagWidget->deleteLater(); // Safely delete the widget
|
||||
tagWidget->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user