diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc
index 67cde480e..88d1e62dc 100644
--- a/cockatrice/cockatrice.qrc
+++ b/cockatrice/cockatrice.qrc
@@ -47,6 +47,8 @@
resources/icons/mana/U.svg
resources/icons/mana/W.svg
+ resources/backgrounds/home.png
+
resources/config/general.svg
resources/config/appearance.svg
resources/config/interface.svg
diff --git a/cockatrice/src/client/ui/widgets/general/home_styled_button.cpp b/cockatrice/src/client/ui/widgets/general/home_styled_button.cpp
index 975dd6c5d..e9a29c3ad 100644
--- a/cockatrice/src/client/ui/widgets/general/home_styled_button.cpp
+++ b/cockatrice/src/client/ui/widgets/general/home_styled_button.cpp
@@ -1,25 +1,82 @@
#include "home_styled_button.h"
-HomeStyledButton::HomeStyledButton(const QString &text, QWidget *parent) : QPushButton(text, parent)
+#include
+#include
+#include
+
+HomeStyledButton::HomeStyledButton(const QString &text, QPair _gradientColors, QWidget *parent)
+ : QPushButton(text, parent), gradientColors(_gradientColors)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- setStyleSheet(R"(
- QPushButton {
- font-size: 16px;
- padding: 10px;
- color: black;
- border: 1px solid #0b5e2e;
- border-radius: 6px;
- background: qlineargradient(x1:0, y1:1, x2:0, y2:0,
- stop:0 #92de58, stop:1 #139740);
- }
- QPushButton:hover {
- background: qlineargradient(x1:0, y1:1, x2:0, y2:0,
- stop:0 #aaf57a, stop:1 #1bb24e);
- }
- QPushButton:pressed {
- background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
- stop:0 #139740, stop:1 #0a4d23);
- }
-)");
+ setMinimumHeight(100); // or higher if needed
+ setStyleSheet(generateButtonStylesheet(gradientColors));
}
+
+QString HomeStyledButton::generateButtonStylesheet(const QPair &colors)
+{
+ QColor base1 = colors.first;
+ QColor base2 = colors.second;
+
+ QColor hover1 = base1.lighter(120); // 20% lighter
+ QColor hover2 = base2.lighter(120);
+
+ QColor pressed1 = base1.darker(130); // 30% darker
+ QColor pressed2 = base2.darker(130);
+
+ return QString(R"(
+ QPushButton {
+ font-size: 34px;
+ padding: 30px;
+ color: white;
+ border: 2px solid %1;
+ border-radius: 6px;
+ background: qlineargradient(x1:0, y1:1, x2:0, y2:0,
+ stop:0 %2, stop:1 %3);
+ }
+ QPushButton:hover {
+ background: qlineargradient(x1:0, y1:1, x2:0, y2:0,
+ stop:0 %4, stop:1 %5);
+ }
+ QPushButton:pressed {
+ background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
+ stop:0 %6, stop:1 %7);
+ }
+ )")
+ .arg(base1.name()) // border color
+ .arg(base1.name()) // normal gradient start
+ .arg(base2.name()) // normal gradient end
+ .arg(hover1.name()) // hover start
+ .arg(hover2.name()) // hover end
+ .arg(pressed1.name()) // pressed start
+ .arg(pressed2.name()); // pressed end
+}
+
+void HomeStyledButton::paintEvent(QPaintEvent *event)
+{
+ QString originalText = text();
+ setText(""); // Prevent QPushButton from drawing the text
+
+ QPushButton::paintEvent(event); // Draw background, borders, etc.
+
+ setText(originalText); // Restore text for internal logic
+
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.setRenderHint(QPainter::TextAntialiasing);
+
+ QFont font = this->font();
+ font.setBold(true);
+ painter.setFont(font);
+
+ QFontMetrics fm(font);
+ QSize textSize = fm.size(Qt::TextSingleLine, originalText);
+ QPointF center((width() - textSize.width()) / 2.0, (height() + textSize.height() / 2.0) / 2.0);
+
+ QPainterPath path;
+ path.addText(center, font, originalText);
+
+ painter.setPen(QPen(Qt::black, 2.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+ painter.setBrush(Qt::white);
+ painter.drawPath(path);
+}
+
diff --git a/cockatrice/src/client/ui/widgets/general/home_styled_button.h b/cockatrice/src/client/ui/widgets/general/home_styled_button.h
index 5020e61a5..2b71dbe7f 100644
--- a/cockatrice/src/client/ui/widgets/general/home_styled_button.h
+++ b/cockatrice/src/client/ui/widgets/general/home_styled_button.h
@@ -10,7 +10,13 @@ class HomeStyledButton : public QPushButton
{
Q_OBJECT
public:
- HomeStyledButton(const QString &text, QWidget *parent = nullptr);
+ HomeStyledButton(const QString &text, QPair gradientColors, QWidget *parent = nullptr);
+ QString generateButtonStylesheet(const QPair &colors);
+public slots:
+ void paintEvent(QPaintEvent *event) override;
+
+private:
+ QPair gradientColors;
};
#endif // HOME_STYLED_BUTTON_H
diff --git a/cockatrice/src/client/ui/widgets/general/home_widget.cpp b/cockatrice/src/client/ui/widgets/general/home_widget.cpp
index 956d3d5e1..5791a590a 100644
--- a/cockatrice/src/client/ui/widgets/general/home_widget.cpp
+++ b/cockatrice/src/client/ui/widgets/general/home_widget.cpp
@@ -4,6 +4,7 @@
#include "home_styled_button.h"
#include
+#include
#include
#include
@@ -12,6 +13,8 @@ HomeWidget::HomeWidget(QWidget *parent, TabSupervisor *_tabSupervisor)
{
layout = new QGridLayout(this);
+ gradientColors = extractDominantColors(background);
+
layout->addWidget(createSettingsButtonGroup("Settings"), 0, 0, Qt::AlignTop | Qt::AlignLeft);
layout->addWidget(createUpdatesButtonGroup("Updates"), 0, 2, Qt::AlignTop | Qt::AlignRight);
layout->addWidget(createNavigationButtonGroup("Navigation"), 2, 0, Qt::AlignBottom | Qt::AlignLeft);
@@ -32,6 +35,7 @@ QGroupBox *HomeWidget::createSettingsButtonGroup(const QString &title)
QGroupBox {
font-size: 20px;
color: white; /* Title text color */
+ background: transparent;
}
QGroupBox::title {
@@ -42,7 +46,7 @@ QGroupBox *HomeWidget::createSettingsButtonGroup(const QString &title)
)");
QVBoxLayout *layout = new QVBoxLayout;
layout->setAlignment(Qt::AlignHCenter); // Center widgets horizontally
- layout->addWidget(new HomeStyledButton("Settings"));
+ layout->addWidget(new HomeStyledButton("Settings", gradientColors));
box->setLayout(layout);
return box;
}
@@ -54,6 +58,7 @@ QGroupBox *HomeWidget::createUpdatesButtonGroup(const QString &title)
QGroupBox {
font-size: 20px;
color: white; /* Title text color */
+ background: transparent;
}
QGroupBox::title {
@@ -64,7 +69,7 @@ QGroupBox *HomeWidget::createUpdatesButtonGroup(const QString &title)
)");
QVBoxLayout *layout = new QVBoxLayout;
layout->setAlignment(Qt::AlignHCenter); // Center widgets horizontally
- layout->addWidget(new HomeStyledButton("Updates"));
+ layout->addWidget(new HomeStyledButton("Updates", gradientColors));
box->setLayout(layout);
return box;
}
@@ -76,6 +81,7 @@ QGroupBox *HomeWidget::createNavigationButtonGroup(const QString &title)
QGroupBox {
font-size: 20px;
color: white; /* Title text color */
+ background: transparent;
}
QGroupBox::title {
@@ -87,20 +93,24 @@ QGroupBox *HomeWidget::createNavigationButtonGroup(const QString &title)
box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
QVBoxLayout *layout = new QVBoxLayout;
layout->setAlignment(Qt::AlignHCenter); // Center widgets horizontally
- auto replaybutton = new HomeStyledButton("View Replays");
+ auto replaybutton = new HomeStyledButton("View Replays", gradientColors);
connect(replaybutton, &QPushButton::clicked, tabSupervisor, [this] { tabSupervisor->actTabReplays(true); });
layout->addWidget(replaybutton);
- auto edhrecButton = new HomeStyledButton("Browse EDHRec");
+ auto edhrecButton = new HomeStyledButton("Browse EDHRec", gradientColors);
connect(edhrecButton, &QPushButton::clicked, tabSupervisor, &TabSupervisor::addEdhrecMainTab);
layout->addWidget(edhrecButton);
- auto visualDatabaseDisplayButton = new HomeStyledButton("Browse Card Database");
+ auto visualDatabaseDisplayButton = new HomeStyledButton("Browse Card Database", gradientColors);
connect(visualDatabaseDisplayButton, &QPushButton::clicked, tabSupervisor,
&TabSupervisor::addVisualDatabaseDisplayTab);
layout->addWidget(visualDatabaseDisplayButton);
- auto visualDeckStorageButton = new HomeStyledButton("Browse Decks");
+ auto visualDeckStorageButton = new HomeStyledButton("Browse Decks", gradientColors);
connect(visualDeckStorageButton, &QPushButton::clicked, tabSupervisor,
[this] { tabSupervisor->actTabVisualDeckStorage(true); });
layout->addWidget(visualDeckStorageButton);
+ auto visualDeckEditorButton = new HomeStyledButton("Create New Deck", gradientColors);
+ connect(visualDeckEditorButton, &QPushButton::clicked, tabSupervisor,
+ [this] { tabSupervisor->addVisualDeckEditorTab(nullptr); });
+ layout->addWidget(visualDeckEditorButton);
box->setLayout(layout);
return box;
}
@@ -112,6 +122,7 @@ QGroupBox *HomeWidget::createPlayButtonGroup(const QString &title)
QGroupBox {
font-size: 20px;
color: white; /* Title text color */
+ background: transparent;
}
QGroupBox::title {
@@ -124,27 +135,89 @@ QGroupBox *HomeWidget::createPlayButtonGroup(const QString &title)
QVBoxLayout *layout = new QVBoxLayout;
layout->setAlignment(Qt::AlignHCenter); // Center widgets horizontally
- auto connectButton = new HomeStyledButton("Connect");
+ auto connectButton = new HomeStyledButton("Connect", gradientColors);
layout->addWidget(connectButton, 1); // stretch factor 1
- auto playButton = new HomeStyledButton("Play");
+ auto playButton = new HomeStyledButton("Play", gradientColors);
layout->addWidget(playButton, 1);
box->setLayout(layout);
return box;
}
+QPair HomeWidget::extractDominantColors(const QPixmap &pixmap)
+{
+ // Step 1: Downscale image for performance
+ QImage image = pixmap.toImage()
+ .scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)
+ .convertToFormat(QImage::Format_RGB32);
+
+ QMap colorCount;
+
+ // Step 2: Count quantized colors
+ for (int y = 0; y < image.height(); ++y) {
+ const QRgb *scanLine = reinterpret_cast(image.scanLine(y));
+ for (int x = 0; x < image.width(); ++x) {
+ QColor color = QColor::fromRgb(scanLine[x]);
+
+ int r = color.red() & 0xF0;
+ int g = color.green() & 0xF0;
+ int b = color.blue() & 0xF0;
+
+ QRgb quantized = qRgb(r, g, b);
+ colorCount[quantized]++;
+ }
+ }
+
+ // Step 3: Sort by frequency
+ QVector> sortedColors;
+ for (auto it = colorCount.constBegin(); it != colorCount.constEnd(); ++it) {
+ sortedColors.append(qMakePair(it.key(), it.value()));
+ }
+
+ std::sort(sortedColors.begin(), sortedColors.end(),
+ [](const QPair &a, const QPair &b) { return a.second > b.second; });
+
+ // Step 4: Pick top two distinct colors
+ QColor first = QColor(sortedColors.value(0).first);
+ QColor second = first;
+
+ for (int i = 1; i < sortedColors.size(); ++i) {
+ QColor candidate = QColor(sortedColors[i].first);
+ if (candidate != first) {
+ second = candidate;
+ break;
+ }
+ }
+
+ return QPair(first, second);
+}
+
void HomeWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
- // Draw background to fill the widget
- painter.drawPixmap(rect(), background);
+ // Draw zoomed background
+ QSize widgetSize = size();
+ QSize bgSize = background.size();
+ QSize scaledSize = bgSize.scaled(widgetSize, Qt::KeepAspectRatioByExpanding);
+ QPoint topLeft((widgetSize.width() - scaledSize.width()) / 2, (widgetSize.height() - scaledSize.height()) / 2);
+ painter.drawPixmap(topLeft,
+ background.scaled(scaledSize, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
- // Draw overlay image centered
+ // Draw translucent black overlay with rounded corners
+ QRectF overlayRect(5, 5, width() - 10, height() - 10); // 5px inset
+ QPainterPath roundedRectPath;
+ roundedRectPath.addRoundedRect(overlayRect, 20, 20); // 20px corner radius
+
+ QColor semiTransparentBlack(0, 0, 0, static_cast(255 * 0.33)); // 33% opacity
+ painter.setRenderHint(QPainter::Antialiasing);
+ painter.fillPath(roundedRectPath, semiTransparentBlack);
+
+ // Draw centered overlay image
QSize overlaySize = overlay.size();
QPoint center((width() - overlaySize.width()) / 2, (height() - overlaySize.height()) / 2);
painter.drawPixmap(center, overlay);
- QWidget::paintEvent(event); // optional, depending on behavior
+ QWidget::paintEvent(event);
}
\ No newline at end of file
diff --git a/cockatrice/src/client/ui/widgets/general/home_widget.h b/cockatrice/src/client/ui/widgets/general/home_widget.h
index d94110b33..048605b7c 100644
--- a/cockatrice/src/client/ui/widgets/general/home_widget.h
+++ b/cockatrice/src/client/ui/widgets/general/home_widget.h
@@ -17,6 +17,7 @@ public:
QGroupBox *createUpdatesButtonGroup(const QString &title);
QGroupBox *createNavigationButtonGroup(const QString &title);
QGroupBox *createPlayButtonGroup(const QString &title);
+ QPair extractDominantColors(const QPixmap &pixmap);
public slots:
void paintEvent(QPaintEvent *event) override;
@@ -26,6 +27,7 @@ private:
TabSupervisor *tabSupervisor;
QPixmap background;
QPixmap overlay;
+ QPair gradientColors;
};
#endif // HOME_WIDGET_H