mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-14 14:32:15 -07:00
Background and buttons and styles.
This commit is contained in:
parent
aa5a6222fd
commit
7bed1dc908
5 changed files with 173 additions and 33 deletions
|
|
@ -47,6 +47,8 @@
|
|||
<file>resources/icons/mana/U.svg</file>
|
||||
<file>resources/icons/mana/W.svg</file>
|
||||
|
||||
<file>resources/backgrounds/home.png</file>
|
||||
|
||||
<file>resources/config/general.svg</file>
|
||||
<file>resources/config/appearance.svg</file>
|
||||
<file>resources/config/interface.svg</file>
|
||||
|
|
|
|||
|
|
@ -1,25 +1,82 @@
|
|||
#include "home_styled_button.h"
|
||||
|
||||
HomeStyledButton::HomeStyledButton(const QString &text, QWidget *parent) : QPushButton(text, parent)
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <qgraphicseffect.h>
|
||||
|
||||
HomeStyledButton::HomeStyledButton(const QString &text, QPair<QColor, QColor> _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<QColor, QColor> &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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,13 @@ class HomeStyledButton : public QPushButton
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HomeStyledButton(const QString &text, QWidget *parent = nullptr);
|
||||
HomeStyledButton(const QString &text, QPair<QColor, QColor> gradientColors, QWidget *parent = nullptr);
|
||||
QString generateButtonStylesheet(const QPair<QColor, QColor> &colors);
|
||||
public slots:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private:
|
||||
QPair<QColor, QColor> gradientColors;
|
||||
};
|
||||
|
||||
#endif // HOME_STYLED_BUTTON_H
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "home_styled_button.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
|
@ -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<QColor, QColor> 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<QRgb, int> colorCount;
|
||||
|
||||
// Step 2: Count quantized colors
|
||||
for (int y = 0; y < image.height(); ++y) {
|
||||
const QRgb *scanLine = reinterpret_cast<const QRgb *>(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<QPair<QRgb, int>> 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<QRgb, int> &a, const QPair<QRgb, int> &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<QColor, QColor>(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<int>(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);
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ public:
|
|||
QGroupBox *createUpdatesButtonGroup(const QString &title);
|
||||
QGroupBox *createNavigationButtonGroup(const QString &title);
|
||||
QGroupBox *createPlayButtonGroup(const QString &title);
|
||||
QPair<QColor, QColor> extractDominantColors(const QPixmap &pixmap);
|
||||
|
||||
public slots:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
|
@ -26,6 +27,7 @@ private:
|
|||
TabSupervisor *tabSupervisor;
|
||||
QPixmap background;
|
||||
QPixmap overlay;
|
||||
QPair<QColor, QColor> gradientColors;
|
||||
};
|
||||
|
||||
#endif // HOME_WIDGET_H
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue