mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-24 10:23:02 -07:00
Merge bb4c489327 into b3c426cd43
This commit is contained in:
commit
68f1ad7c7d
4 changed files with 92 additions and 14 deletions
|
|
@ -22,6 +22,22 @@
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Below this row width the delegate switches to a compact layout so the card
|
||||||
|
// name stays readable when the popup cannot be as wide as PopupRowWidth.
|
||||||
|
constexpr int CompactRowWidth = 380;
|
||||||
|
constexpr int CompactSymbolRadius = 6;
|
||||||
|
constexpr int CompactSymbolSpacing = 1;
|
||||||
|
constexpr int CompactRightPad = 8;
|
||||||
|
constexpr int ManaZoneWidth = 110;
|
||||||
|
constexpr int CompactManaZoneWidth = 70;
|
||||||
|
constexpr int RightPad = 14;
|
||||||
|
constexpr int TextLeftPad = 12;
|
||||||
|
constexpr int TextRightGap = 8;
|
||||||
|
|
||||||
|
// Below this text width the type-line band is dropped so the name can use the
|
||||||
|
// whole row height instead of being elided to a single readable character.
|
||||||
|
constexpr int MinNameWidth = 120;
|
||||||
|
|
||||||
struct ManaColor
|
struct ManaColor
|
||||||
{
|
{
|
||||||
QColor fill;
|
QColor fill;
|
||||||
|
|
@ -101,7 +117,7 @@ QSize CardCompleterDelegate::sizeHint(const QStyleOptionViewItem &option, const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixed wide rows so the popup has room for name, type line, set and mana
|
// Fixed wide rows so the popup has room for name, type line, set and mana
|
||||||
return {480, CardRowHeight};
|
return {PopupRowWidth, CardRowHeight};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
@ -152,7 +168,12 @@ void CardCompleterDelegate::drawManaSymbol(QPainter *p, QPoint centre, const QSt
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
int CardCompleterDelegate::drawManaCost(QPainter *p, const QRect &row, const QString &manaCost, int radius) const
|
int CardCompleterDelegate::drawManaCost(QPainter *p,
|
||||||
|
const QRect &row,
|
||||||
|
const QString &manaCost,
|
||||||
|
int radius,
|
||||||
|
int spacing,
|
||||||
|
int rightPad) const
|
||||||
{
|
{
|
||||||
if (manaCost.isEmpty()) {
|
if (manaCost.isEmpty()) {
|
||||||
return row.right();
|
return row.right();
|
||||||
|
|
@ -181,11 +202,9 @@ int CardCompleterDelegate::drawManaCost(QPainter *p, const QRect &row, const QSt
|
||||||
totalW += PartGap;
|
totalW += PartGap;
|
||||||
}
|
}
|
||||||
|
|
||||||
totalW += parts.at(i).size() * diam + qMax(0, parts.at(i).size() - 1) * SymbolSpacing;
|
totalW += parts.at(i).size() * diam + qMax(0, parts.at(i).size() - 1) * spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int rightPad = 14;
|
|
||||||
|
|
||||||
int x = row.right() - rightPad - totalW + radius;
|
int x = row.right() - rightPad - totalW + radius;
|
||||||
|
|
||||||
const int cy = row.center().y();
|
const int cy = row.center().y();
|
||||||
|
|
@ -195,11 +214,11 @@ int CardCompleterDelegate::drawManaCost(QPainter *p, const QRect &row, const QSt
|
||||||
|
|
||||||
for (const QString &sym : symbols) {
|
for (const QString &sym : symbols) {
|
||||||
drawManaSymbol(p, {x, cy}, sym, radius);
|
drawManaSymbol(p, {x, cy}, sym, radius);
|
||||||
x += diam + SymbolSpacing;
|
x += diam + spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < parts.size() - 1) {
|
if (i < parts.size() - 1) {
|
||||||
x += PartGap - SymbolSpacing;
|
x += PartGap - spacing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,6 +285,14 @@ void CardCompleterDelegate::paint(QPainter *painter, const QStyleOptionViewItem
|
||||||
const QString typeLine = card->getCardType();
|
const QString typeLine = card->getCardType();
|
||||||
const QString setCode = setCodeForCard(card);
|
const QString setCode = setCodeForCard(card);
|
||||||
|
|
||||||
|
// When the row is too narrow for the full layout, use smaller mana pips and
|
||||||
|
// a slimmer mana zone so the card name keeps as much room as possible.
|
||||||
|
const bool compact = rect.width() < CompactRowWidth;
|
||||||
|
const int symbolRadius = compact ? CompactSymbolRadius : SymbolRadius;
|
||||||
|
const int symbolSpacing = compact ? CompactSymbolSpacing : SymbolSpacing;
|
||||||
|
const int rightPad = compact ? CompactRightPad : RightPad;
|
||||||
|
const int manaZoneWidth = compact ? CompactManaZoneWidth : ManaZoneWidth;
|
||||||
|
|
||||||
const QColor accent = accentForColors(card->getColors());
|
const QColor accent = accentForColors(card->getColors());
|
||||||
|
|
||||||
const QColor base = pal.color(QPalette::Base);
|
const QColor base = pal.color(QPalette::Base);
|
||||||
|
|
@ -314,7 +341,7 @@ void CardCompleterDelegate::paint(QPainter *painter, const QStyleOptionViewItem
|
||||||
// Right mana zone
|
// Right mana zone
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
const QRectF manaZone(cardRect.right() - 110, cardRect.top(), 110, cardRect.height());
|
const QRectF manaZone(cardRect.right() - manaZoneWidth, cardRect.top(), manaZoneWidth, cardRect.height());
|
||||||
|
|
||||||
QLinearGradient manaGrad(manaZone.topLeft(), manaZone.bottomLeft());
|
QLinearGradient manaGrad(manaZone.topLeft(), manaZone.bottomLeft());
|
||||||
|
|
||||||
|
|
@ -356,22 +383,27 @@ void CardCompleterDelegate::paint(QPainter *painter, const QStyleOptionViewItem
|
||||||
// Mana cost
|
// Mana cost
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
const int costLeft = drawManaCost(painter, cardRect.toRect(), manaCost, SymbolRadius);
|
const int costLeft = drawManaCost(painter, cardRect.toRect(), manaCost, symbolRadius, symbolSpacing, rightPad);
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Card name + type line + set code
|
// Card name + type line + set code
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
const int textLeft = cardRect.left() + AccentBarWidth + 12;
|
const int textLeft = cardRect.left() + AccentBarWidth + TextLeftPad;
|
||||||
const int textRight = costLeft - 8;
|
const int textRight = costLeft - TextRightGap;
|
||||||
const int textWidth = qMax(0, textRight - textLeft);
|
const int textWidth = qMax(0, textRight - textLeft);
|
||||||
|
|
||||||
|
// If even the compact layout leaves too little room for a readable name,
|
||||||
|
// drop the type-line band and let the name use the full row height.
|
||||||
|
const bool showInfoBand = textWidth >= MinNameWidth;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
// Card name (top band)
|
// Card name (top band)
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
{
|
{
|
||||||
const QRect nameRect(textLeft, rect.top() + 2, textWidth, 20);
|
const QRect nameRect = showInfoBand ? QRect(textLeft, rect.top() + 2, textWidth, 20)
|
||||||
|
: QRect(textLeft, rect.top() + 2, textWidth, rect.height() - 4);
|
||||||
|
|
||||||
QFont f = option.font;
|
QFont f = option.font;
|
||||||
f.setPixelSize(13);
|
f.setPixelSize(13);
|
||||||
|
|
@ -392,7 +424,7 @@ void CardCompleterDelegate::paint(QPainter *painter, const QStyleOptionViewItem
|
||||||
// Type line + set code (bottom band)
|
// Type line + set code (bottom band)
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
{
|
if (showInfoBand) {
|
||||||
const QRect infoRect(textLeft, rect.top() + 22, textWidth, rect.height() - 24);
|
const QRect infoRect(textLeft, rect.top() + 22, textWidth, rect.height() - 24);
|
||||||
|
|
||||||
QFont f = option.font;
|
QFont f = option.font;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@ public:
|
||||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||||
|
|
||||||
|
// Content width of one popup row; the completer popup is sized to fit it.
|
||||||
|
static constexpr int PopupRowWidth = 480;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Set short codes, resolved once per card name and cached
|
// Set short codes, resolved once per card name and cached
|
||||||
mutable QCache<QString, QString> setCodeCache;
|
mutable QCache<QString, QString> setCodeCache;
|
||||||
|
|
@ -42,7 +45,8 @@ private:
|
||||||
|
|
||||||
// Draw all mana pips for a cost string like "2RG" or "{2}{R}{G}"; split and
|
// Draw all mana pips for a cost string like "2RG" or "{2}{R}{G}"; split and
|
||||||
// adventure costs ("1W // W") are drawn as separate groups. Returns the left-most x used
|
// adventure costs ("1W // W") are drawn as separate groups. Returns the left-most x used
|
||||||
int drawManaCost(QPainter *p, const QRect &row, const QString &manaCost, int radius) const;
|
int
|
||||||
|
drawManaCost(QPainter *p, const QRect &row, const QString &manaCost, int radius, int spacing, int rightPad) const;
|
||||||
|
|
||||||
// Resolve the preferred printing's set short code for a card
|
// Resolve the preferred printing's set short code for a card
|
||||||
QString setCodeForCard(const QSharedPointer<CardInfo> &card) const;
|
QString setCodeForCard(const QSharedPointer<CardInfo> &card) const;
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,11 @@
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QPoint>
|
||||||
#include <QPropertyAnimation>
|
#include <QPropertyAnimation>
|
||||||
|
#include <QRect>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
|
#include <QScrollBar>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <libcockatrice/card/card_info.h>
|
#include <libcockatrice/card/card_info.h>
|
||||||
#include <libcockatrice/card/database/card_database_manager.h>
|
#include <libcockatrice/card/database/card_database_manager.h>
|
||||||
|
|
@ -86,6 +89,7 @@ bool CardCompleterStyler::eventFilter(QObject *obj, QEvent *ev)
|
||||||
case QEvent::Show:
|
case QEvent::Show:
|
||||||
case QEvent::Move:
|
case QEvent::Move:
|
||||||
case QEvent::Resize:
|
case QEvent::Resize:
|
||||||
|
applyPopupWidth();
|
||||||
updateOrientation();
|
updateOrientation();
|
||||||
reposition();
|
reposition();
|
||||||
break;
|
break;
|
||||||
|
|
@ -140,6 +144,43 @@ bool CardCompleterStyler::handlePopupKeyPress(QKeyEvent *event)
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CardCompleterStyler::applyPopupWidth()
|
||||||
|
{
|
||||||
|
auto *popup = completer->popup();
|
||||||
|
|
||||||
|
// QCompleter sizes its popup to the line edit, so a narrow search field
|
||||||
|
// would crush the rows. Ask for the width the rows are designed for (plus
|
||||||
|
// the frame and scrollbar) and let QWidget's geometry clamping keep the
|
||||||
|
// popup that wide, clamped to the screen it is shown on.
|
||||||
|
int contentWidth = CardCompleterDelegate::PopupRowWidth + popup->frameWidth() * 2;
|
||||||
|
if (auto *vbar = popup->verticalScrollBar(); vbar != nullptr) {
|
||||||
|
contentWidth += vbar->sizeHint().width();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QScreen *screen = popup->screen();
|
||||||
|
const QRect available = screen ? screen->availableGeometry() : QRect();
|
||||||
|
|
||||||
|
const int minWidth = available.isEmpty() ? contentWidth : qMin(contentWidth, available.width());
|
||||||
|
popup->setMinimumWidth(minWidth);
|
||||||
|
|
||||||
|
// Widen the popup right away on the first show; QCompleter has already
|
||||||
|
// positioned it for the narrow size, so keep it on screen afterwards.
|
||||||
|
if (popup->width() < minWidth) {
|
||||||
|
popup->resize(minWidth, popup->height());
|
||||||
|
|
||||||
|
if (!available.isEmpty()) {
|
||||||
|
// Clamp in screen coordinates, then map back to parent coordinates.
|
||||||
|
QPoint globalPos = popup->mapToGlobal(QPoint(0, 0));
|
||||||
|
int clampedGlobalX =
|
||||||
|
qBound(available.left(), globalPos.x(), qMax(available.left(), available.right() - popup->width() + 1));
|
||||||
|
QPoint parentPos = popup->mapFromGlobal(QPoint(clampedGlobalX, globalPos.y()));
|
||||||
|
popup->move(parentPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
void CardCompleterStyler::updateOrientation()
|
void CardCompleterStyler::updateOrientation()
|
||||||
{
|
{
|
||||||
above = isPopupAboveWidget();
|
above = isPopupAboveWidget();
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ private:
|
||||||
void stopPreviewFade();
|
void stopPreviewFade();
|
||||||
void reposition();
|
void reposition();
|
||||||
|
|
||||||
|
void applyPopupWidth();
|
||||||
void updateOrientation();
|
void updateOrientation();
|
||||||
void ensureClosestSelected();
|
void ensureClosestSelected();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue