mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
* 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:
parent
f484c98152
commit
17dcaf9afa
337 changed files with 728 additions and 721 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue