55#include < QPainterPath>
66#include < QMouseEvent>
77#include < QLinearGradient>
8+ #include < QRadialGradient>
89#include < QFont>
910
1011GameCard::GameCard (QWidget* parent)
1112 : QWidget(parent)
1213{
13- setMinimumSize (140 , 120 );
14+ setMinimumSize (160 , 200 );
1415 setCursor (Qt::PointingHandCursor);
1516 setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Fixed);
16- setFixedHeight (180 );
17+ setFixedHeight (220 );
1718}
1819
1920void GameCard::setGameData (const QMap<QString, QString>& data) {
@@ -55,8 +56,9 @@ void GameCard::paintEvent(QPaintEvent* event) {
5556 painter.setRenderHint (QPainter::Antialiasing);
5657 painter.setRenderHint (QPainter::SmoothPixmapTransform);
5758
58- QRect cardRect = rect ().adjusted (4 , 4 , -4 , -4 );
59- int radius = 10 ;
59+ QRect cardRect = rect ().adjusted (5 , 5 , -5 , -5 );
60+ int radius = 14 ;
61+ bool supported = (m_data.value (" supported" ) == " true" );
6062
6163 // Clip to rounded rect
6264 QPainterPath clipPath;
@@ -66,84 +68,123 @@ void GameCard::paintEvent(QPaintEvent* event) {
6668 if (m_hasThumbnail) {
6769 // Stretch thumbnail to fill the entire card
6870 painter.drawPixmap (cardRect, m_thumbnail);
71+
72+ // Subtle dark vignette overlay for depth
73+ QRadialGradient vignette (cardRect.center (), cardRect.width () * 0.7 );
74+ vignette.setColorAt (0 , QColor (0 , 0 , 0 , 0 ));
75+ vignette.setColorAt (1 , QColor (0 , 0 , 0 , 80 ));
76+ painter.fillRect (cardRect, vignette);
6977 } else {
70- // Dark glass background
71- QLinearGradient bg (cardRect.topLeft (), cardRect.bottomLeft ());
72- bg.setColorAt (0 , QColor (30 , 41 , 59 , 200 ));
73- bg.setColorAt (1 , QColor (15 , 23 , 42 , 220 ));
78+ // Rich glass background gradient
79+ QLinearGradient bg (cardRect.topLeft (), cardRect.bottomRight ());
80+ bg.setColorAt (0 , QColor (30 , 41 , 59 , 220 ));
81+ bg.setColorAt (0.5 , QColor (20 , 30 , 48 , 230 ));
82+ bg.setColorAt (1 , QColor (10 , 18 , 32 , 240 ));
7483 painter.fillRect (cardRect, bg);
7584
85+ // Subtle pattern: inner glow
86+ QRadialGradient glow (cardRect.center (), cardRect.height () * 0.5 );
87+ glow.setColorAt (0 , QColor (59 , 130 , 246 , 15 ));
88+ glow.setColorAt (1 , QColor (0 , 0 , 0 , 0 ));
89+ painter.fillRect (cardRect, glow);
90+
7691 // Large default gamepad icon
77- QFont iconFont (" Segoe UI Emoji" , 40 );
92+ QFont iconFont (" Segoe UI Emoji" , 48 );
7893 painter.setFont (iconFont);
79- painter.setPen (QColor (148 , 163 , 184 , 120 ));
94+ painter.setPen (QColor (148 , 163 , 184 , 80 ));
8095
81- QRect iconArea = cardRect.adjusted (0 , 0 , 0 , -45 );
82- painter.drawText (iconArea, Qt::AlignCenter, QString::fromUtf8 (" 🎮 " ));
96+ QRect iconArea = cardRect.adjusted (0 , - 15 , 0 , -55 );
97+ painter.drawText (iconArea, Qt::AlignCenter, QString::fromUtf8 (" \xF0\x9F\x8E\xAE " ));
8398 }
8499
85- // Bottom info gradient overlay
86- int infoHeight = 50 ;
100+ // ---- Bottom info gradient overlay ----
101+ int infoHeight = 65 ;
87102 QRect infoRect (cardRect.left (), cardRect.bottom () - infoHeight, cardRect.width (), infoHeight);
88103
89104 QLinearGradient infoGrad (infoRect.topLeft (), infoRect.bottomLeft ());
90105 infoGrad.setColorAt (0 , QColor (0 , 0 , 0 , 0 ));
91- infoGrad.setColorAt (0.3 , QColor (0 , 0 , 0 , 160 ));
92- infoGrad.setColorAt (1 , QColor (0 , 0 , 0 , 220 ));
106+ infoGrad.setColorAt (0.25 , QColor (0 , 0 , 0 , 140 ));
107+ infoGrad.setColorAt (1 , QColor (0 , 0 , 0 , 230 ));
93108 painter.fillRect (infoRect, infoGrad);
94109
95- // Game name
110+ // Game name (larger, bolder)
96111 QString name = m_data.value (" name" , " Unknown" );
97- QFont nameFont (" Segoe UI" , 9 , QFont::Bold);
112+ QFont nameFont (" Segoe UI" , 10 , QFont::Bold);
98113 painter.setFont (nameFont);
99114 painter.setPen (Qt::white);
100115
101- QRect nameRect = infoRect.adjusted ( 8 , 6 , - 8 , - 16 );
116+ QRect nameRect (infoRect. left () + 12 , infoRect.top () + 10 , infoRect. width () - 24 , 22 );
102117 QFontMetrics fm (nameFont);
103118 QString elidedName = fm.elidedText (name, Qt::ElideRight, nameRect.width ());
104119 painter.drawText (nameRect, Qt::AlignLeft | Qt::AlignVCenter, elidedName);
105120
106- // Status line
107- bool supported = (m_data.value (" supported" ) == " true" );
108- QString statusText = supported ? " Supported" : " Not Indexed" ;
109- QString idText = QString (" ID: %1" ).arg (m_data.value (" appid" , " ?" ));
110-
111- QFont statusFont (" Segoe UI" , 7 );
112- painter.setFont (statusFont);
113- painter.setPen (supported ? Colors::toQColor (Colors::ACCENT_GREEN)
114- : QColor (148 , 163 , 184 ));
115-
116- QRect statusRect = infoRect.adjusted (8 , 20 , -8 , -2 );
117- painter.drawText (statusRect, Qt::AlignLeft | Qt::AlignVCenter,
118- QString (" %1 • %2" ).arg (statusText).arg (idText));
121+ // App ID line
122+ QFont idFont (" Segoe UI" , 8 );
123+ painter.setFont (idFont);
124+ painter.setPen (QColor (180 , 190 , 210 , 180 ));
125+ QRect idRect (infoRect.left () + 12 , infoRect.top () + 36 , infoRect.width () - 24 , 20 );
126+ painter.drawText (idRect, Qt::AlignLeft | Qt::AlignVCenter,
127+ QString (" ID: %1" ).arg (m_data.value (" appid" , " ?" )));
119128
120129 // Reset clip for border drawing
121130 painter.setClipRect (rect ());
122131
123- // Selection / hover border
132+ // ---- Border & glow effects ----
124133 if (m_selected) {
125- QPen selPen (Colors::toQColor (Colors::ACCENT_BLUE), 2.5 );
134+ // Outer glow
135+ for (int i = 3 ; i >= 1 ; --i) {
136+ QPen glowPen (QColor (59 , 130 , 246 , 30 * i), i * 1.5 );
137+ painter.setPen (glowPen);
138+ painter.setBrush (Qt::NoBrush);
139+ painter.drawRoundedRect (cardRect.adjusted (-i, -i, i, i), radius + i, radius + i);
140+ }
141+ // Main selection border
142+ QPen selPen (Colors::toQColor (Colors::ACCENT_BLUE), 2 );
126143 painter.setPen (selPen);
127144 painter.setBrush (Qt::NoBrush);
128- painter.drawRoundedRect (cardRect. adjusted ( 1 , 1 , - 1 , - 1 ) , radius, radius);
145+ painter.drawRoundedRect (cardRect, radius, radius);
129146 } else if (m_hovered) {
130- QPen hovPen (QColor (255 , 255 , 255 , 60 ), 1.5 );
147+ // Hover glow
148+ QPen hovPen (QColor (255 , 255 , 255 , 50 ), 1.5 );
131149 painter.setPen (hovPen);
132150 painter.setBrush (Qt::NoBrush);
133- painter.drawRoundedRect (cardRect.adjusted (1 , 1 , -1 , -1 ), radius, radius);
151+ painter.drawRoundedRect (cardRect, radius, radius);
152+
153+ // Subtle inner highlight at top
154+ painter.setClipPath (clipPath);
155+ QLinearGradient topShine (cardRect.topLeft (), QPoint (cardRect.left (), cardRect.top () + 40 ));
156+ topShine.setColorAt (0 , QColor (255 , 255 , 255 , 20 ));
157+ topShine.setColorAt (1 , QColor (255 , 255 , 255 , 0 ));
158+ painter.fillRect (QRect (cardRect.left (), cardRect.top (), cardRect.width (), 40 ), topShine);
159+ painter.setClipRect (rect ());
134160 } else {
135- // Subtle border
136- QPen borderPen (QColor (255 , 255 , 255 , 20 ), 1 );
161+ // Resting border
162+ QPen borderPen (QColor (255 , 255 , 255 , 15 ), 1 );
137163 painter.setPen (borderPen);
138164 painter.setBrush (Qt::NoBrush);
139- painter.drawRoundedRect (cardRect. adjusted ( 1 , 1 , - 1 , - 1 ) , radius, radius);
165+ painter.drawRoundedRect (cardRect, radius, radius);
140166 }
141167
142- // Supported accent dot (top-right)
168+ // Supported badge (top-right corner )
143169 if (supported) {
170+ painter.setClipPath (clipPath);
171+ // Green gradient badge
172+ QRect badge (cardRect.right () - 28 , cardRect.top () + 6 , 22 , 22 );
173+ QRadialGradient badgeGrad (badge.center (), 11 );
174+ badgeGrad.setColorAt (0 , Colors::toQColor (Colors::ACCENT_GREEN));
175+ badgeGrad.setColorAt (1 , QColor (16 , 185 , 129 , 180 ));
144176 painter.setPen (Qt::NoPen);
145- painter.setBrush (Colors::toQColor (Colors::ACCENT_GREEN));
146- painter.drawEllipse (cardRect.right () - 16 , cardRect.top () + 8 , 8 , 8 );
177+ painter.setBrush (badgeGrad);
178+ painter.drawEllipse (badge);
179+
180+ // Checkmark
181+ painter.setPen (QPen (Qt::white, 2 , Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
182+ QPainterPath check;
183+ check.moveTo (badge.left () + 5 , badge.center ().y ());
184+ check.lineTo (badge.center ().x () - 1 , badge.bottom () - 6 );
185+ check.lineTo (badge.right () - 5 , badge.top () + 6 );
186+ painter.drawPath (check);
187+ painter.setClipRect (rect ());
147188 }
148189}
149190
0 commit comments