From 29f60c4a676d1bbd40895e56947eaef2c985fece Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Wed, 14 Jan 2026 14:41:54 +0100 Subject: [PATCH] [VDE] Placeholder image for deck view if deck is empty (#6516) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [VDE] A stab at things Took 14 minutes Took 10 minutes Took 5 minutes Took 4 minutes Took 41 seconds Took 10 minutes Took 3 minutes * [VDE] Use placeholder image for deck view if deck is empty. Took 15 minutes Took 9 seconds Took 5 seconds * Sort CMakeList correctly. Took 35 seconds Took 23 seconds * Visibility updates got lost in the rebase. Took 7 minutes * Same treatment for printing selector. Took 42 minutes * Actually add file. Took 4 minutes --------- Co-authored-by: Lukas BrĂ¼bach --- cockatrice/CMakeLists.txt | 5 ++- cockatrice/cockatrice.qrc | 2 + .../resources/backgrounds/card_triplet.svg | 31 ++++++++++++++ .../placeholder_printing_selector.svg | 28 +++++++++++++ .../printing_selector/printing_selector.cpp | 23 +++++++++- .../printing_selector/printing_selector.h | 2 + .../printing_selector_placeholder_widget.cpp | 42 +++++++++++++++++++ .../printing_selector_placeholder_widget.h | 23 ++++++++++ .../visual_deck_editor_placeholder_widget.cpp | 41 ++++++++++++++++++ .../visual_deck_editor_placeholder_widget.h | 22 ++++++++++ .../visual_deck_editor_widget.cpp | 25 ++++++++++- .../visual_deck_editor_widget.h | 3 ++ 12 files changed, 242 insertions(+), 5 deletions(-) create mode 100644 cockatrice/resources/backgrounds/card_triplet.svg create mode 100644 cockatrice/resources/backgrounds/placeholder_printing_selector.svg create mode 100644 cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.cpp create mode 100644 cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.h create mode 100644 cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.cpp create mode 100644 cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.h diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index fb57bf7e0..c6d962ffb 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -203,6 +203,7 @@ set(cockatrice_SOURCES src/interface/widgets/printing_selector/printing_selector.cpp src/interface/widgets/printing_selector/printing_selector_card_display_widget.cpp src/interface/widgets/printing_selector/printing_selector_card_overlay_widget.cpp + src/interface/widgets/printing_selector/printing_selector_placeholder_widget.cpp src/interface/widgets/printing_selector/printing_selector_card_search_widget.cpp src/interface/widgets/printing_selector/printing_selector_card_selection_widget.cpp src/interface/widgets/printing_selector/printing_selector_card_sorting_widget.cpp @@ -228,6 +229,7 @@ set(cockatrice_SOURCES src/interface/widgets/utility/sequence_edit.cpp src/interface/widgets/visual_database_display/visual_database_display_color_filter_widget.cpp src/interface/widgets/visual_database_display/visual_database_display_filter_save_load_widget.cpp + src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.cpp src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.cpp src/interface/widgets/visual_database_display/visual_database_display_main_type_filter_widget.cpp src/interface/widgets/visual_database_display/visual_database_display_name_filter_widget.cpp @@ -236,6 +238,7 @@ set(cockatrice_SOURCES src/interface/widgets/visual_database_display/visual_database_display_widget.cpp src/interface/widgets/visual_database_display/visual_database_filter_display_widget.cpp src/interface/widgets/visual_deck_editor/visual_deck_display_options_widget.cpp + src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.cpp src/interface/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.cpp src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp src/interface/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_filter_widget.cpp @@ -317,8 +320,6 @@ set(cockatrice_SOURCES src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_bracket_navigation_widget.h src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.cpp src/interface/widgets/tabs/api/edhrec/display/commander/edhrec_commander_api_response_budget_navigation_widget.h - src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.cpp - src/interface/widgets/visual_database_display/visual_database_display_filter_toolbar_widget.h ) add_subdirectory(sounds) diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc index 6e90d342d..f087bfe66 100644 --- a/cockatrice/cockatrice.qrc +++ b/cockatrice/cockatrice.qrc @@ -60,6 +60,8 @@ resources/icons/mana/W.svg resources/backgrounds/home.png + resources/backgrounds/card_triplet.svg + resources/backgrounds/placeholder_printing_selector.svg resources/config/general.svg resources/config/appearance.svg diff --git a/cockatrice/resources/backgrounds/card_triplet.svg b/cockatrice/resources/backgrounds/card_triplet.svg new file mode 100644 index 000000000..3749c678b --- /dev/null +++ b/cockatrice/resources/backgrounds/card_triplet.svg @@ -0,0 +1,31 @@ + + + + + + + + + + diff --git a/cockatrice/resources/backgrounds/placeholder_printing_selector.svg b/cockatrice/resources/backgrounds/placeholder_printing_selector.svg new file mode 100644 index 000000000..44f1e534c --- /dev/null +++ b/cockatrice/resources/backgrounds/placeholder_printing_selector.svg @@ -0,0 +1,28 @@ + + + diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp index 506395789..2f18c7116 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector.cpp @@ -8,6 +8,7 @@ #include "printing_selector_card_search_widget.h" #include "printing_selector_card_selection_widget.h" #include "printing_selector_card_sorting_widget.h" +#include "printing_selector_placeholder_widget.h" #include #include @@ -34,6 +35,8 @@ PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deck flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded); + placeholderWidget = new PrintingSelectorPlaceholderWidget(this); + sortToolBar = new PrintingSelectorCardSortingWidget(this); sortToolBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); @@ -70,8 +73,13 @@ PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deck layout->addWidget(sortAndOptionsContainer); + layout->addWidget(placeholderWidget); layout->addWidget(flowWidget); + // Initially show placeholder, hide flowWidget + placeholderWidget->setVisible(true); + flowWidget->setVisible(false); + cardSelectionBar = new PrintingSelectorCardSelectionWidget(this, deckStateManager); cardSelectionBar->setVisible(SettingsCache::instance().getPrintingSelectorNavigationButtonsVisible()); layout->addWidget(cardSelectionBar); @@ -139,7 +147,16 @@ void PrintingSelector::updateDisplay() widgetLoadingBufferTimer->deleteLater(); widgetLoadingBufferTimer = new QTimer(this); flowWidget->clearLayout(); - if (selectedCard != nullptr) { + + if (selectedCard.isNull()) { + // Show placeholder, hide flowWidget + placeholderWidget->setVisible(true); + flowWidget->setVisible(false); + setWindowTitle(tr("Printing Selector")); + } else { + // Hide placeholder, show flowWidget + placeholderWidget->setVisible(false); + flowWidget->setVisible(true); setWindowTitle(selectedCard->getName()); } getAllSetsForCurrentCard(); @@ -153,6 +170,8 @@ void PrintingSelector::updateDisplay() void PrintingSelector::setCard(const CardInfoPtr &newCard) { if (newCard.isNull()) { + selectedCard = newCard; + updateDisplay(); return; } @@ -229,4 +248,4 @@ void PrintingSelector::getAllSetsForCurrentCard() void PrintingSelector::toggleVisibilityNavigationButtons(bool _state) { cardSelectionBar->setVisible(_state); -} +} \ No newline at end of file diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector.h index e48eb2f2c..f7844504d 100644 --- a/cockatrice/src/interface/widgets/printing_selector/printing_selector.h +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector.h @@ -10,6 +10,7 @@ #include "../cards/card_size_widget.h" #include "../general/layout_containers/flow_widget.h" #include "../quick_settings/settings_button_widget.h" +#include "printing_selector_placeholder_widget.h" #include #include @@ -70,6 +71,7 @@ private: QCheckBox *navigationCheckBox; PrintingSelectorCardSortingWidget *sortToolBar; PrintingSelectorCardSearchWidget *searchBar; + PrintingSelectorPlaceholderWidget *placeholderWidget; FlowWidget *flowWidget; CardSizeWidget *cardSizeWidget; PrintingSelectorCardSelectionWidget *cardSelectionBar; diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.cpp b/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.cpp new file mode 100644 index 000000000..aee34bccd --- /dev/null +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.cpp @@ -0,0 +1,42 @@ +#include "printing_selector_placeholder_widget.h" + +PrintingSelectorPlaceholderWidget::PrintingSelectorPlaceholderWidget(QWidget *parent) : QWidget(parent) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + mainLayout = new QVBoxLayout(this); + mainLayout->setAlignment(Qt::AlignCenter); + setLayout(mainLayout); + + // Image label with the background image + imageLabel = new QLabel(this); + imageLabel->setAlignment(Qt::AlignCenter); + imageLabel->setStyleSheet(R"( + QLabel { + background-image: url(theme:backgrounds/placeholder_printing_selector.svg); + background-repeat: no-repeat; + background-position: center; + } + )"); + imageLabel->setFixedSize(300, 300); + + textLabel = new QLabel(this); + textLabel->setAlignment(Qt::AlignCenter); + textLabel->setWordWrap(true); + textLabel->setStyleSheet(R"( + QLabel { + color: palette(mid); + font-size: 14px; + padding: 10px; + } + )"); + + mainLayout->addWidget(imageLabel); + mainLayout->addWidget(textLabel); + + retranslateUi(); +} + +void PrintingSelectorPlaceholderWidget::retranslateUi() +{ + textLabel->setText(tr("Select a card to view its available printings")); +} \ No newline at end of file diff --git a/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.h b/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.h new file mode 100644 index 000000000..abf030c69 --- /dev/null +++ b/cockatrice/src/interface/widgets/printing_selector/printing_selector_placeholder_widget.h @@ -0,0 +1,23 @@ +#ifndef COCKATRICE_PRINTING_SELECTOR_PLACEHOLDER_WIDGET_H +#define COCKATRICE_PRINTING_SELECTOR_PLACEHOLDER_WIDGET_H + +#include +#include +#include + +class PrintingSelectorPlaceholderWidget : public QWidget +{ + Q_OBJECT + +public: + explicit PrintingSelectorPlaceholderWidget(QWidget *parent = nullptr); + +private: + QVBoxLayout *mainLayout; + QLabel *imageLabel; + QLabel *textLabel; + + void retranslateUi(); +}; + +#endif // COCKATRICE_PRINTING_SELECTOR_PLACEHOLDER_WIDGET_H diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.cpp new file mode 100644 index 000000000..da4fe09e5 --- /dev/null +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.cpp @@ -0,0 +1,41 @@ +#include "visual_deck_editor_placeholder_widget.h" + +VisualDeckEditorPlaceholderWidget::VisualDeckEditorPlaceholderWidget(QWidget *parent) : QWidget(parent) +{ + mainLayout = new QVBoxLayout(this); + mainLayout->setAlignment(Qt::AlignCenter); + setLayout(mainLayout); + + // Image label with the background image + imageLabel = new QLabel(this); + imageLabel->setAlignment(Qt::AlignCenter); + imageLabel->setStyleSheet(R"( + QLabel { + background-image: url(theme:backgrounds/card_triplet.svg); + background-repeat: no-repeat; + background-position: center; + } + )"); + imageLabel->setFixedSize(300, 300); + + textLabel = new QLabel(this); + textLabel->setAlignment(Qt::AlignCenter); + textLabel->setWordWrap(true); + textLabel->setStyleSheet(R"( + QLabel { + color: palette(mid); + font-size: 14px; + padding: 10px; + } + )"); + + mainLayout->addWidget(imageLabel); + mainLayout->addWidget(textLabel); + + retranslateUi(); +} + +void VisualDeckEditorPlaceholderWidget::retranslateUi() +{ + textLabel->setText(tr("Add cards using the search bar or database tab to have them appear here")); +} \ No newline at end of file diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.h b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.h new file mode 100644 index 000000000..de2362a81 --- /dev/null +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_placeholder_widget.h @@ -0,0 +1,22 @@ +#ifndef COCKATRICE_VISUAL_DECK_EDITOR_PLACEHOLDER_WIDGET_H +#define COCKATRICE_VISUAL_DECK_EDITOR_PLACEHOLDER_WIDGET_H + +#include +#include +#include + +class VisualDeckEditorPlaceholderWidget : public QWidget +{ + Q_OBJECT + +public: + explicit VisualDeckEditorPlaceholderWidget(QWidget *parent = nullptr); + void retranslateUi(); + +private: + QVBoxLayout *mainLayout; + QLabel *imageLabel; + QLabel *textLabel; +}; + +#endif // COCKATRICE_VISUAL_DECK_EDITOR_PLACEHOLDER_WIDGET_H diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp index 9d2aadc63..d6afb5f22 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.cpp @@ -59,6 +59,7 @@ VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, &VisualDeckEditorWidget::onSelectionChanged); } + updatePlaceholderVisibility(); retranslateUi(); } @@ -180,8 +181,14 @@ void VisualDeckEditorWidget::initializeScrollAreaAndZoneContainer() zoneContainer = new QWidget(scrollArea); zoneContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + zoneContainer->setObjectName("zoneContainer"); zoneContainerLayout = new QVBoxLayout(zoneContainer); zoneContainer->setLayout(zoneContainerLayout); + + // Create placeholder widget + placeholderWidget = new VisualDeckEditorPlaceholderWidget(zoneContainer); + zoneContainerLayout->addWidget(placeholderWidget); + scrollArea->addScrollBarWidget(zoneContainer, Qt::AlignHCenter); scrollArea->setWidget(zoneContainer); } @@ -200,6 +207,17 @@ void VisualDeckEditorWidget::retranslateUi() searchPushButton->setText(tr("Quick search and add card")); searchPushButton->setToolTip(tr("Search for closest match in the database (with auto-suggestions) and add " "preferred printing to the deck on pressing enter")); + + if (placeholderWidget) { + placeholderWidget->retranslateUi(); + } +} + +void VisualDeckEditorWidget::updatePlaceholderVisibility() +{ + if (placeholderWidget) { + placeholderWidget->setVisible(indexToWidgetMap.isEmpty()); + } } // ===================================================================================================================== @@ -250,6 +268,7 @@ void VisualDeckEditorWidget::constructZoneWidgetsFromDeckListModel() constructZoneWidgetForIndex(persistent); } + updatePlaceholderVisibility(); } void VisualDeckEditorWidget::updateZoneWidgets() @@ -264,6 +283,7 @@ void VisualDeckEditorWidget::clearAllDisplayWidgets() indexToWidgetMap.remove(idx); delete displayWidget; } + updatePlaceholderVisibility(); } void VisualDeckEditorWidget::cleanupInvalidZones(DeckCardZoneDisplayWidget *displayWidget) @@ -275,6 +295,7 @@ void VisualDeckEditorWidget::cleanupInvalidZones(DeckCardZoneDisplayWidget *disp } } delete displayWidget; + updatePlaceholderVisibility(); } // ===================================================================================================================== @@ -294,6 +315,7 @@ void VisualDeckEditorWidget::onCardAddition(const QModelIndex &parent, int first constructZoneWidgetForIndex(index); } } + updatePlaceholderVisibility(); } void VisualDeckEditorWidget::onCardRemoval(const QModelIndex &parent, int first, int last) @@ -308,6 +330,7 @@ void VisualDeckEditorWidget::onCardRemoval(const QModelIndex &parent, int first, indexToWidgetMap.remove(idx); } } + updatePlaceholderVisibility(); } void VisualDeckEditorWidget::decklistModelReset() @@ -390,4 +413,4 @@ void VisualDeckEditorWidget::onSelectionChanged(const QItemSelection &selected, } } } -} +} \ No newline at end of file diff --git a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.h b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.h index 5789155b8..13065d623 100644 --- a/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.h +++ b/cockatrice/src/interface/widgets/visual_deck_editor/visual_deck_editor_widget.h @@ -11,6 +11,7 @@ #include "../cards/card_size_widget.h" #include "../general/layout_containers/overlap_control_widget.h" #include "../quick_settings/settings_button_widget.h" +#include "visual_deck_editor_placeholder_widget.h" #include #include @@ -44,6 +45,7 @@ public: void setSelectionModel(QItemSelectionModel *model); void onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + void updatePlaceholderVisibility(); QItemSelectionModel *getSelectionModel() const { return selectionModel; @@ -96,6 +98,7 @@ private: QScrollArea *scrollArea; QWidget *zoneContainer; QVBoxLayout *zoneContainerLayout; + VisualDeckEditorPlaceholderWidget *placeholderWidget; // OverlapControlWidget *overlapControlWidget; QHash indexToWidgetMap; };