mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-16 15:32:15 -07:00
New visual deck storage (#5290)
* Add TabDeckStorageVisual * Visual Deck Storage * Add BannerCard to .cod format, use it in the visual deck storage widget. * Show filename instead of deckname if deck name is empty. * Lint. * Don't delint cmake list through hooks. * Add deck loading functionality. * Open Decks on double click, not single click. * Void event for now. * Fix build issue with overload? * Fix build issue with overload? * Include QDebug. * Turn the tab into a widget. * Move the signals down to the widget, move the connections and slots up to the parent widgets. * No banner card equals an empty CardInfoPtr. * Add an option to sort by filename or last modified. * Flip last modified comparison. * Lint. * Don't open decks twice in the storage tab. * Fix unload deck not working by showing/hiding widgets instead of adding/removing to layout. * Add a search bar. * Add a card size slider. * Lint. * Lint. * Lint. * Fix settings mocks. * No need to QDebug. * No need to QDebug. * Member variable. * Member variable. * Non-lambda. * Change set to list conversion. * Specify overload. * Include MouseEvent * Adjust font size dynamically. * Add an option to show the visual deck storage on database load. * Fix the close button not working on the tab, add an option to launch the visual deck storage tab to Cockatrice menu. * Override virtual functions. * Correct tab text. * Add a setting to remember last used sorting order for visual deck storage widget. * Update banner card combo box correctly. * Fix mocks. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> Co-authored-by: Zach H <zahalpern+github@gmail.com>
This commit is contained in:
parent
7496e79e8c
commit
62f7c7f9ce
30 changed files with 834 additions and 31 deletions
|
|
@ -96,16 +96,12 @@ void CardInfoPictureWithTextOverlayWidget::paintEvent(QPaintEvent *event)
|
|||
// Call the base class's paintEvent to draw the card image
|
||||
CardInfoPictureWidget::paintEvent(event);
|
||||
|
||||
// Now add the custom text overlay on top of the image
|
||||
// If no overlay text, skip drawing the text
|
||||
if (overlayText.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QStylePainter painter(this);
|
||||
|
||||
// Set text properties
|
||||
QFont font = painter.font();
|
||||
font.setPointSize(fontSize);
|
||||
painter.setFont(font);
|
||||
QStylePainter painter(this);
|
||||
|
||||
// Get the pixmap from the base class using the getter
|
||||
const QPixmap &pixmap = getResizedPixmap();
|
||||
|
|
@ -118,13 +114,34 @@ void CardInfoPictureWithTextOverlayWidget::paintEvent(QPaintEvent *event)
|
|||
const QPoint topLeft{(width() - scaledSize.width()) / 2, (height() - scaledSize.height()) / 2};
|
||||
const QRect pixmapRect(topLeft, scaledSize);
|
||||
|
||||
// Prepare text wrapping
|
||||
const QFontMetrics fontMetrics(font);
|
||||
const int lineHeight = fontMetrics.height();
|
||||
const int textWidth = pixmapRect.width();
|
||||
QString wrappedText;
|
||||
// Calculate the optimal font size
|
||||
QFont font = painter.font();
|
||||
int optimalFontSize = fontSize; // Start with the user-defined font size
|
||||
const QFontMetrics baseMetrics(font);
|
||||
int textWidth = pixmapRect.width();
|
||||
|
||||
// Break the text into multiple lines to fit within the pixmap width
|
||||
// Reduce the font size until the text fits within the pixmap's width
|
||||
do {
|
||||
font.setPointSize(optimalFontSize);
|
||||
QFontMetrics fm(font);
|
||||
int currentWidth = 0;
|
||||
for (const QString &word : overlayText.split(' ')) {
|
||||
currentWidth = std::max(currentWidth, fm.horizontalAdvance(word));
|
||||
}
|
||||
|
||||
if (currentWidth <= textWidth) {
|
||||
break;
|
||||
}
|
||||
|
||||
--optimalFontSize;
|
||||
} while (optimalFontSize > 1);
|
||||
|
||||
// Apply the calculated font size
|
||||
painter.setFont(font);
|
||||
|
||||
// Wrap the text to fit within the pixmap width
|
||||
const QFontMetrics fontMetrics(font);
|
||||
QString wrappedText;
|
||||
QString currentLine;
|
||||
QStringList words = overlayText.split(' ');
|
||||
for (const QString &word : words) {
|
||||
|
|
@ -141,13 +158,22 @@ void CardInfoPictureWithTextOverlayWidget::paintEvent(QPaintEvent *event)
|
|||
wrappedText += currentLine;
|
||||
|
||||
// Calculate total text block height
|
||||
const int totalTextHeight = static_cast<int>(wrappedText.count('\n')) * lineHeight + lineHeight;
|
||||
int totalTextHeight = wrappedText.count('\n') * fontMetrics.height() + fontMetrics.height();
|
||||
|
||||
// Adjust font size if the total text height exceeds the pixmap height
|
||||
while (totalTextHeight > pixmapRect.height() && optimalFontSize > 1) {
|
||||
--optimalFontSize;
|
||||
font.setPointSize(optimalFontSize);
|
||||
painter.setFont(font);
|
||||
const QFontMetrics newMetrics(font);
|
||||
totalTextHeight = wrappedText.count('\n') * newMetrics.height() + newMetrics.height();
|
||||
}
|
||||
|
||||
// Set up the text layout options
|
||||
QTextOption textOption;
|
||||
textOption.setAlignment(textAlignment);
|
||||
|
||||
// Create a text rectangle centered within the pixmap rect
|
||||
// Create a text rectangle centered vertically within the pixmap rect
|
||||
auto textRect = QRect(pixmapRect.left(), pixmapRect.top(), pixmapRect.width(), totalTextHeight);
|
||||
textRect.moveTop((pixmapRect.height() - totalTextHeight) / 2 + pixmapRect.top());
|
||||
|
||||
|
|
@ -169,7 +195,6 @@ void CardInfoPictureWithTextOverlayWidget::drawOutlinedText(QPainter &painter,
|
|||
const QString &text,
|
||||
const QTextOption &textOption) const
|
||||
{
|
||||
// Draw the black outline (outlineColor)
|
||||
painter.setPen(outlineColor);
|
||||
for (int dx = -1; dx <= 1; ++dx) {
|
||||
for (int dy = -1; dy <= 1; ++dy) {
|
||||
|
|
@ -180,7 +205,7 @@ void CardInfoPictureWithTextOverlayWidget::drawOutlinedText(QPainter &painter,
|
|||
}
|
||||
}
|
||||
|
||||
// Draw the main text (textColor)
|
||||
// Draw the main text
|
||||
painter.setPen(textColor);
|
||||
painter.drawText(textRect, text, textOption);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include <QSize>
|
||||
#include <QTextOption>
|
||||
|
||||
class CardInfoPictureWithTextOverlayWidget final : public CardInfoPictureWidget
|
||||
class CardInfoPictureWithTextOverlayWidget : public CardInfoPictureWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#include "card_size_widget.h"
|
||||
|
||||
#include "../../../../settings/cache_settings.h"
|
||||
#include "../printing_selector/printing_selector.h"
|
||||
#include "../visual_deck_storage/visual_deck_storage_widget.h"
|
||||
|
||||
/**
|
||||
* @class CardSizeWidget
|
||||
|
|
@ -40,7 +42,12 @@ CardSizeWidget::CardSizeWidget(QWidget *parent, FlowWidget *flowWidget, int defa
|
|||
*/
|
||||
void CardSizeWidget::updateCardSizeSetting(int newValue)
|
||||
{
|
||||
SettingsCache::instance().setPrintingSelectorCardSize(newValue);
|
||||
// Check the type of the parent widget
|
||||
if ((parent = qobject_cast<PrintingSelector *>(parentWidget()))) {
|
||||
SettingsCache::instance().setPrintingSelectorCardSize(newValue);
|
||||
} else if ((parent = qobject_cast<VisualDeckStorageWidget *>(parentWidget()))) {
|
||||
SettingsCache::instance().setVisualDeckStorageCardSize(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ class CardSizeWidget : public QWidget
|
|||
public:
|
||||
explicit CardSizeWidget(QWidget *parent, FlowWidget *flowWidget = nullptr, int defaultValue = 100);
|
||||
[[nodiscard]] QSlider *getSlider() const;
|
||||
QWidget *parent;
|
||||
public slots:
|
||||
static void updateCardSizeSetting(int newValue);
|
||||
void updateCardSizeSetting(int newValue);
|
||||
|
||||
private:
|
||||
QWidget *parent;
|
||||
FlowWidget *flowWidget;
|
||||
QHBoxLayout *cardSizeLayout;
|
||||
QLabel *cardSizeLabel;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
#include "deck_preview_card_picture_widget.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFontMetrics>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainterPath>
|
||||
#include <QStylePainter>
|
||||
#include <QTextOption>
|
||||
|
||||
/**
|
||||
* @brief Constructs a CardPictureWithTextOverlay widget.
|
||||
* @param parent The parent widget.
|
||||
* @param hoverToZoomEnabled If this widget will spawn a larger widget when hovered over.
|
||||
* @param textColor The color of the overlay text.
|
||||
* @param outlineColor The color of the outline around the text.
|
||||
* @param fontSize The font size of the overlay text.
|
||||
* @param alignment The alignment of the text within the overlay.
|
||||
*
|
||||
* Sets the widget's size policy and default border style.
|
||||
*/
|
||||
DeckPreviewCardPictureWidget::DeckPreviewCardPictureWidget(QWidget *parent,
|
||||
const bool hoverToZoomEnabled,
|
||||
const QColor &textColor,
|
||||
const QColor &outlineColor,
|
||||
const int fontSize,
|
||||
const Qt::Alignment alignment)
|
||||
: CardInfoPictureWithTextOverlayWidget(parent, hoverToZoomEnabled, textColor, outlineColor, fontSize, alignment)
|
||||
{
|
||||
singleClickTimer = new QTimer(this);
|
||||
singleClickTimer->setSingleShot(true);
|
||||
connect(singleClickTimer, &QTimer::timeout, this, [this]() { emit imageClicked(lastMouseEvent, this); });
|
||||
}
|
||||
|
||||
void DeckPreviewCardPictureWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
lastMouseEvent = event;
|
||||
singleClickTimer->start(QApplication::doubleClickInterval());
|
||||
}
|
||||
}
|
||||
|
||||
void DeckPreviewCardPictureWidget::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
singleClickTimer->stop(); // Prevent single-click logic
|
||||
emit imageDoubleClicked(lastMouseEvent, this);
|
||||
}
|
||||
}
|
||||
|
||||
void DeckPreviewCardPictureWidget::setFilePath(const QString &_filePath)
|
||||
{
|
||||
filePath = _filePath;
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef DECK_PREVIEW_CARD_PICTURE_WIDGET_H
|
||||
#define DECK_PREVIEW_CARD_PICTURE_WIDGET_H
|
||||
|
||||
#include "card_info_picture_with_text_overlay_widget.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QSize>
|
||||
#include <QTextOption>
|
||||
|
||||
class DeckPreviewCardPictureWidget final : public CardInfoPictureWithTextOverlayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DeckPreviewCardPictureWidget(QWidget *parent = nullptr,
|
||||
bool hoverToZoomEnabled = false,
|
||||
const QColor &textColor = Qt::white,
|
||||
const QColor &outlineColor = Qt::black,
|
||||
int fontSize = 12,
|
||||
Qt::Alignment alignment = Qt::AlignCenter);
|
||||
|
||||
QString filePath;
|
||||
|
||||
signals:
|
||||
void imageClicked(QMouseEvent *event, DeckPreviewCardPictureWidget *instance);
|
||||
void imageDoubleClicked(QMouseEvent *event, DeckPreviewCardPictureWidget *instance);
|
||||
|
||||
public slots:
|
||||
void setFilePath(const QString &filePath);
|
||||
|
||||
private:
|
||||
QTimer *singleClickTimer;
|
||||
QMouseEvent *lastMouseEvent = nullptr; // Store the last mouse event
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
||||
};
|
||||
|
||||
#endif // DECK_PREVIEW_CARD_PICTURE_WIDGET_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue