mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-14 22:42:14 -07:00
More performant display updating.
This commit is contained in:
parent
268d3f2e6b
commit
d60b613fd5
12 changed files with 320 additions and 245 deletions
|
|
@ -65,10 +65,8 @@ void TabDeckEditorVisual::createCentralFrame()
|
|||
&TabDeckEditorVisual::changeModelIndexAndCardInfo);
|
||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardChangedDatabaseDisplay, this,
|
||||
&AbstractTabDeckEditor::updateCard);
|
||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::mainboardCardClicked, this,
|
||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardClicked, this,
|
||||
&TabDeckEditorVisual::processMainboardCardClick);
|
||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::sideboardCardClicked, this,
|
||||
&TabDeckEditorVisual::processSideboardCardClick);
|
||||
|
||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardClickedDatabaseDisplay, this,
|
||||
&TabDeckEditorVisual::processCardClickDatabaseDisplay);
|
||||
|
|
@ -161,10 +159,12 @@ void TabDeckEditorVisual::changeModelIndexToCard(const CardInfoPtr &activeCard)
|
|||
deckDockWidget->deckView->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::processMainboardCardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance)
|
||||
void TabDeckEditorVisual::processMainboardCardClick(QMouseEvent *event,
|
||||
CardInfoPictureWithTextOverlayWidget *instance,
|
||||
QString zoneName)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
actSwapCard(instance->getInfo(), DECK_ZONE_MAIN);
|
||||
actSwapCard(instance->getInfo(), zoneName);
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
actDecrementCard(instance->getInfo());
|
||||
} else if (event->button() == Qt::MiddleButton) {
|
||||
|
|
@ -172,17 +172,6 @@ void TabDeckEditorVisual::processMainboardCardClick(QMouseEvent *event, CardInfo
|
|||
}
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::processSideboardCardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
actSwapCard(instance->getInfo(), DECK_ZONE_SIDE);
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
actDecrementCardFromSideboard(instance->getInfo());
|
||||
} else if (event->button() == Qt::MiddleButton) {
|
||||
deckDockWidget->actRemoveCard();
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::processCardClickDatabaseDisplay(QMouseEvent *event,
|
||||
CardInfoPictureWithTextOverlayWidget *instance)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ public:
|
|||
public slots:
|
||||
void onDeckChanged() override;
|
||||
void showPrintingSelector() override;
|
||||
void processMainboardCardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
void processSideboardCardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
void
|
||||
processMainboardCardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||
void processCardClickDatabaseDisplay(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,13 +20,10 @@ TabDeckEditorVisualTabWidget::TabDeckEditorVisualTabWidget(QWidget *parent,
|
|||
|
||||
visualDeckView = new VisualDeckEditorWidget(this, deckModel);
|
||||
visualDeckView->setObjectName("visualDeckView");
|
||||
visualDeckView->updateDisplay();
|
||||
connect(visualDeckView, &VisualDeckEditorWidget::activeCardChanged, this,
|
||||
&TabDeckEditorVisualTabWidget::onCardChanged);
|
||||
connect(visualDeckView, &VisualDeckEditorWidget::mainboardCardClicked, this,
|
||||
&TabDeckEditorVisualTabWidget::onMainboardCardClickedDeckEditor);
|
||||
connect(visualDeckView, &VisualDeckEditorWidget::sideboardCardClicked, this,
|
||||
&TabDeckEditorVisualTabWidget::onSideboardCardClickedDeckEditor);
|
||||
connect(visualDeckView, &VisualDeckEditorWidget::cardClicked, this,
|
||||
&TabDeckEditorVisualTabWidget::onCardClickedDeckEditor);
|
||||
|
||||
visualDatabaseDisplay =
|
||||
new VisualDatabaseDisplayWidget(this, deckEditor, cardDatabaseModel, cardDatabaseDisplayModel);
|
||||
|
|
@ -57,16 +54,11 @@ void TabDeckEditorVisualTabWidget::onCardChangedDatabaseDisplay(CardInfoPtr acti
|
|||
emit cardChangedDatabaseDisplay(activeCard);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::onMainboardCardClickedDeckEditor(QMouseEvent *event,
|
||||
CardInfoPictureWithTextOverlayWidget *instance)
|
||||
void TabDeckEditorVisualTabWidget::onCardClickedDeckEditor(QMouseEvent *event,
|
||||
CardInfoPictureWithTextOverlayWidget *instance,
|
||||
QString zoneName)
|
||||
{
|
||||
emit mainboardCardClicked(event, instance);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::onSideboardCardClickedDeckEditor(QMouseEvent *event,
|
||||
CardInfoPictureWithTextOverlayWidget *instance)
|
||||
{
|
||||
emit sideboardCardClicked(event, instance);
|
||||
emit cardClicked(event, instance, zoneName);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::onCardClickedDatabaseDisplay(QMouseEvent *event,
|
||||
|
|
|
|||
|
|
@ -39,15 +39,13 @@ public:
|
|||
public slots:
|
||||
void onCardChanged(CardInfoPtr activeCard);
|
||||
void onCardChangedDatabaseDisplay(CardInfoPtr activeCard);
|
||||
void onMainboardCardClickedDeckEditor(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
void onSideboardCardClickedDeckEditor(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
void onCardClickedDeckEditor(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||
void onCardClickedDatabaseDisplay(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
|
||||
signals:
|
||||
void cardChanged(CardInfoPtr activeCard);
|
||||
void cardChangedDatabaseDisplay(CardInfoPtr activeCard);
|
||||
void mainboardCardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
void sideboardCardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||
void cardClickedDatabaseDisplay(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -1,23 +1,33 @@
|
|||
#include "deck_card_zone_display_widget.h"
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../../../../utility/card_info_comparator.h"
|
||||
#include "overlapped_card_group_display_widget.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
|
||||
DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent,
|
||||
QList<QPair<QString, QList<CardInfoPtr>>> cardLists,
|
||||
QString bannerText,
|
||||
DeckListModel *_deckListModel,
|
||||
QString _zoneName,
|
||||
QString _activeSortCriteria,
|
||||
int bannerOpacity,
|
||||
int subBannerOpacity)
|
||||
: QWidget(parent), cardLists(cardLists), bannerOpacity(bannerOpacity), subBannerOpacity(subBannerOpacity)
|
||||
: QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), activeSortCriteria(_activeSortCriteria),
|
||||
bannerOpacity(bannerOpacity), subBannerOpacity(subBannerOpacity)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
banner = new BannerWidget(this, bannerText, Qt::Orientation::Vertical, bannerOpacity);
|
||||
banner = new BannerWidget(this, zoneName, Qt::Orientation::Vertical, bannerOpacity);
|
||||
layout->addWidget(banner);
|
||||
|
||||
cardGroupContainer = new QWidget(this);
|
||||
cardGroupLayout = new QVBoxLayout(cardGroupContainer);
|
||||
cardGroupContainer->setLayout(cardGroupLayout);
|
||||
layout->addWidget(cardGroupContainer);
|
||||
|
||||
displayCards();
|
||||
connect(deckListModel, &DeckListModel::dataChanged, this, &DeckCardZoneDisplayWidget::displayCards);
|
||||
}
|
||||
void DeckCardZoneDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
|
|
@ -31,7 +41,7 @@ void DeckCardZoneDisplayWidget::resizeEvent(QResizeEvent *event)
|
|||
}
|
||||
void DeckCardZoneDisplayWidget::onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card)
|
||||
{
|
||||
emit cardClicked(event, card);
|
||||
emit cardClicked(event, card, zoneName);
|
||||
}
|
||||
void DeckCardZoneDisplayWidget::onHover(CardInfoPtr card)
|
||||
{
|
||||
|
|
@ -40,15 +50,70 @@ void DeckCardZoneDisplayWidget::onHover(CardInfoPtr card)
|
|||
|
||||
void DeckCardZoneDisplayWidget::displayCards()
|
||||
{
|
||||
for (QPair<QString, QList<CardInfoPtr>> &pair : cardLists) {
|
||||
QString criteriaValue = pair.first;
|
||||
QList<CardInfoPtr> cardList = pair.second;
|
||||
addCardGroupIfItDoesNotExist();
|
||||
deleteCardGroupIfItDoesNotExist();
|
||||
}
|
||||
|
||||
OverlappedCardGroupDisplayWidget *display_widget =
|
||||
new OverlappedCardGroupDisplayWidget(this, &cardList, criteriaValue, subBannerOpacity);
|
||||
connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this,
|
||||
SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)));
|
||||
connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr)));
|
||||
layout->addWidget(display_widget);
|
||||
void DeckCardZoneDisplayWidget::addCardGroupIfItDoesNotExist()
|
||||
{
|
||||
QList<OverlappedCardGroupDisplayWidget *> cardGroupsDisplayWidgets =
|
||||
cardGroupContainer->findChildren<OverlappedCardGroupDisplayWidget *>();
|
||||
|
||||
QList<QString> cardGroups = getSortCriteriaValueList();
|
||||
|
||||
for (QString cardGroup : cardGroups) {
|
||||
bool found = false;
|
||||
for (OverlappedCardGroupDisplayWidget *cardGroupDisplayWidget : cardGroupsDisplayWidgets) {
|
||||
if (cardGroupDisplayWidget->cardGroupCategory == cardGroup) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
OverlappedCardGroupDisplayWidget *display_widget = new OverlappedCardGroupDisplayWidget(
|
||||
this, deckListModel, zoneName, cardGroup, activeSortCriteria, subBannerOpacity);
|
||||
connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this,
|
||||
SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)));
|
||||
connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr)));
|
||||
cardGroupLayout->addWidget(display_widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeckCardZoneDisplayWidget::deleteCardGroupIfItDoesNotExist()
|
||||
{
|
||||
QList<OverlappedCardGroupDisplayWidget *> cardGroupsDisplayWidgets =
|
||||
cardGroupLayout->findChildren<OverlappedCardGroupDisplayWidget *>();
|
||||
for (OverlappedCardGroupDisplayWidget *cardGroupDisplayWidget : cardGroupsDisplayWidgets) {
|
||||
bool found = false;
|
||||
for (QString cardGroup : getSortCriteriaValueList()) {
|
||||
if (cardGroupDisplayWidget->cardGroupCategory == cardGroup) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
cardGroupLayout->removeWidget(cardGroupDisplayWidget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged(QString _activeSortCriteria)
|
||||
{
|
||||
activeSortCriteria = _activeSortCriteria;
|
||||
}
|
||||
|
||||
QList<QString> DeckCardZoneDisplayWidget::getSortCriteriaValueList()
|
||||
{
|
||||
QList<QString> sortCriteriaValues;
|
||||
|
||||
QList<CardInfoPtr> *cardsInZone = deckListModel->getCardsAsCardInfoPtrsForZone(zoneName);
|
||||
|
||||
for (CardInfoPtr cardInZone : *cardsInZone) {
|
||||
sortCriteriaValues.append(cardInZone->getProperty(activeSortCriteria));
|
||||
}
|
||||
|
||||
sortCriteriaValues.removeDuplicates();
|
||||
sortCriteriaValues.sort();
|
||||
return sortCriteriaValues;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef DECK_CARD_ZONE_DISPLAY_WIDGET_H
|
||||
#define DECK_CARD_ZONE_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../../../../game/cards/card_database.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
#include "../general/layout_containers/overlap_widget.h"
|
||||
|
|
@ -15,10 +16,13 @@ class DeckCardZoneDisplayWidget : public QWidget
|
|||
|
||||
public:
|
||||
DeckCardZoneDisplayWidget(QWidget *parent,
|
||||
QList<QPair<QString, QList<CardInfoPtr>>> cardLists,
|
||||
QString bannerText,
|
||||
DeckListModel *deckListModel,
|
||||
QString zoneName,
|
||||
QString activeSortCriteria,
|
||||
int bannerOpacity,
|
||||
int subBannerOpacity);
|
||||
DeckListModel *deckListModel;
|
||||
QString zoneName;
|
||||
void addCardsToOverlapWidget();
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
|
|
@ -26,15 +30,21 @@ public slots:
|
|||
void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
|
||||
void onHover(CardInfoPtr card);
|
||||
void displayCards();
|
||||
void addCardGroupIfItDoesNotExist();
|
||||
void deleteCardGroupIfItDoesNotExist();
|
||||
void onActiveSortCriteriaChanged(QString activeSortCriteria);
|
||||
QList<QString> getSortCriteriaValueList();
|
||||
|
||||
signals:
|
||||
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
|
||||
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card, QString zoneName);
|
||||
void cardHovered(CardInfoPtr card);
|
||||
|
||||
private:
|
||||
QList<QPair<QString, QList<CardInfoPtr>>> cardLists;
|
||||
QString activeSortCriteria;
|
||||
QVBoxLayout *layout;
|
||||
BannerWidget *banner;
|
||||
QWidget *cardGroupContainer;
|
||||
QVBoxLayout *cardGroupLayout;
|
||||
int bannerOpacity = 20;
|
||||
int subBannerOpacity = 10;
|
||||
OverlapWidget *overlapWidget;
|
||||
|
|
|
|||
|
|
@ -1,45 +1,119 @@
|
|||
#include "overlapped_card_group_display_widget.h"
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../../../../game/cards/card_database_manager.h"
|
||||
#include "../../../../utility/card_info_comparator.h"
|
||||
#include "card_info_picture_with_text_overlay_widget.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
|
||||
OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *parent,
|
||||
QList<CardInfoPtr> *cards,
|
||||
QString bannerText,
|
||||
DeckListModel *_deckListModel,
|
||||
QString _zoneName,
|
||||
QString _cardGroupCategory,
|
||||
QString _activeSortCriteria,
|
||||
int bannerOpacity)
|
||||
: QWidget(parent), cardsToDisplay(cards)
|
||||
: QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), cardGroupCategory(_cardGroupCategory),
|
||||
activeSortCriteria(_activeSortCriteria)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
setMinimumSize(QSize(0, 0));
|
||||
|
||||
banner = new BannerWidget(this, bannerText, Qt::Orientation::Vertical, bannerOpacity);
|
||||
banner = new BannerWidget(this, cardGroupCategory, Qt::Orientation::Vertical, bannerOpacity);
|
||||
overlapWidget = new OverlapWidget(this, 80, 1, 1, Qt::Vertical, true);
|
||||
|
||||
layout->addWidget(banner);
|
||||
layout->addWidget(overlapWidget);
|
||||
addCardsToOverlapWidget();
|
||||
updateCardDisplays();
|
||||
connect(deckListModel, &DeckListModel::dataChanged, this, &OverlappedCardGroupDisplayWidget::updateCardDisplays);
|
||||
}
|
||||
|
||||
void OverlappedCardGroupDisplayWidget::addCardsToOverlapWidget()
|
||||
void OverlappedCardGroupDisplayWidget::updateCardDisplays()
|
||||
{
|
||||
for (int i = 0; i < cardsToDisplay->size(); i++) {
|
||||
CardInfoPtr card = cardsToDisplay->at(i);
|
||||
if (card) {
|
||||
CardInfoPictureWithTextOverlayWidget *display =
|
||||
new CardInfoPictureWithTextOverlayWidget(overlapWidget, true);
|
||||
display->setCard(card);
|
||||
QList<CardInfoPtr> cardsInZone = getCardsMatchingGroup(deckListModel->getCardsAsCardInfoPtrsForZone(zoneName));
|
||||
|
||||
QList<CardInfoPictureWithTextOverlayWidget *> existingWidgets =
|
||||
overlapWidget->findChildren<CardInfoPictureWithTextOverlayWidget *>();
|
||||
|
||||
QHash<QString, int> requiredCounts;
|
||||
for (const CardInfoPtr &card : cardsInZone) {
|
||||
requiredCounts[card->getName()]++;
|
||||
}
|
||||
|
||||
QHash<QString, QList<CardInfoPictureWithTextOverlayWidget *>> widgetMap;
|
||||
for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) {
|
||||
widgetMap[widget->getInfo()->getName()].append(widget);
|
||||
}
|
||||
|
||||
for (auto it = widgetMap.begin(); it != widgetMap.end(); ++it) {
|
||||
QString name = it.key();
|
||||
QList<CardInfoPictureWithTextOverlayWidget *> &widgets = it.value();
|
||||
|
||||
int neededCount = requiredCounts.value(name, 0);
|
||||
while (widgets.size() > neededCount) {
|
||||
CardInfoPictureWithTextOverlayWidget *widgetToRemove = widgets.takeLast();
|
||||
overlapWidget->removeWidget(widgetToRemove);
|
||||
delete widgetToRemove;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = requiredCounts.begin(); it != requiredCounts.end(); ++it) {
|
||||
QString name = it.key();
|
||||
int missingCount = it.value() - widgetMap[name].size();
|
||||
|
||||
for (int i = 0; i < missingCount; ++i) {
|
||||
auto *display = new CardInfoPictureWithTextOverlayWidget(overlapWidget, true);
|
||||
|
||||
auto cardIt = std::find_if(cardsInZone.begin(), cardsInZone.end(),
|
||||
[&](const CardInfoPtr &c) { return c->getName() == name; });
|
||||
|
||||
if (cardIt != cardsInZone.end()) {
|
||||
display->setCard(*cardIt);
|
||||
}
|
||||
|
||||
connect(display, &CardInfoPictureWithTextOverlayWidget::imageClicked, this,
|
||||
&OverlappedCardGroupDisplayWidget::onClick);
|
||||
connect(display, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this,
|
||||
&OverlappedCardGroupDisplayWidget::onHover);
|
||||
|
||||
connect(display, SIGNAL(imageClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this,
|
||||
SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)));
|
||||
connect(display, SIGNAL(hoveredOnCard(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr)));
|
||||
overlapWidget->addWidget(display);
|
||||
}
|
||||
}
|
||||
|
||||
overlapWidget->adjustMaxColumnsAndRows();
|
||||
}
|
||||
|
||||
QList<CardInfoPtr> OverlappedCardGroupDisplayWidget::getCardsMatchingGroup(QList<CardInfoPtr> *cardsToSort)
|
||||
{
|
||||
QList<CardInfoPtr> activeList;
|
||||
|
||||
QStringList sortCriteria;
|
||||
sortCriteria.append(activeSortCriteria);
|
||||
sortCardList(cardsToSort, sortCriteria, Qt::SortOrder::AscendingOrder);
|
||||
|
||||
for (int i = 0; i < cardsToSort->size(); ++i) {
|
||||
CardInfoPtr info = cardsToSort->at(i);
|
||||
if (info) {
|
||||
if (info->getProperty(activeSortCriteria) == cardGroupCategory) {
|
||||
activeList.append(info);
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Card not found in database!";
|
||||
}
|
||||
}
|
||||
|
||||
return activeList;
|
||||
}
|
||||
|
||||
void OverlappedCardGroupDisplayWidget::sortCardList(QList<CardInfoPtr> *cardsToSort,
|
||||
const QStringList properties,
|
||||
Qt::SortOrder order = Qt::AscendingOrder)
|
||||
{
|
||||
CardInfoComparator comparator(properties, order);
|
||||
std::sort(cardsToSort->begin(), cardsToSort->end(), comparator);
|
||||
}
|
||||
|
||||
void OverlappedCardGroupDisplayWidget::onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card)
|
||||
{
|
||||
emit cardClicked(event, card);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef OVERLAPPED_CARD_GROUP_DISPLAY_WIDGET_H
|
||||
#define OVERLAPPED_CARD_GROUP_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../../../../game/cards/card_database.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
#include "../general/layout_containers/overlap_widget.h"
|
||||
|
|
@ -15,20 +16,32 @@ class OverlappedCardGroupDisplayWidget : public QWidget
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OverlappedCardGroupDisplayWidget(QWidget *parent, QList<CardInfoPtr> *cards, QString bannerText, int bannerOpacity);
|
||||
void addCardsToOverlapWidget();
|
||||
OverlappedCardGroupDisplayWidget(QWidget *parent,
|
||||
DeckListModel *deckListModel,
|
||||
QString zoneName,
|
||||
QString cardGroupCategory,
|
||||
QString activeSortCriteria,
|
||||
int bannerOpacity);
|
||||
|
||||
QList<CardInfoPtr> getCardsMatchingGroup(QList<CardInfoPtr> *cardsToSort);
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
DeckListModel *deckListModel;
|
||||
QString zoneName;
|
||||
QString cardGroupCategory;
|
||||
QString activeSortCriteria;
|
||||
|
||||
public slots:
|
||||
void sortCardList(QList<CardInfoPtr> *cardsToSort, QStringList properties, Qt::SortOrder order);
|
||||
void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
|
||||
void onHover(CardInfoPtr card);
|
||||
void updateCardDisplays();
|
||||
|
||||
signals:
|
||||
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
|
||||
void cardHovered(CardInfoPtr card);
|
||||
|
||||
private:
|
||||
QList<CardInfoPtr> *cardsToDisplay;
|
||||
QVBoxLayout *layout;
|
||||
BannerWidget *banner;
|
||||
OverlapWidget *overlapWidget;
|
||||
|
|
|
|||
|
|
@ -100,41 +100,26 @@ QHash<QString, int> ManaBaseWidget::analyzeManaBase()
|
|||
|
||||
QHash<QString, int> ManaBaseWidget::determineManaProduction(const QString &rulesText)
|
||||
{
|
||||
// Initialize mana counts
|
||||
QHash<QString, int> manaCounts;
|
||||
manaCounts.insert("W", 0);
|
||||
manaCounts.insert("U", 0);
|
||||
manaCounts.insert("B", 0);
|
||||
manaCounts.insert("R", 0);
|
||||
manaCounts.insert("G", 0);
|
||||
manaCounts.insert("C", 0);
|
||||
QHash<QString, int> manaCounts = {{"W", 0}, {"U", 0}, {"B", 0}, {"R", 0}, {"G", 0}, {"C", 0}};
|
||||
|
||||
// Define regex patterns for different mana production rules
|
||||
QRegularExpression tapAddColorless(R"(\{T\}:\s*Add\s*\{C\}|Add\s*one\s*colorless\s*mana)");
|
||||
QRegularExpression tapAddAnyColor(
|
||||
R"(\{T\}:\s*Add\s*one\s*mana\s*of\s*any\s*color|Add\s*one\s*mana\s*of\s*any\s*color)");
|
||||
QRegularExpression tapAddSpecificColor(
|
||||
R"(\{T\}:\s*Add\s*\{(W|U|B|R|G)\}|Add\s*one\s*(white|blue|black|red|green)\s*mana)");
|
||||
QString text = rulesText.toLower(); // Normalize case for matching
|
||||
|
||||
// Check for mana production rules in the text
|
||||
if (tapAddColorless.match(rulesText).hasMatch()) {
|
||||
manaCounts["C"] += 1; // Adds colorless mana
|
||||
// Quick keyword-based checks for any color and colorless mana
|
||||
if (text.contains("{t}: add one mana of any color") || text.contains("add one mana of any color")) {
|
||||
for (const auto &color : {QStringLiteral("W"), QStringLiteral("U"), QStringLiteral("B"), QStringLiteral("R"),
|
||||
QStringLiteral("G")}) {
|
||||
manaCounts[color]++;
|
||||
}
|
||||
}
|
||||
if (text.contains("{t}: add {c}") || text.contains("add one colorless mana")) {
|
||||
manaCounts["C"]++;
|
||||
}
|
||||
|
||||
if (tapAddAnyColor.match(rulesText).hasMatch()) {
|
||||
manaCounts["W"] += 1; // Assumes at least 1 of any color can be produced
|
||||
manaCounts["U"] += 1;
|
||||
manaCounts["B"] += 1;
|
||||
manaCounts["R"] += 1;
|
||||
manaCounts["G"] += 1;
|
||||
}
|
||||
|
||||
// Check for specific color production
|
||||
QRegularExpression specificColorRegex(R"(\{T\}:\s*Add\s*\{(W|U|B|R|G)\})");
|
||||
auto match = specificColorRegex.match(rulesText);
|
||||
// Optimized regex for specific mana symbols
|
||||
static const QRegularExpression specificColorRegex(R"(\{T\}:\s*Add\s*\{([WUBRG])\})");
|
||||
QRegularExpressionMatch match = specificColorRegex.match(rulesText);
|
||||
if (match.hasMatch()) {
|
||||
QString color = match.captured(1);
|
||||
manaCounts[color] += 1;
|
||||
manaCounts[match.captured(1)]++;
|
||||
}
|
||||
|
||||
return manaCounts;
|
||||
|
|
|
|||
|
|
@ -99,38 +99,29 @@ void ManaDevotionWidget::updateDisplay()
|
|||
// Function to count mana symbols W, U, B, R, G in the input string
|
||||
std::unordered_map<char, int> ManaDevotionWidget::countManaSymbols(const QString &manaString)
|
||||
{
|
||||
// Only track counts for W, U, B, R, G
|
||||
std::unordered_map<char, int> manaCounts = {{'W', 0}, {'U', 0}, {'B', 0}, {'R', 0}, {'G', 0}};
|
||||
|
||||
// Convert QString to std::string for regex processing
|
||||
std::string stdManaString = manaString.toStdString();
|
||||
std::regex regexPattern(R"(\{([WUBRG])\/([WUBRG])\})");
|
||||
std::string::const_iterator searchStart(stdManaString.cbegin());
|
||||
std::smatch match;
|
||||
|
||||
// Go through the string and find pairs within {}/ for W, U, B, R, G
|
||||
while (std::regex_search(searchStart, stdManaString.cend(), match, regexPattern)) {
|
||||
char mana1 = match[1].str()[0];
|
||||
char mana2 = match[2].str()[0];
|
||||
|
||||
// Increment the count for both mana symbols
|
||||
manaCounts[mana1]++;
|
||||
manaCounts[mana2]++;
|
||||
|
||||
// Move past the current match
|
||||
searchStart = match.suffix().first;
|
||||
}
|
||||
|
||||
// Now go through the string again but ignore the {}/ parts and non-WUBRG symbols
|
||||
for (int i = 0; i < manaString.size(); ++i) {
|
||||
int len = manaString.length();
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (manaString[i] == '{') {
|
||||
// Skip over the {X/Y} pattern
|
||||
while (manaString[i] != '}' && i < manaString.size()) {
|
||||
++i;
|
||||
++i; // Move past '{'
|
||||
if (i < len && manaCounts.find(manaString[i].toLatin1()) != manaCounts.end()) {
|
||||
char mana1 = manaString[i].toLatin1();
|
||||
++i; // Move to next character
|
||||
if (i < len && manaString[i] == '/') {
|
||||
++i; // Move past '/'
|
||||
if (i < len && manaCounts.find(manaString[i].toLatin1()) != manaCounts.end()) {
|
||||
char mana2 = manaString[i].toLatin1();
|
||||
manaCounts[mana1]++;
|
||||
manaCounts[mana2]++;
|
||||
}
|
||||
} else {
|
||||
manaCounts[mana1]++;
|
||||
}
|
||||
}
|
||||
while (i < len && manaString[i] != '}') {
|
||||
++i; // Skip to closing '}'
|
||||
}
|
||||
} else if (manaCounts.find(manaString[i].toLatin1()) != manaCounts.end()) {
|
||||
// If it's one of W, U, B, R, G, count it
|
||||
manaCounts[manaString[i].toLatin1()]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@
|
|||
VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_deckListModel)
|
||||
: QWidget(parent), deckListModel(_deckListModel)
|
||||
{
|
||||
this->mainDeckCards = new QList<CardInfoPtr>;
|
||||
this->sideboardCards = new QList<CardInfoPtr>;
|
||||
connect(deckListModel, &DeckListModel::dataChanged, this, &VisualDeckEditorWidget::decklistDataChanged);
|
||||
|
||||
// The Main Widget and Main Layout, which contain a single Widget: The Scroll Area
|
||||
|
|
@ -36,7 +34,9 @@ VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_
|
|||
<< "cmc"
|
||||
<< "name";
|
||||
sortByComboBox->addItems(sortProperties);
|
||||
connect(sortByComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(activeSortCriteriaChanged()));
|
||||
connect(sortByComboBox, &QComboBox::currentIndexChanged, this,
|
||||
&VisualDeckEditorWidget::actChangeActiveSortCriteria);
|
||||
actChangeActiveSortCriteria();
|
||||
|
||||
scrollArea = new QScrollArea();
|
||||
scrollArea->setWidgetResizable(true);
|
||||
|
|
@ -52,13 +52,63 @@ VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_
|
|||
scrollArea->addScrollBarWidget(zoneContainer, Qt::AlignHCenter);
|
||||
scrollArea->setWidget(zoneContainer);
|
||||
|
||||
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
|
||||
updateZoneWidgets();
|
||||
|
||||
overlap_control_widget = new OverlapControlWidget(80, 1, 1, Qt::Vertical, this);
|
||||
overlapControlWidget = new OverlapControlWidget(80, 1, 1, Qt::Vertical, this);
|
||||
|
||||
mainLayout->addWidget(sortByComboBox);
|
||||
mainLayout->addWidget(scrollArea);
|
||||
mainLayout->addWidget(overlap_control_widget);
|
||||
mainLayout->addWidget(overlapControlWidget);
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::updateZoneWidgets()
|
||||
{
|
||||
addZoneIfDoesNotExist();
|
||||
deleteZoneIfDoesNotExist();
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::addZoneIfDoesNotExist()
|
||||
{
|
||||
QList<DeckCardZoneDisplayWidget *> cardZoneDisplayWidgets =
|
||||
zoneContainer->findChildren<DeckCardZoneDisplayWidget *>();
|
||||
for (const QString &zone : *deckListModel->getZones()) {
|
||||
bool found = false;
|
||||
for (DeckCardZoneDisplayWidget *displayWidget : cardZoneDisplayWidgets) {
|
||||
if (displayWidget->zoneName == zone) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
DeckCardZoneDisplayWidget *zoneDisplayWidget =
|
||||
new DeckCardZoneDisplayWidget(zoneContainer, deckListModel, zone, activeSortCriteria, 20, 10);
|
||||
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardHovered, this, &VisualDeckEditorWidget::onHover);
|
||||
connect(zoneDisplayWidget, &DeckCardZoneDisplayWidget::cardClicked, this,
|
||||
&VisualDeckEditorWidget::onCardClick);
|
||||
connect(this, &VisualDeckEditorWidget::activeSortCriteriaChanged, zoneDisplayWidget,
|
||||
&DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged);
|
||||
zoneContainerLayout->addWidget(zoneDisplayWidget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::deleteZoneIfDoesNotExist()
|
||||
{
|
||||
QList<DeckCardZoneDisplayWidget *> cardZoneDisplayWidgets =
|
||||
zoneContainer->findChildren<DeckCardZoneDisplayWidget *>();
|
||||
for (DeckCardZoneDisplayWidget *displayWidget : cardZoneDisplayWidgets) {
|
||||
bool found = false;
|
||||
for (const QString &zone : *deckListModel->getZones()) {
|
||||
|
||||
if (displayWidget->zoneName == zone) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
zoneContainerLayout->removeWidget(displayWidget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::resizeEvent(QResizeEvent *event)
|
||||
|
|
@ -67,11 +117,10 @@ void VisualDeckEditorWidget::resizeEvent(QResizeEvent *event)
|
|||
zoneContainer->setMaximumWidth(scrollArea->viewport()->width());
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::activeSortCriteriaChanged()
|
||||
void VisualDeckEditorWidget::actChangeActiveSortCriteria()
|
||||
{
|
||||
activeSortCriteria = sortByComboBox->currentText();
|
||||
qDebug() << "activeSortCriteria changed: " << activeSortCriteria;
|
||||
updateDisplay();
|
||||
emit activeSortCriteriaChanged(activeSortCriteria);
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::decklistDataChanged(QModelIndex topLeft, QModelIndex bottomRight)
|
||||
|
|
@ -81,69 +130,7 @@ void VisualDeckEditorWidget::decklistDataChanged(QModelIndex topLeft, QModelInde
|
|||
(void)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.
|
||||
QTimer::singleShot(0, this, [this] { updateDisplay(); });
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::updateDisplay()
|
||||
{
|
||||
// Clear the layout first
|
||||
populateCards();
|
||||
zoneContainer = new QWidget(scrollArea);
|
||||
zoneContainer->setMaximumWidth(scrollArea->viewport()->width());
|
||||
zoneContainerLayout = new QVBoxLayout(zoneContainer);
|
||||
|
||||
DeckCardZoneDisplayWidget *mainBoardWidget =
|
||||
new DeckCardZoneDisplayWidget(zoneContainer, sortCards(mainDeckCards), tr("Mainboard"), 20, 10);
|
||||
connect(mainBoardWidget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr)));
|
||||
connect(mainBoardWidget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this,
|
||||
SLOT(onMainboardClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)));
|
||||
|
||||
DeckCardZoneDisplayWidget *sideBoardWidget =
|
||||
new DeckCardZoneDisplayWidget(zoneContainer, sortCards(sideboardCards), tr("Sideboard"), 40, 30);
|
||||
connect(sideBoardWidget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr)));
|
||||
connect(sideBoardWidget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this,
|
||||
SLOT(onSideboardClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)));
|
||||
|
||||
zoneContainerLayout->addWidget(mainBoardWidget);
|
||||
zoneContainerLayout->addWidget(sideBoardWidget);
|
||||
|
||||
scrollArea->setWidget(zoneContainer);
|
||||
update();
|
||||
}
|
||||
|
||||
QList<QPair<QString, QList<CardInfoPtr>>> VisualDeckEditorWidget::sortCards(QList<CardInfoPtr> *cardsToSort)
|
||||
{
|
||||
QList<QPair<QString, QList<CardInfoPtr>>> sortedCardGroups;
|
||||
QList<CardInfoPtr> activeList;
|
||||
|
||||
QStringList sortCriteria;
|
||||
sortCriteria.append(activeSortCriteria);
|
||||
sortCardList(sortCriteria, Qt::SortOrder::AscendingOrder);
|
||||
|
||||
QString lastSortCriteriaValue = cardsToSort->isEmpty() ? "" : cardsToSort->at(0)->getProperty(activeSortCriteria);
|
||||
|
||||
for (int i = 0; i < cardsToSort->size(); ++i) {
|
||||
CardInfoPtr info = cardsToSort->at(i);
|
||||
if (info) {
|
||||
QString currentCriteriaValue = info->getProperty(activeSortCriteria);
|
||||
if (currentCriteriaValue != lastSortCriteriaValue) {
|
||||
// Save the current tuple (criteriaValue, list) and start a new list
|
||||
sortedCardGroups.append(qMakePair(lastSortCriteriaValue, activeList));
|
||||
activeList.clear();
|
||||
lastSortCriteriaValue = currentCriteriaValue;
|
||||
}
|
||||
activeList.append(info);
|
||||
} else {
|
||||
qDebug() << "Card not found in database!";
|
||||
}
|
||||
}
|
||||
|
||||
// Add the last tuple to sortedCardGroups
|
||||
if (!activeList.isEmpty()) {
|
||||
sortedCardGroups.append(qMakePair(lastSortCriteriaValue, activeList));
|
||||
}
|
||||
|
||||
return sortedCardGroups;
|
||||
updateZoneWidgets();
|
||||
}
|
||||
|
||||
/*void VisualDeckEditorWidget::sortCards()
|
||||
|
|
@ -187,31 +174,9 @@ void VisualDeckEditorWidget::onHover(CardInfoPtr hoveredCard)
|
|||
emit activeCardChanged(hoveredCard);
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::onMainboardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance)
|
||||
void VisualDeckEditorWidget::onCardClick(QMouseEvent *event,
|
||||
CardInfoPictureWithTextOverlayWidget *instance,
|
||||
QString zoneName)
|
||||
{
|
||||
emit mainboardCardClicked(event, instance);
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::onSideboardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance)
|
||||
{
|
||||
emit sideboardCardClicked(event, instance);
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::populateCards()
|
||||
{
|
||||
mainDeckCards->clear();
|
||||
sideboardCards->clear();
|
||||
|
||||
if (!deckListModel)
|
||||
return;
|
||||
|
||||
mainDeckCards = deckListModel->getCardsAsCardInfoPtrsForZone(DECK_ZONE_MAIN);
|
||||
sideboardCards = deckListModel->getCardsAsCardInfoPtrsForZone(DECK_ZONE_SIDE);
|
||||
}
|
||||
|
||||
void VisualDeckEditorWidget::sortCardList(const QStringList properties, Qt::SortOrder order = Qt::AscendingOrder)
|
||||
{
|
||||
CardInfoComparator comparator(properties, order);
|
||||
std::sort(mainDeckCards->begin(), mainDeckCards->end(), comparator);
|
||||
std::sort(sideboardCards->begin(), sideboardCards->end(), comparator);
|
||||
emit cardClicked(event, instance, zoneName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,41 +17,34 @@ class VisualDeckEditorWidget : public QWidget
|
|||
public:
|
||||
explicit VisualDeckEditorWidget(QWidget *parent, DeckListModel *deckListModel);
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void updateDisplay();
|
||||
QWidget *displayCards(QList<QPair<QString, QList<CardInfoPtr>>> cardLists, int bannerOpacity);
|
||||
QList<QPair<QString, QList<CardInfoPtr>>> sortCards(QList<CardInfoPtr> *cardsToSort);
|
||||
|
||||
OverlapWidget *getSortedCards();
|
||||
void populateCards();
|
||||
void sortCardList(QStringList properties, Qt::SortOrder order);
|
||||
void setDeckList(const DeckList &new_deck_list_model);
|
||||
void setDeckList(const DeckList &_deckListModel);
|
||||
|
||||
public slots:
|
||||
void decklistDataChanged(QModelIndex topLeft, QModelIndex bottomRight);
|
||||
void updateZoneWidgets();
|
||||
void addZoneIfDoesNotExist();
|
||||
void deleteZoneIfDoesNotExist();
|
||||
|
||||
signals:
|
||||
void activeCardChanged(CardInfoPtr activeCard);
|
||||
void mainboardCardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
void sideboardCardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
void activeSortCriteriaChanged(QString activeSortCriteria);
|
||||
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||
|
||||
protected slots:
|
||||
void onHover(CardInfoPtr hoveredCard);
|
||||
void onMainboardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
void onSideboardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
void activeSortCriteriaChanged();
|
||||
void onCardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||
void actChangeActiveSortCriteria();
|
||||
|
||||
private:
|
||||
DeckListModel *deckListModel;
|
||||
QList<CardInfoPtr> *mainDeckCards;
|
||||
QList<CardInfoPtr> *sideboardCards;
|
||||
QVBoxLayout *mainLayout;
|
||||
QComboBox *sortByComboBox;
|
||||
QString activeSortCriteria = "maintype";
|
||||
FlowWidget *flowWidget;
|
||||
QScrollArea *scrollArea;
|
||||
QWidget *zoneContainer;
|
||||
QVBoxLayout *zoneContainerLayout;
|
||||
OverlapControlWidget *overlap_control_widget;
|
||||
OverlapControlWidget *overlapControlWidget;
|
||||
QWidget *container;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue