diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt
index 45ad94f34..770bf4f22 100644
--- a/cockatrice/CMakeLists.txt
+++ b/cockatrice/CMakeLists.txt
@@ -113,6 +113,8 @@ set(cockatrice_SOURCES
src/client/ui/widgets/printing_selector/printing_selector_view_options_toolbar_widget.cpp
src/client/ui/widgets/printing_selector/printing_selector_view_options_widget.cpp
src/client/ui/widgets/printing_selector/set_name_and_collectors_number_display_widget.cpp
+ src/client/ui/widgets/quick_settings/settings_button_widget.cpp
+ src/client/ui/widgets/quick_settings/settings_popup_widget.cpp
src/client/network/release_channel.cpp
src/client/network/client_update_checker.cpp
src/server/remote/remote_client.cpp
diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc
index 32dbdd61c..5ad485618 100644
--- a/cockatrice/cockatrice.qrc
+++ b/cockatrice/cockatrice.qrc
@@ -13,6 +13,7 @@
resources/icons/arrow_top_green.svg
resources/icons/arrow_up_green.svg
resources/icons/clearsearch.svg
+ resources/icons/cogwheel.svg
resources/icons/conceded.svg
resources/icons/decrement.svg
resources/icons/delete.svg
diff --git a/cockatrice/src/client/ui/widgets/quick_settings/settings_button_widget.cpp b/cockatrice/src/client/ui/widgets/quick_settings/settings_button_widget.cpp
new file mode 100644
index 000000000..73484e4f4
--- /dev/null
+++ b/cockatrice/src/client/ui/widgets/quick_settings/settings_button_widget.cpp
@@ -0,0 +1,73 @@
+#include "settings_button_widget.h"
+
+#include
+#include
+#include
+#include
+
+SettingsButtonWidget::SettingsButtonWidget(QWidget *parent)
+ : QWidget(parent), button(new QToolButton(this)), popup(new SettingsPopupWidget(this))
+{
+
+ button->setIcon(QPixmap("theme:icons/cogwheel"));
+ button->setCheckable(true);
+ button->setFixedSize(32, 32);
+ connect(button, &QToolButton::clicked, this, &SettingsButtonWidget::togglePopup);
+ connect(popup, &SettingsPopupWidget::aboutToClose, this, &SettingsButtonWidget::onPopupClosed);
+
+ layout = new QHBoxLayout(this);
+ layout->addWidget(button);
+ layout->setContentsMargins(0, 0, 0, 0);
+ setLayout(layout);
+}
+
+void SettingsButtonWidget::addSettingsWidget(QWidget *toAdd) const
+{
+ popup->addSettingsWidget(toAdd);
+}
+
+void SettingsButtonWidget::togglePopup()
+{
+ if (popup->isVisible()) {
+ popup->close();
+ } else {
+ // Get button position
+ QPoint buttonGlobalPos = button->mapToGlobal(QPoint(0, button->height()));
+ QSize popupSize = popup->size();
+
+ // Get screen geometry
+ QScreen *screen = QApplication::screenAt(buttonGlobalPos);
+ QRect screenGeom = screen ? screen->availableGeometry() : QApplication::primaryScreen()->availableGeometry();
+
+ int x = buttonGlobalPos.x();
+ int y = buttonGlobalPos.y();
+
+ // Adjust X position if popup overflows the right side of the screen
+ if (x + popupSize.width() > screenGeom.right()) {
+ x = buttonGlobalPos.x() - popupSize.width() + button->width(); // Move left
+ }
+
+ // Adjust Y position if popup overflows the bottom of the screen
+ if (y + popupSize.height() > screenGeom.bottom()) {
+ y = buttonGlobalPos.y() - popupSize.height() - button->height(); // Move up
+ }
+
+ popup->move(x, y);
+ popup->show();
+ popup->setFocus();
+ button->setChecked(true); // Ensure button is checked when popup is visible
+ }
+}
+
+void SettingsButtonWidget::onPopupClosed() const
+{
+ button->setChecked(false); // Ensure button unchecks when popup closes
+}
+
+void SettingsButtonWidget::mousePressEvent(QMouseEvent *event)
+{
+ if (popup->isVisible() && !popup->geometry().contains(event->globalPosition().toPoint())) {
+ popup->close();
+ }
+ QWidget::mousePressEvent(event);
+}
diff --git a/cockatrice/src/client/ui/widgets/quick_settings/settings_button_widget.h b/cockatrice/src/client/ui/widgets/quick_settings/settings_button_widget.h
new file mode 100644
index 000000000..7e07f573c
--- /dev/null
+++ b/cockatrice/src/client/ui/widgets/quick_settings/settings_button_widget.h
@@ -0,0 +1,30 @@
+#ifndef SETTINGS_BUTTON_WIDGET_H
+#define SETTINGS_BUTTON_WIDGET_H
+
+#include "settings_popup_widget.h"
+
+#include
+#include
+
+class SettingsButtonWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit SettingsButtonWidget(QWidget *parent = nullptr);
+ void addSettingsWidget(QWidget *toAdd) const;
+
+protected:
+ void mousePressEvent(QMouseEvent *event) override;
+
+private slots:
+ void togglePopup();
+ void onPopupClosed() const;
+
+private:
+ QHBoxLayout *layout;
+ QToolButton *button;
+ SettingsPopupWidget *popup;
+};
+
+#endif // SETTINGS_BUTTON_WIDGET_H
diff --git a/cockatrice/src/client/ui/widgets/quick_settings/settings_popup_widget.cpp b/cockatrice/src/client/ui/widgets/quick_settings/settings_popup_widget.cpp
new file mode 100644
index 000000000..a201ed4f1
--- /dev/null
+++ b/cockatrice/src/client/ui/widgets/quick_settings/settings_popup_widget.cpp
@@ -0,0 +1,25 @@
+#include "settings_popup_widget.h"
+
+#include
+
+SettingsPopupWidget::SettingsPopupWidget(QWidget *parent) : QWidget(parent, Qt::Popup | Qt::FramelessWindowHint)
+{
+ layout = new QVBoxLayout(this);
+}
+
+void SettingsPopupWidget::addSettingsWidget(QWidget *toAdd) const
+{
+ layout->addWidget(toAdd);
+}
+
+void SettingsPopupWidget::focusOutEvent(QFocusEvent *event)
+{
+ close();
+ QWidget::focusOutEvent(event);
+}
+
+void SettingsPopupWidget::closeEvent(QCloseEvent *event)
+{
+ emit aboutToClose();
+ QWidget::closeEvent(event);
+}
diff --git a/cockatrice/src/client/ui/widgets/quick_settings/settings_popup_widget.h b/cockatrice/src/client/ui/widgets/quick_settings/settings_popup_widget.h
new file mode 100644
index 000000000..3fa439c50
--- /dev/null
+++ b/cockatrice/src/client/ui/widgets/quick_settings/settings_popup_widget.h
@@ -0,0 +1,26 @@
+#ifndef SETTINGS_POPUP_WIDGET_H
+#define SETTINGS_POPUP_WIDGET_H
+
+#include
+#include
+#include
+
+class SettingsPopupWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit SettingsPopupWidget(QWidget *parent = nullptr);
+ void addSettingsWidget(QWidget *toAdd) const;
+
+signals:
+ void aboutToClose();
+
+protected:
+ void focusOutEvent(QFocusEvent *event) override;
+ void closeEvent(QCloseEvent *event) override;
+
+ QVBoxLayout *layout;
+};
+
+#endif // SETTINGSPOPUP_H
diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp
index ecd4f4a79..af9badccf 100644
--- a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp
+++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.cpp
@@ -1,6 +1,7 @@
#include "deck_preview_widget.h"
#include "../../../../../game/cards/card_database_manager.h"
+#include "../../../../../settings/cache_settings.h"
#include "../../cards/deck_preview_card_picture_widget.h"
#include "deck_preview_deck_tags_display_widget.h"
@@ -51,6 +52,7 @@ void DeckPreviewWidget::initializeUi(const bool deckLoadSuccess)
colorIdentityWidget = new DeckPreviewColorIdentityWidget(this, getColorIdentity());
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckLoader);
+ updateTagsVisibility(SettingsCache::instance().getVisualDeckStorageShowTags());
layout->addWidget(colorIdentityWidget);
layout->addWidget(deckTagsDisplayWidget);
@@ -72,6 +74,15 @@ bool DeckPreviewWidget::checkVisibility() const
return true;
}
+void DeckPreviewWidget::updateTagsVisibility(bool visible)
+{
+ if (visible) {
+ deckTagsDisplayWidget->setVisible(true);
+ } else {
+ deckTagsDisplayWidget->setHidden(true);
+ }
+}
+
QString DeckPreviewWidget::getColorIdentity()
{
QStringList cardList = deckLoader->getCardList();
diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h
index 8be7d07ac..af5dd04b7 100644
--- a/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h
+++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_widget.h
@@ -45,6 +45,7 @@ public slots:
void imageDoubleClickedEvent(QMouseEvent *event, DeckPreviewCardPictureWidget *instance);
void initializeUi(bool deckLoadSuccess);
void updateVisibility();
+ void updateTagsVisibility(bool visible);
};
#endif // DECK_PREVIEW_WIDGET_H
diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp
index 84981e071..90097e75d 100644
--- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp
+++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.cpp
@@ -39,6 +39,8 @@ VisualDeckStorageFolderDisplayWidget::VisualDeckStorageFolderDisplayWidget(
&VisualDeckStorageFolderDisplayWidget::updateVisibility);
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::searchFilterUpdated, this,
&VisualDeckStorageFolderDisplayWidget::updateVisibility);
+ connect(visualDeckStorageWidget, &VisualDeckStorageWidget::updateTagsVisibility, this,
+ &VisualDeckStorageFolderDisplayWidget::updateTagVisibility);
createWidgetsForFiles();
createWidgetsForFolders();
@@ -93,6 +95,8 @@ void VisualDeckStorageFolderDisplayWidget::createWidgetsForFiles()
&VisualDeckStorageWidget::deckPreviewDoubleClickedEvent);
connect(visualDeckStorageWidget->cardSizeWidget->getSlider(), &QSlider::valueChanged,
display->bannerCardDisplayWidget, &CardInfoPictureWidget::setScaleFactor);
+ connect(this, &VisualDeckStorageFolderDisplayWidget::tagsVisibilityChanged, display,
+ &DeckPreviewWidget::updateTagsVisibility);
display->bannerCardDisplayWidget->setScaleFactor(visualDeckStorageWidget->cardSizeWidget->getSlider()->value());
allDecks.append(display);
}
@@ -161,6 +165,8 @@ void VisualDeckStorageFolderDisplayWidget::createWidgetsForFolders()
for (const QString &dir : getAllSubFolders(filePath)) {
auto *display = new VisualDeckStorageFolderDisplayWidget(this, visualDeckStorageWidget, dir, true, showFolders);
+ connect(this, &VisualDeckStorageFolderDisplayWidget::tagsVisibilityChanged, display,
+ &VisualDeckStorageFolderDisplayWidget::updateTagVisibility);
containerLayout->addWidget(display);
}
}
@@ -180,6 +186,11 @@ void VisualDeckStorageFolderDisplayWidget::updateShowFolders(bool enabled)
header->setHidden(!showFolders);
}
+void VisualDeckStorageFolderDisplayWidget::updateTagVisibility(bool visible)
+{
+ emit tagsVisibilityChanged(visible);
+}
+
/**
* Recursively gets all DeckPreviewWidgets in this folder and its subfolders
*/
diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.h
index d149e4d27..0f3500315 100644
--- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.h
+++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_folder_display_widget.h
@@ -27,10 +27,14 @@ public:
return flowWidget;
};
+signals:
+ void tagsVisibilityChanged(bool visible);
+
public slots:
void updateVisibility();
bool checkVisibility();
void updateShowFolders(bool enabled);
+ void updateTagVisibility(bool visible);
private:
bool showFolders;
diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp
index 598bcd03f..5482dd3d8 100644
--- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp
+++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.cpp
@@ -2,6 +2,7 @@
#include "../../../../game/cards/card_database_manager.h"
#include "../../../../settings/cache_settings.h"
+#include "../quick_settings/settings_button_widget.h"
#include "deck_preview/deck_preview_widget.h"
#include "visual_deck_storage_folder_display_widget.h"
#include "visual_deck_storage_search_widget.h"
@@ -38,13 +39,24 @@ VisualDeckStorageWidget::VisualDeckStorageWidget(QWidget *parent) : QWidget(pare
connect(showFoldersCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
&SettingsCache::setVisualDeckStorageShowFolders);
+ tagsVisibilityCheckBox = new QCheckBox(this);
+ tagsVisibilityCheckBox->setChecked(SettingsCache::instance().getVisualDeckStorageShowTags());
+ connect(tagsVisibilityCheckBox, &QCheckBox::QT_STATE_CHANGED, this, &VisualDeckStorageWidget::updateTagsVisibility);
+ connect(tagsVisibilityCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
+ &SettingsCache::setVisualDeckStorageShowTags);
+
+ quickSettingsWidget = new SettingsButtonWidget(this);
+ quickSettingsWidget->addSettingsWidget(showFoldersCheckBox);
+ quickSettingsWidget->addSettingsWidget(tagsVisibilityCheckBox);
+
searchAndSortLayout->addWidget(deckPreviewColorIdentityFilterWidget);
searchAndSortLayout->addWidget(sortWidget);
searchAndSortLayout->addWidget(searchWidget);
- searchAndSortLayout->addWidget(showFoldersCheckBox);
+ searchAndSortLayout->addWidget(quickSettingsWidget);
// tag filter box
tagFilterWidget = new VisualDeckStorageTagFilterWidget(this);
+ updateTagsVisibility(SettingsCache::instance().getVisualDeckStorageShowTags());
// card size slider
cardSizeWidget = new CardSizeWidget(this, nullptr, SettingsCache::instance().getVisualDeckStorageCardSize());
@@ -101,6 +113,7 @@ void VisualDeckStorageWidget::retranslateUi()
databaseLoadIndicator->setText(tr("Loading database ..."));
showFoldersCheckBox->setText(tr("Show Folders"));
+ tagsVisibilityCheckBox->setText(tr("Show Tags"));
}
void VisualDeckStorageWidget::deckPreviewClickedEvent(QMouseEvent *event, DeckPreviewWidget *instance)
@@ -118,6 +131,8 @@ void VisualDeckStorageWidget::createRootFolderWidget()
{
folderWidget = new VisualDeckStorageFolderDisplayWidget(this, this, SettingsCache::instance().getDeckPath(), false,
showFoldersCheckBox->isChecked());
+ connect(this, &VisualDeckStorageWidget::tagsVisibilityChanged, folderWidget,
+ &VisualDeckStorageFolderDisplayWidget::updateTagVisibility);
scrollArea->setWidget(folderWidget);
scrollArea->widget()->setMaximumWidth(scrollArea->viewport()->width());
@@ -167,3 +182,14 @@ void VisualDeckStorageWidget::updateSearchFilter()
}
emit searchFilterUpdated();
}
+
+void VisualDeckStorageWidget::updateTagsVisibility(const bool visible)
+{
+ if (visible) {
+ tagFilterWidget->setVisible(true);
+
+ } else {
+ tagFilterWidget->setHidden(true);
+ }
+ emit tagsVisibilityChanged(visible);
+}
diff --git a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.h b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.h
index 01b4f53fa..487ec5148 100644
--- a/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.h
+++ b/cockatrice/src/client/ui/widgets/visual_deck_storage/visual_deck_storage_widget.h
@@ -4,6 +4,7 @@
#include "../../../../deck/deck_list_model.h"
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
#include "../cards/card_size_widget.h"
+#include "../quick_settings/settings_button_widget.h"
#include "deck_preview/deck_preview_color_identity_filter_widget.h"
#include "deck_preview/deck_preview_widget.h"
#include "visual_deck_storage_folder_display_widget.h"
@@ -24,8 +25,8 @@ class VisualDeckStorageWidget final : public QWidget
Q_OBJECT
public:
explicit VisualDeckStorageWidget(QWidget *parent);
-
void retranslateUi();
+
CardSizeWidget *cardSizeWidget;
VisualDeckStorageTagFilterWidget *tagFilterWidget;
@@ -37,6 +38,7 @@ public slots:
void updateTagFilter();
void updateColorFilter();
void updateSearchFilter();
+ void updateTagsVisibility(bool visible);
void updateSortOrder();
void resizeEvent(QResizeEvent *event) override;
void showEvent(QShowEvent *event) override;
@@ -49,6 +51,7 @@ signals:
void tagFilterUpdated();
void colorFilterUpdated();
void searchFilterUpdated();
+ void tagsVisibilityChanged(bool visible);
private:
QVBoxLayout *layout;
@@ -58,9 +61,9 @@ private:
VisualDeckStorageSortWidget *sortWidget;
VisualDeckStorageSearchWidget *searchWidget;
DeckPreviewColorIdentityFilterWidget *deckPreviewColorIdentityFilterWidget;
-
+ SettingsButtonWidget *quickSettingsWidget;
QCheckBox *showFoldersCheckBox;
-
+ QCheckBox *tagsVisibilityCheckBox;
QScrollArea *scrollArea;
VisualDeckStorageFolderDisplayWidget *folderWidget;
};
diff --git a/cockatrice/src/settings/cache_settings.cpp b/cockatrice/src/settings/cache_settings.cpp
index bbe228c52..c986d9a83 100644
--- a/cockatrice/src/settings/cache_settings.cpp
+++ b/cockatrice/src/settings/cache_settings.cpp
@@ -267,6 +267,7 @@ SettingsCache::SettingsCache()
visualDeckStorageCardSize = settings->value("cards/visualdeckstoragecardsize", 100).toInt();
visualDeckStorageSortingOrder = settings->value("interface/visualdeckstoragesortingorder", 0).toInt();
visualDeckStorageShowFolders = settings->value("interface/visualdeckstorageshowfolders", true).toBool();
+ visualDeckStorageShowTags = settings->value("interface/visualdeckstorageshowtags", true).toBool();
visualDeckStorageDrawUnusedColorIdentities =
settings->value("interface/visualdeckstoragedrawunusedcoloridentities", true).toBool();
visualDeckStorageUnusedColorIdentitiesOpacity =
@@ -685,6 +686,12 @@ void SettingsCache::setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T value)
settings->setValue("interface/visualdeckstorageshowfolders", visualDeckStorageShowFolders);
}
+void SettingsCache::setVisualDeckStorageShowTags(QT_STATE_CHANGED_T _showTags)
+{
+ visualDeckStorageShowTags = _showTags;
+ settings->setValue("interface/visualdeckstorageshowtags", visualDeckStorageShowTags);
+}
+
void SettingsCache::setVisualDeckStorageCardSize(int _visualDeckStorageCardSize)
{
visualDeckStorageCardSize = _visualDeckStorageCardSize;
diff --git a/cockatrice/src/settings/cache_settings.h b/cockatrice/src/settings/cache_settings.h
index b2800e9f5..b02968738 100644
--- a/cockatrice/src/settings/cache_settings.h
+++ b/cockatrice/src/settings/cache_settings.h
@@ -132,6 +132,7 @@ private:
bool printingSelectorNavigationButtonsVisible;
int visualDeckStorageSortingOrder;
bool visualDeckStorageShowFolders;
+ bool visualDeckStorageShowTags;
int visualDeckStorageCardSize;
bool visualDeckStorageDrawUnusedColorIdentities;
int visualDeckStorageUnusedColorIdentitiesOpacity;
@@ -421,6 +422,10 @@ public:
{
return visualDeckStorageShowFolders;
}
+ bool getVisualDeckStorageShowTags() const
+ {
+ return visualDeckStorageShowTags;
+ }
int getVisualDeckStorageCardSize() const
{
return visualDeckStorageCardSize;
@@ -767,6 +772,7 @@ public slots:
void setPrintingSelectorNavigationButtonsVisible(QT_STATE_CHANGED_T _navigationButtonsVisible);
void setVisualDeckStorageSortingOrder(int _visualDeckStorageSortingOrder);
void setVisualDeckStorageShowFolders(QT_STATE_CHANGED_T value);
+ void setVisualDeckStorageShowTags(QT_STATE_CHANGED_T _showTags);
void setVisualDeckStorageCardSize(int _visualDeckStorageCardSize);
void setVisualDeckStorageDrawUnusedColorIdentities(QT_STATE_CHANGED_T _visualDeckStorageDrawUnusedColorIdentities);
void setVisualDeckStorageUnusedColorIdentitiesOpacity(int _visualDeckStorageUnusedColorIdentitiesOpacity);