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);