[EDHRec] Display name above card, add bars for inclusion and synergy instead of coloring the whole label, card size slider (#5851)

* Display name above card, add bars for inclusion and synergy instead of coloring the whole label.

* Re-add commander label.

* Add a card size slider.

* Lint.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2025-04-19 00:28:44 +02:00 committed by GitHub
parent 2fe639676b
commit 3b1d6e394d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 252 additions and 25 deletions

View file

@ -24,7 +24,9 @@ set(cockatrice_SOURCES
src/client/tabs/api/edhrec/display/commander/edhrec_commander_api_response_navigation_widget.cpp
src/client/tabs/api/edhrec/display/card_prices/edhrec_api_response_card_prices_display_widget.cpp
src/client/tabs/api/edhrec/display/cards/edhrec_api_response_card_details_display_widget.cpp
src/client/tabs/api/edhrec/display/cards/edhrec_api_response_card_inclusion_display_widget.cpp
src/client/tabs/api/edhrec/display/cards/edhrec_api_response_card_list_display_widget.cpp
src/client/tabs/api/edhrec/display/cards/edhrec_api_response_card_synergy_display_widget.cpp
src/client/tabs/api/edhrec/display/commander/edhrec_api_response_commander_details_display_widget.cpp
src/client/tabs/api/edhrec/display/top_cards/edhrec_top_cards_api_response_display_widget.cpp
src/client/tabs/api/edhrec/display/top_commander/edhrec_top_commanders_api_response_display_widget.cpp
@ -99,6 +101,7 @@ set(cockatrice_SOURCES
src/client/ui/widgets/general/display/dynamic_font_size_label.cpp
src/client/ui/widgets/general/display/dynamic_font_size_push_button.cpp
src/client/ui/widgets/general/display/labeled_input.cpp
src/client/ui/widgets/general/display/percent_bar_widget.cpp
src/client/ui/widgets/general/display/shadow_background_label.cpp
src/client/ui/widgets/general/layout_containers/flow_widget.cpp
src/client/ui/widgets/general/layout_containers/overlap_control_widget.cpp

View file

@ -14,34 +14,18 @@ EdhrecApiResponseCardDetailsDisplayWidget::EdhrecApiResponseCardDetailsDisplayWi
cardPictureWidget = new CardInfoPictureWidget(this);
cardPictureWidget->setCard(CardDatabaseManager::getInstance()->guessCard(toDisplay.sanitized));
label = new QLabel(this);
label->setText(toDisplay.name + "\n" + toDisplay.label);
label->setAlignment(Qt::AlignHCenter);
nameLabel = new QLabel(this);
nameLabel->setText(toDisplay.name);
nameLabel->setAlignment(Qt::AlignHCenter);
int inclusionRate = 0;
// Set label color based on inclusion rate
if (toDisplay.potentialDecks != 0) {
inclusionRate = (toDisplay.numDecks * 100) / toDisplay.potentialDecks;
}
inclusionDisplayWidget = new EdhrecApiResponseCardInclusionDisplayWidget(this, toDisplay);
QColor labelColor;
if (inclusionRate <= 30) {
labelColor = QColor(255, 0, 0); // Red
} else if (inclusionRate <= 60) {
int red = 255 - ((inclusionRate - 30) * 2);
int green = (inclusionRate - 30) * 4; // Adjust green to make the transition smoother
labelColor = QColor(red, green, 0); // purple-ish
} else if (inclusionRate <= 90) {
int green = (inclusionRate - 60) * 5; // Increase green
labelColor = QColor(100, green, 100); // Green shades
} else {
labelColor = QColor(100, 200, 100); // Dark Green
}
label->setStyleSheet(QString("color: %1").arg(labelColor.name()));
synergyDisplayWidget = new EdhrecApiResponseCardSynergyDisplayWidget(this, toDisplay);
layout->addWidget(nameLabel);
layout->addWidget(cardPictureWidget);
layout->addWidget(label);
layout->addWidget(inclusionDisplayWidget);
layout->addWidget(synergyDisplayWidget);
QWidget *currentParent = parentWidget();
TabEdhRecMain *parentTab = nullptr;
@ -54,8 +38,11 @@ EdhrecApiResponseCardDetailsDisplayWidget::EdhrecApiResponseCardDetailsDisplayWi
}
if (parentTab) {
cardPictureWidget->setScaleFactor(parentTab->getCardSizeSlider()->getSlider()->value());
connect(cardPictureWidget, &CardInfoPictureWidget::cardClicked, this,
&EdhrecApiResponseCardDetailsDisplayWidget::actRequestPageNavigation);
connect(parentTab->getCardSizeSlider()->getSlider(), &QSlider::valueChanged, cardPictureWidget,
&CardInfoPictureWidget::setScaleFactor);
connect(this, &EdhrecApiResponseCardDetailsDisplayWidget::requestUrl, parentTab,
&TabEdhRecMain::actNavigatePage);
}

View file

@ -3,6 +3,8 @@
#include "../../../../../ui/widgets/cards/card_info_picture_widget.h"
#include "../../api_response/cards/edhrec_api_response_card_details.h"
#include "edhrec_api_response_card_inclusion_display_widget.h"
#include "edhrec_api_response_card_synergy_display_widget.h"
#include <QHBoxLayout>
#include <QLabel>
@ -22,7 +24,9 @@ private:
EdhrecApiResponseCardDetails toDisplay;
QVBoxLayout *layout;
CardInfoPictureWidget *cardPictureWidget;
QLabel *label;
QLabel *nameLabel;
EdhrecApiResponseCardInclusionDisplayWidget *inclusionDisplayWidget;
EdhrecApiResponseCardSynergyDisplayWidget *synergyDisplayWidget;
};
#endif // EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H

View file

@ -0,0 +1,41 @@
#include "edhrec_api_response_card_inclusion_display_widget.h"
EdhrecApiResponseCardInclusionDisplayWidget::EdhrecApiResponseCardInclusionDisplayWidget(
QWidget *parent,
const EdhrecApiResponseCardDetails &_toDisplay)
: QWidget(parent), toDisplay(_toDisplay)
{
layout = new QVBoxLayout(this);
setLayout(layout);
commanderLabel = new QLabel(this);
commanderLabel->setAlignment(Qt::AlignCenter);
amountLabel = new QLabel(this);
amountLabel->setAlignment(Qt::AlignCenter);
inclusionLabel = new QLabel(this);
inclusionLabel->setAlignment(Qt::AlignCenter);
percentBarWidget = new PercentBarWidget(this, toDisplay.inclusion / (toDisplay.potentialDecks / 100.0));
if (toDisplay.inclusion != 0 && toDisplay.potentialDecks != 0) {
layout->addWidget(amountLabel);
layout->addWidget(inclusionLabel);
layout->addWidget(percentBarWidget);
commanderLabel->hide();
} else {
amountLabel->hide();
inclusionLabel->hide();
percentBarWidget->hide();
layout->addWidget(commanderLabel);
}
retranslateUi();
}
void EdhrecApiResponseCardInclusionDisplayWidget::retranslateUi()
{
commanderLabel->setText(toDisplay.label);
amountLabel->setText(tr("In %1 decks").arg(QString::number(toDisplay.inclusion)));
inclusionLabel->setText(tr("%1% of %2 decks")
.arg(QString::number(toDisplay.inclusion / (toDisplay.potentialDecks / 100.0), 'f', 2),
QString::number(toDisplay.potentialDecks)));
}

View file

@ -0,0 +1,27 @@
#ifndef EDHREC_API_RESPONSE_CARD_INCLUSION_DISPLAY_WIDGET_H
#define EDHREC_API_RESPONSE_CARD_INCLUSION_DISPLAY_WIDGET_H
#include "../../../../../ui/widgets/general/display/percent_bar_widget.h"
#include "../../api_response/cards/edhrec_api_response_card_details.h"
#include <QLabel>
#include <QVBoxLayout>
#include <QWidget>
class EdhrecApiResponseCardInclusionDisplayWidget : public QWidget
{
Q_OBJECT
public:
EdhrecApiResponseCardInclusionDisplayWidget(QWidget *parent, const EdhrecApiResponseCardDetails &_toDisplay);
void retranslateUi();
private:
QVBoxLayout *layout;
EdhrecApiResponseCardDetails toDisplay;
QLabel *commanderLabel;
QLabel *amountLabel;
QLabel *inclusionLabel;
PercentBarWidget *percentBarWidget;
};
#endif // EDHREC_API_RESPONSE_CARD_INCLUSION_DISPLAY_WIDGET_H

View file

@ -0,0 +1,28 @@
#include "edhrec_api_response_card_synergy_display_widget.h"
EdhrecApiResponseCardSynergyDisplayWidget::EdhrecApiResponseCardSynergyDisplayWidget(
QWidget *parent,
const EdhrecApiResponseCardDetails &_toDisplay)
: QWidget(parent), toDisplay(_toDisplay)
{
layout = new QVBoxLayout(this);
setLayout(layout);
label = new QLabel(this);
label->setAlignment(Qt::AlignCenter);
percentBarWidget = new PercentBarWidget(this, toDisplay.synergy * 100.0);
if (toDisplay.synergy != 0) {
layout->addWidget(label);
layout->addWidget(percentBarWidget);
} else {
hide();
}
retranslateUi();
}
void EdhrecApiResponseCardSynergyDisplayWidget::retranslateUi()
{
label->setText(tr("%1% Synergy").arg(QString::number(toDisplay.synergy * 100.0, 'f', 1)));
}

View file

@ -0,0 +1,25 @@
#ifndef EDHREC_API_RESPONSE_CARD_SYNERGY_DISPLAY_WIDGET_H
#define EDHREC_API_RESPONSE_CARD_SYNERGY_DISPLAY_WIDGET_H
#include "../../../../../ui/widgets/general/display/percent_bar_widget.h"
#include "../../api_response/cards/edhrec_api_response_card_details.h"
#include <QLabel>
#include <QVBoxLayout>
#include <QWidget>
class EdhrecApiResponseCardSynergyDisplayWidget : public QWidget
{
Q_OBJECT
public:
EdhrecApiResponseCardSynergyDisplayWidget(QWidget *parent, const EdhrecApiResponseCardDetails &_toDisplay);
void retranslateUi();
private:
QVBoxLayout *layout;
EdhrecApiResponseCardDetails toDisplay;
QLabel *label;
PercentBarWidget *percentBarWidget;
};
#endif // EDHREC_API_RESPONSE_CARD_SYNERGY_DISPLAY_WIDGET_H

View file

@ -2,6 +2,7 @@
#include "../../../../../../game/cards/card_database_manager.h"
#include "../../../../../ui/widgets/cards/card_info_picture_widget.h"
#include "../../tab_edhrec_main.h"
#include "../card_prices/edhrec_api_response_card_prices_display_widget.h"
EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCommanderDetailsDisplayWidget(
@ -16,6 +17,22 @@ EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCom
commanderPicture = new CardInfoPictureWidget(this);
commanderPicture->setCard(CardDatabaseManager::getInstance()->getCard(commanderDetails.getName()));
QWidget *currentParent = parentWidget();
TabEdhRecMain *parentTab = nullptr;
while (currentParent) {
if ((parentTab = qobject_cast<TabEdhRecMain *>(currentParent))) {
break;
}
currentParent = currentParent->parentWidget();
}
if (parentTab) {
connect(parentTab->getCardSizeSlider()->getSlider(), &QSlider::valueChanged, commanderPicture,
&CardInfoPictureWidget::setScaleFactor);
commanderPicture->setScaleFactor(parentTab->getCardSizeSlider()->getSlider()->value());
}
commanderDetails.debugPrint();
label = new QLabel(this);

View file

@ -94,11 +94,18 @@ TabEdhRecMain::TabEdhRecMain(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor
searchPushButton = new QPushButton(navigationContainer);
connect(searchPushButton, &QPushButton::clicked, this, [=, this]() { doSearch(); });
settingsButton = new SettingsButtonWidget(this);
cardSizeSlider = new CardSizeWidget(this);
settingsButton->addSettingsWidget(cardSizeSlider);
navigationLayout->addWidget(cardsPushButton);
navigationLayout->addWidget(topCommandersPushButton);
navigationLayout->addWidget(tagsPushButton);
navigationLayout->addWidget(searchBar);
navigationLayout->addWidget(searchPushButton);
navigationLayout->addWidget(settingsButton);
currentPageDisplay = new QWidget(container);
currentPageLayout = new QVBoxLayout(currentPageDisplay);

View file

@ -2,7 +2,9 @@
#define TAB_EDHREC_MAIN_H
#include "../../../../game/cards/card_database.h"
#include "../../../ui/widgets/cards/card_size_widget.h"
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
#include "../../../ui/widgets/quick_settings/settings_button_widget.h"
#include "../../tab.h"
#include "display/commander/edhrec_commander_api_response_display_widget.h"
@ -25,6 +27,11 @@ public:
return tr("EDHREC: ") + cardName;
}
CardSizeWidget *getCardSizeSlider()
{
return cardSizeSlider;
}
QNetworkAccessManager *networkManager;
public slots:
@ -53,6 +60,8 @@ private:
QPushButton *tagsPushButton;
QLineEdit *searchBar;
QPushButton *searchPushButton;
SettingsButtonWidget *settingsButton;
CardSizeWidget *cardSizeSlider;
CardInfoPtr cardToQuery;
EdhrecCommanderApiResponseDisplayWidget *displayWidget;
};

View file

@ -0,0 +1,46 @@
#include "percent_bar_widget.h"
PercentBarWidget::PercentBarWidget(QWidget *parent, double initialValue) : QWidget(parent), valueToDisplay(initialValue)
{
setMinimumSize(50, 10);
}
void PercentBarWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
QRect rect = this->rect();
const int midX = rect.width() / 2;
const int height = rect.height();
// Draw background border (no fill)
painter.setPen(QPen(Qt::black, 1));
painter.setBrush(Qt::NoBrush);
painter.drawRect(rect.adjusted(0, 0, -1, -1)); // Avoid right/bottom overflow
const double halfWidth = rect.width() / 2.0;
const int barLength = static_cast<int>((qAbs(valueToDisplay) / 100.0) * halfWidth);
QRect fillRect;
if (valueToDisplay > 0.0) {
fillRect = QRect(midX, 0, barLength, height);
painter.fillRect(fillRect, Qt::green);
} else if (valueToDisplay < 0.0) {
fillRect = QRect(midX - barLength, 0, barLength, height);
painter.fillRect(fillRect, Qt::red);
}
// Draw center line at 0
painter.fillRect(midX - 1, 0, 3, height, Qt::white);
// Draw tick marks every 10%
const int tickHeight = 4;
for (int percent = -100; percent <= 100; percent += 10) {
int x = midX + static_cast<int>((percent / 100.0) * halfWidth);
painter.drawLine(x, height - tickHeight, x, height);
}
}

View file

@ -0,0 +1,33 @@
#ifndef PERCENT_BAR_WIDGET_H
#define PERCENT_BAR_WIDGET_H
#include <QColor>
#include <QPainter>
#include <QWidget>
class PercentBarWidget : public QWidget
{
Q_OBJECT
public:
explicit PercentBarWidget(QWidget *parent, double initialValue);
void setValue(double newValue)
{
valueToDisplay = qBound(-100.0, newValue, 100.0); // Clamp to [-100, 100]
update(); // Trigger repaint
}
double value() const
{
return valueToDisplay;
}
protected:
void paintEvent(QPaintEvent *event) override;
private:
double valueToDisplay; // Ranges from -100 to 100
};
#endif // PERCENT_BAR_WIDGET_H