* move message_log_widget to game

* move files

* update headers

* fix cmakelists

* oracle fixes

* split implementation out to cpp

* fix recursive import

* fix main file

* format
This commit is contained in:
ebbit1q 2025-09-20 14:35:52 +02:00 committed by GitHub
parent f484c98152
commit 17dcaf9afa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
337 changed files with 728 additions and 721 deletions

View file

@ -0,0 +1,130 @@
#include "visual_deck_editor_sample_hand_widget.h"
#include "../../../database/card_database_manager.h"
#include "../../../deck/deck_loader.h"
#include "../../../settings/cache_settings.h"
#include "../cards/card_info_picture_widget.h"
#include <random>
VisualDeckEditorSampleHandWidget::VisualDeckEditorSampleHandWidget(QWidget *parent, DeckListModel *_deckListModel)
: QWidget(parent), deckListModel(_deckListModel)
{
layout = new QVBoxLayout(this);
setLayout(layout);
resetAndHandSizeContainerWidget = new QWidget(this);
resetAndHandSizeLayout = new QHBoxLayout(resetAndHandSizeContainerWidget);
resetAndHandSizeContainerWidget->setLayout(resetAndHandSizeLayout);
resetButton = new QPushButton(this);
connect(resetButton, SIGNAL(clicked()), this, SLOT(updateDisplay()));
resetAndHandSizeLayout->addWidget(resetButton);
handSizeSpinBox = new QSpinBox(this);
handSizeSpinBox->setValue(SettingsCache::instance().getVisualDeckEditorSampleHandSize());
handSizeSpinBox->setMinimum(1);
connect(handSizeSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), &SettingsCache::instance(),
&SettingsCache::setVisualDeckEditorSampleHandSize);
connect(handSizeSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), this,
&VisualDeckEditorSampleHandWidget::updateDisplay);
resetAndHandSizeLayout->addWidget(handSizeSpinBox);
layout->addWidget(resetAndHandSizeContainerWidget);
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
layout->addWidget(flowWidget);
cardSizeWidget = new CardSizeWidget(this, flowWidget);
layout->addWidget(cardSizeWidget);
for (const ExactCard &card : getRandomCards(handSizeSpinBox->value())) {
auto displayWidget = new CardInfoPictureWidget(this);
displayWidget->setCard(card);
displayWidget->setScaleFactor(cardSizeWidget->getSlider()->value());
flowWidget->addWidget(displayWidget);
}
retranslateUi();
}
void VisualDeckEditorSampleHandWidget::retranslateUi()
{
resetButton->setText(tr("Draw a new sample hand"));
handSizeSpinBox->setToolTip(tr("Sample hand size"));
}
void VisualDeckEditorSampleHandWidget::setDeckModel(DeckListModel *deckModel)
{
deckListModel = deckModel;
// connect(deckListModel, &DeckListModel::dataChanged, this, &VisualDeckEditorSampleHandWidget::updateDisplay);
updateDisplay();
}
void VisualDeckEditorSampleHandWidget::updateDisplay()
{
flowWidget->clearLayout();
for (const ExactCard &card : getRandomCards(handSizeSpinBox->value())) {
auto displayWidget = new CardInfoPictureWidget(this);
displayWidget->setCard(card);
displayWidget->setScaleFactor(cardSizeWidget->getSlider()->value());
connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, displayWidget,
&CardInfoPictureWidget::setScaleFactor);
flowWidget->addWidget(displayWidget);
}
}
QList<ExactCard> VisualDeckEditorSampleHandWidget::getRandomCards(int amountToGet)
{
QList<ExactCard> mainDeckCards;
QList<ExactCard> randomCards;
if (!deckListModel)
return randomCards;
DeckList *decklist = deckListModel->getDeckList();
if (!decklist)
return randomCards;
InnerDecklistNode *listRoot = decklist->getRoot();
if (!listRoot)
return randomCards;
// Collect all cards in the main deck, allowing duplicates based on their count
for (int i = 0; i < listRoot->size(); i++) {
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
if (!currentZone)
continue;
if (currentZone->getName() != DECK_ZONE_MAIN)
continue; // Only process the main deck
for (int j = 0; j < currentZone->size(); j++) {
DecklistCardNode *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
if (!currentCard)
continue;
for (int k = 0; k < currentCard->getNumber(); ++k) {
ExactCard card = CardDatabaseManager::getInstance()->getCard(currentCard->toCardRef());
if (card) {
mainDeckCards.append(card);
}
}
}
}
if (mainDeckCards.isEmpty())
return randomCards;
// Shuffle the deck
std::random_device rd;
std::mt19937 rng(rd());
std::shuffle(mainDeckCards.begin(), mainDeckCards.end(), rng);
// Select amountToGet cards
for (int i = 0; i < qMin(amountToGet, mainDeckCards.size()); ++i) {
randomCards.append(mainDeckCards.at(i));
}
std::sort(randomCards.begin(), randomCards.end(),
[](const ExactCard &a, const ExactCard &b) { return a.getInfo().getCmc() < b.getInfo().getCmc(); });
return randomCards;
}

View file

@ -0,0 +1,35 @@
#ifndef VISUAL_DECK_EDITOR_SAMPLE_HAND_WIDGET_H
#define VISUAL_DECK_EDITOR_SAMPLE_HAND_WIDGET_H
#include "../../../deck/deck_list_model.h"
#include "../cards/card_size_widget.h"
#include "../general/layout_containers/flow_widget.h"
#include <QPushButton>
#include <QSpinBox>
#include <QWidget>
class VisualDeckEditorSampleHandWidget : public QWidget
{
Q_OBJECT
public:
VisualDeckEditorSampleHandWidget(QWidget *parent, DeckListModel *deckListModel);
QList<ExactCard> getRandomCards(int amountToGet);
public slots:
void updateDisplay();
void setDeckModel(DeckListModel *deckModel);
void retranslateUi();
private:
DeckListModel *deckListModel;
QVBoxLayout *layout;
QWidget *resetAndHandSizeContainerWidget;
QHBoxLayout *resetAndHandSizeLayout;
QPushButton *resetButton;
QSpinBox *handSizeSpinBox;
FlowWidget *flowWidget;
CardSizeWidget *cardSizeWidget;
};
#endif // VISUAL_DECK_EDITOR_SAMPLE_HAND_WIDGET_H

View file

@ -0,0 +1,381 @@
#include "visual_deck_editor_widget.h"
#include "../../../database/card_completer_proxy_model.h"
#include "../../../database/card_database.h"
#include "../../../database/card_database_manager.h"
#include "../../../database/card_database_model.h"
#include "../../../database/card_search_model.h"
#include "../../../deck/deck_list_model.h"
#include "../../../deck/deck_loader.h"
#include "../../../main.h"
#include "../../../utility/card_info_comparator.h"
#include "../../layouts/overlap_layout.h"
#include "../cards/card_info_picture_with_text_overlay_widget.h"
#include "../cards/deck_card_zone_display_widget.h"
#include "../general/layout_containers/flow_widget.h"
#include "../general/layout_containers/overlap_control_widget.h"
#include <QCheckBox>
#include <QCompleter>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QResizeEvent>
#include <qscrollarea.h>
VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_deckListModel)
: QWidget(parent), deckListModel(_deckListModel)
{
// The Main Widget and Main Layout, which contain a single Widget: The Scroll Area
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
mainLayout = new QVBoxLayout(this);
setLayout(mainLayout);
mainLayout->setContentsMargins(9, 0, 9, 5);
mainLayout->setSpacing(0);
searchContainer = new QWidget(this);
searchLayout = new QHBoxLayout(searchContainer);
searchContainer->setLayout(searchLayout);
searchBar = new QLineEdit(this);
connect(searchBar, &QLineEdit::returnPressed, this, [=, this]() {
if (!searchBar->hasFocus())
return;
ExactCard card = CardDatabaseManager::getInstance()->getCard({searchBar->text()});
if (card) {
emit cardAdditionRequested(card);
}
});
setFocusProxy(searchBar);
setFocusPolicy(Qt::ClickFocus);
cardDatabaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), false, this);
cardDatabaseDisplayModel = new CardDatabaseDisplayModel(this);
cardDatabaseDisplayModel->setSourceModel(cardDatabaseModel);
CardSearchModel *searchModel = new CardSearchModel(cardDatabaseDisplayModel, this);
proxyModel = new CardCompleterProxyModel(this);
proxyModel->setSourceModel(searchModel);
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
proxyModel->setFilterRole(Qt::DisplayRole);
completer = new QCompleter(proxyModel, this);
completer->setCompletionRole(Qt::DisplayRole);
completer->setCompletionMode(QCompleter::PopupCompletion);
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setFilterMode(Qt::MatchContains);
completer->setMaxVisibleItems(15);
searchBar->setCompleter(completer);
// Update suggestions dynamically
connect(searchBar, &QLineEdit::textEdited, searchModel, &CardSearchModel::updateSearchResults);
connect(searchBar, &QLineEdit::textEdited, this, [=, this](const QString &text) {
// Ensure substring matching
QString pattern = ".*" + QRegularExpression::escape(text) + ".*";
proxyModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
if (!text.isEmpty()) {
completer->complete(); // Force the dropdown to appear
}
});
connect(completer, static_cast<void (QCompleter::*)(const QString &)>(&QCompleter::activated), this,
[=, this](const QString &completion) {
// Prevent the text from changing automatically when navigating with arrow keys
if (searchBar->text() != completion) {
searchBar->setText(completion); // Set the completion explicitly
searchBar->setCursorPosition(searchBar->text().length()); // Move cursor to the end
}
});
// Ensure that the text stays consistent during selection
connect(searchBar, &QLineEdit::textEdited, this, [=, this](const QString &text) {
if (searchBar->hasFocus() && !searchBar->completer()->popup()->isVisible()) {
// Allow text to change when typing, but not when navigating the completer
QString pattern = ".*" + QRegularExpression::escape(text) + ".*";
proxyModel->setFilterRegularExpression(
QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
}
});
// Search button functionality
searchPushButton = new QPushButton(this);
connect(searchPushButton, &QPushButton::clicked, this, [=, this]() {
ExactCard card = CardDatabaseManager::getInstance()->getCard({searchBar->text()});
if (card) {
emit cardAdditionRequested(card);
}
});
searchLayout->addWidget(searchBar);
searchLayout->addWidget(searchPushButton);
mainLayout->addWidget(searchContainer);
groupAndSortContainer = new QWidget(this);
groupAndSortLayout = new QHBoxLayout(groupAndSortContainer);
groupAndSortLayout->setAlignment(Qt::AlignLeft);
groupAndSortContainer->setLayout(groupAndSortLayout);
groupByComboBox = new QComboBox();
QStringList groupProperties = {"maintype", "colors", "cmc", "name"};
groupByComboBox->addItems(groupProperties);
groupByComboBox->setMinimumWidth(300);
connect(groupByComboBox, QOverload<const QString &>::of(&QComboBox::currentTextChanged), this,
&VisualDeckEditorWidget::actChangeActiveGroupCriteria);
actChangeActiveGroupCriteria();
sortCriteriaButton = new SettingsButtonWidget(this);
sortLabel = new QLabel(sortCriteriaButton);
sortLabel->setWordWrap(true);
QStringList sortProperties = {"colors", "cmc", "name", "maintype"};
sortByListWidget = new QListWidget();
sortByListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
sortByListWidget->setDragDropMode(QAbstractItemView::InternalMove);
sortByListWidget->setDefaultDropAction(Qt::MoveAction);
for (const QString &property : sortProperties) {
QListWidgetItem *item = new QListWidgetItem(property, sortByListWidget);
item->setFlags(item->flags() | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
}
connect(sortByListWidget->model(), &QAbstractItemModel::rowsMoved, this,
&VisualDeckEditorWidget::actChangeActiveSortCriteria);
actChangeActiveSortCriteria();
sortByListWidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
sortCriteriaButton->addSettingsWidget(sortLabel);
sortCriteriaButton->addSettingsWidget(sortByListWidget);
displayTypeButton = new QPushButton(this);
connect(displayTypeButton, &QPushButton::clicked, this, &VisualDeckEditorWidget::updateDisplayType);
groupAndSortLayout->addWidget(groupByComboBox);
groupAndSortLayout->addWidget(sortCriteriaButton);
groupAndSortLayout->addWidget(displayTypeButton);
scrollArea = new QScrollArea(this);
scrollArea->setWidgetResizable(true);
scrollArea->setMinimumSize(0, 0);
// Set scrollbar policies
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
zoneContainer = new QWidget(scrollArea);
zoneContainerLayout = new QVBoxLayout(zoneContainer);
zoneContainer->setLayout(zoneContainerLayout);
scrollArea->addScrollBarWidget(zoneContainer, Qt::AlignHCenter);
scrollArea->setWidget(zoneContainer);
cardSizeWidget = new CardSizeWidget(this);
mainLayout->addWidget(groupAndSortContainer);
mainLayout->addWidget(scrollArea);
mainLayout->addWidget(cardSizeWidget);
connect(deckListModel, &DeckListModel::modelReset, this, &VisualDeckEditorWidget::decklistModelReset);
connect(deckListModel, &DeckListModel::dataChanged, this, &VisualDeckEditorWidget::decklistDataChanged);
connect(deckListModel, &QAbstractItemModel::rowsInserted, this, &VisualDeckEditorWidget::onCardAddition);
connect(deckListModel, &QAbstractItemModel::rowsRemoved, this, &VisualDeckEditorWidget::onCardRemoval);
constructZoneWidgetsFromDeckListModel();
retranslateUi();
}
void VisualDeckEditorWidget::retranslateUi()
{
sortLabel->setText(tr("Click and drag to change the sort order within the groups"));
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"));
sortCriteriaButton->setToolTip(tr("Configure how cards are sorted within their groups"));
displayTypeButton->setText(tr("Overlap Layout"));
displayTypeButton->setToolTip(
tr("Change how cards are displayed within zones (i.e. overlapped or fully visible.)"));
}
void VisualDeckEditorWidget::clearAllDisplayWidgets()
{
for (auto idx : indexToWidgetMap.keys()) {
auto displayWidget = indexToWidgetMap.value(idx);
zoneContainerLayout->removeWidget(displayWidget);
indexToWidgetMap.remove(idx);
delete displayWidget;
}
}
void VisualDeckEditorWidget::cleanupInvalidZones(DeckCardZoneDisplayWidget *displayWidget)
{
zoneContainerLayout->removeWidget(displayWidget);
for (auto idx : indexToWidgetMap.keys()) {
if (!idx.isValid()) {
indexToWidgetMap.remove(idx);
}
}
delete displayWidget;
}
void VisualDeckEditorWidget::onCardAddition(const QModelIndex &parent, int first, int last)
{
if (parent == deckListModel->getRoot()) {
for (int i = first; i <= last; i++) {
QPersistentModelIndex index = QPersistentModelIndex(deckListModel->index(i, 0, deckListModel->getRoot()));
if (indexToWidgetMap.contains(index)) {
continue;
}
DeckCardZoneDisplayWidget *zoneDisplayWidget = new DeckCardZoneDisplayWidget(
zoneContainer, deckListModel, index,
deckListModel->data(index.sibling(index.row(), 1), Qt::EditRole).toString(), activeGroupCriteria,
activeSortCriteria, currentDisplayType, 20, 10, cardSizeWidget);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardHovered, this, &VisualDeckEditorWidget::onHover);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardClicked, this,
&VisualDeckEditorWidget::onCardClick);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::requestCleanup, this,
&VisualDeckEditorWidget::cleanupInvalidZones);
connect(this, &VisualDeckEditorWidget::activeSortCriteriaChanged, zoneDisplayWidget,
&DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged);
connect(this, &VisualDeckEditorWidget::activeGroupCriteriaChanged, zoneDisplayWidget,
&DeckCardZoneDisplayWidget::onActiveGroupCriteriaChanged);
connect(this, &VisualDeckEditorWidget::displayTypeChanged, zoneDisplayWidget,
&DeckCardZoneDisplayWidget::refreshDisplayType);
zoneDisplayWidget->refreshDisplayType(currentDisplayType);
zoneContainerLayout->addWidget(zoneDisplayWidget);
indexToWidgetMap.insert(index, zoneDisplayWidget);
}
}
}
void VisualDeckEditorWidget::onCardRemoval(const QModelIndex &parent, int first, int last)
{
Q_UNUSED(parent);
Q_UNUSED(first);
Q_UNUSED(last);
for (const QPersistentModelIndex &idx : indexToWidgetMap.keys()) {
if (!idx.isValid()) {
zoneContainerLayout->removeWidget(indexToWidgetMap.value(idx));
indexToWidgetMap.value(idx)->deleteLater();
indexToWidgetMap.remove(idx);
}
}
}
void VisualDeckEditorWidget::constructZoneWidgetsFromDeckListModel()
{
QSortFilterProxyModel proxy;
proxy.setSourceModel(deckListModel);
proxy.setSortRole(Qt::EditRole);
proxy.sort(1, Qt::AscendingOrder);
for (int i = 0; i < proxy.rowCount(); ++i) {
QModelIndex proxyIndex = proxy.index(i, 0);
QModelIndex sourceIndex = proxy.mapToSource(proxyIndex);
// Make a persistent index from the *source* model
QPersistentModelIndex persistent(sourceIndex);
if (indexToWidgetMap.contains(persistent)) {
continue;
}
DeckCardZoneDisplayWidget *zoneDisplayWidget = new DeckCardZoneDisplayWidget(
zoneContainer, deckListModel, persistent,
deckListModel->data(persistent.sibling(persistent.row(), 1), Qt::EditRole).toString(), activeGroupCriteria,
activeSortCriteria, currentDisplayType, 20, 10, cardSizeWidget);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardHovered, this, &VisualDeckEditorWidget::onHover);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardClicked, this, &VisualDeckEditorWidget::onCardClick);
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::requestCleanup, this,
&VisualDeckEditorWidget::cleanupInvalidZones);
connect(this, &VisualDeckEditorWidget::activeSortCriteriaChanged, zoneDisplayWidget,
&DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged);
connect(this, &VisualDeckEditorWidget::activeGroupCriteriaChanged, zoneDisplayWidget,
&DeckCardZoneDisplayWidget::onActiveGroupCriteriaChanged);
connect(this, &VisualDeckEditorWidget::displayTypeChanged, zoneDisplayWidget,
&DeckCardZoneDisplayWidget::refreshDisplayType);
zoneContainerLayout->addWidget(zoneDisplayWidget);
indexToWidgetMap.insert(persistent, zoneDisplayWidget);
}
}
void VisualDeckEditorWidget::updateZoneWidgets()
{
}
void VisualDeckEditorWidget::updateDisplayType()
{
// Toggle the display type
currentDisplayType = (currentDisplayType == DisplayType::Overlap) ? DisplayType::Flat : DisplayType::Overlap;
// Update UI and emit signal
switch (currentDisplayType) {
case DisplayType::Flat:
displayTypeButton->setText(tr("Flat Layout"));
break;
case DisplayType::Overlap:
displayTypeButton->setText(tr("Overlap Layout"));
break;
}
emit displayTypeChanged(currentDisplayType);
}
void VisualDeckEditorWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
zoneContainer->setMaximumWidth(scrollArea->viewport()->width());
}
void VisualDeckEditorWidget::actChangeActiveGroupCriteria()
{
activeGroupCriteria = groupByComboBox->currentText();
emit activeGroupCriteriaChanged(activeGroupCriteria);
}
void VisualDeckEditorWidget::actChangeActiveSortCriteria()
{
QStringList selectedCriteria;
for (int i = 0; i < sortByListWidget->count(); ++i) {
QListWidgetItem *item = sortByListWidget->item(i);
selectedCriteria.append(item->text()); // Collect user-defined sort order
}
activeSortCriteria = selectedCriteria;
emit activeSortCriteriaChanged(selectedCriteria);
}
void VisualDeckEditorWidget::decklistModelReset()
{
clearAllDisplayWidgets();
constructZoneWidgetsFromDeckListModel();
}
void VisualDeckEditorWidget::decklistDataChanged(QModelIndex topLeft, QModelIndex bottomRight)
{
// Might use these at some point.
Q_UNUSED(topLeft);
Q_UNUSED(bottomRight);
// Necessary to delay this in this manner else the updateDisplay will nuke widgets while their onClick event
// hasn't returned yet. Interval of 0 means QT will schedule this after the current event loop has finished.
updateZoneWidgets();
}
void VisualDeckEditorWidget::onHover(const ExactCard &hoveredCard)
{
emit activeCardChanged(hoveredCard);
}
void VisualDeckEditorWidget::onCardClick(QMouseEvent *event,
CardInfoPictureWithTextOverlayWidget *instance,
QString zoneName)
{
emit cardClicked(event, instance, zoneName);
}

View file

@ -0,0 +1,94 @@
#ifndef VISUAL_DECK_EDITOR_H
#define VISUAL_DECK_EDITOR_H
#include "../../../database/card_completer_proxy_model.h"
#include "../../../database/card_database.h"
#include "../../../database/card_database_model.h"
#include "../../../deck/deck_list_model.h"
#include "../cards/card_info_picture_with_text_overlay_widget.h"
#include "../cards/card_size_widget.h"
#include "../general/layout_containers/flow_widget.h"
#include "../general/layout_containers/overlap_control_widget.h"
#include "../quick_settings/settings_button_widget.h"
#include <QCheckBox>
#include <QListWidget>
#include <QPushButton>
#include <QWidget>
#include <qscrollarea.h>
class DeckCardZoneDisplayWidget;
enum class DisplayType
{
Flat,
Overlap
};
class VisualDeckEditorWidget : public QWidget
{
Q_OBJECT
public:
explicit VisualDeckEditorWidget(QWidget *parent, DeckListModel *deckListModel);
void retranslateUi();
void clearAllDisplayWidgets();
void resizeEvent(QResizeEvent *event) override;
void setDeckList(const DeckList &_deckListModel);
QLineEdit *searchBar;
CardSizeWidget *cardSizeWidget;
public slots:
void decklistDataChanged(QModelIndex topLeft, QModelIndex bottomRight);
void updateZoneWidgets();
void updateDisplayType();
void cleanupInvalidZones(DeckCardZoneDisplayWidget *displayWidget);
void onCardAddition(const QModelIndex &parent, int first, int last);
void onCardRemoval(const QModelIndex &parent, int first, int last);
void constructZoneWidgetsFromDeckListModel();
signals:
void activeCardChanged(const ExactCard &activeCard);
void activeGroupCriteriaChanged(QString activeGroupCriteria);
void activeSortCriteriaChanged(QStringList activeSortCriteria);
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
void cardAdditionRequested(const ExactCard &card);
void displayTypeChanged(DisplayType displayType);
protected slots:
void onHover(const ExactCard &hoveredCard);
void onCardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
void actChangeActiveGroupCriteria();
void actChangeActiveSortCriteria();
void decklistModelReset();
private:
DeckListModel *deckListModel;
QVBoxLayout *mainLayout;
QWidget *searchContainer;
QHBoxLayout *searchLayout;
CardDatabaseModel *cardDatabaseModel;
CardDatabaseDisplayModel *cardDatabaseDisplayModel;
CardCompleterProxyModel *proxyModel;
QCompleter *completer;
QPushButton *searchPushButton;
DisplayType currentDisplayType = DisplayType::Overlap;
QPushButton *displayTypeButton;
QWidget *groupAndSortContainer;
QHBoxLayout *groupAndSortLayout;
QComboBox *groupByComboBox;
QString activeGroupCriteria = "maintype";
SettingsButtonWidget *sortCriteriaButton;
QLabel *sortLabel;
QListWidget *sortByListWidget;
QStringList activeSortCriteria = {"name", "cmc", "colors", "maintype"};
QScrollArea *scrollArea;
QWidget *zoneContainer;
QVBoxLayout *zoneContainerLayout;
// OverlapControlWidget *overlapControlWidget;
QWidget *container;
QHash<QPersistentModelIndex, QWidget *> indexToWidgetMap;
};
#endif // VISUAL_DECK_EDITOR_H