164 lines
6.5 KiB
C++
164 lines
6.5 KiB
C++
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||
|
|
||
|
#include <QHeaderView>
|
||
|
#include <QScrollBar>
|
||
|
#include "game_list_grid.h"
|
||
|
#include "game_list_grid_delegate.h"
|
||
|
#include "game_list_item.h"
|
||
|
|
||
|
GameListGrid::GameListGrid(const QSize& icon_size, QColor icon_color, const qreal& margin_factor,
|
||
|
const qreal& text_factor, const bool& showText)
|
||
|
: m_icon_size(icon_size), m_icon_color(std::move(icon_color)), m_margin_factor(margin_factor),
|
||
|
m_text_factor(text_factor), m_text_enabled(showText) {
|
||
|
setObjectName("game_grid");
|
||
|
|
||
|
QSize item_size;
|
||
|
if (m_text_enabled) {
|
||
|
item_size =
|
||
|
m_icon_size + QSize(m_icon_size.width() * m_margin_factor * 2,
|
||
|
m_icon_size.height() * m_margin_factor * (m_text_factor + 1));
|
||
|
} else {
|
||
|
item_size = m_icon_size + m_icon_size * m_margin_factor * 2;
|
||
|
}
|
||
|
|
||
|
grid_item_delegate = new GameListGridDelegate(item_size, m_margin_factor, m_text_factor, this);
|
||
|
setItemDelegate(grid_item_delegate);
|
||
|
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||
|
setSelectionBehavior(QAbstractItemView::SelectItems);
|
||
|
setSelectionMode(QAbstractItemView::SingleSelection);
|
||
|
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||
|
setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||
|
verticalScrollBar()->setSingleStep(20);
|
||
|
horizontalScrollBar()->setSingleStep(20);
|
||
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
||
|
verticalHeader()->setVisible(false);
|
||
|
horizontalHeader()->setVisible(false);
|
||
|
setShowGrid(false);
|
||
|
QPalette palette;
|
||
|
palette.setColor(QPalette::Base, QColor(230, 230, 230, 80));
|
||
|
setPalette(palette);
|
||
|
|
||
|
connect(this, &GameListTable::itemClicked, this, &GameListGrid::SetGridBackgroundImage);
|
||
|
connect(this, &GameListGrid::ResizedWindowGrid, this, &GameListGrid::SetGridBackgroundImage);
|
||
|
connect(this->verticalScrollBar(), &QScrollBar::valueChanged, this,
|
||
|
&GameListGrid::RefreshBackgroundImage);
|
||
|
connect(this->horizontalScrollBar(), &QScrollBar::valueChanged, this,
|
||
|
&GameListGrid::RefreshBackgroundImage);
|
||
|
}
|
||
|
|
||
|
void GameListGrid::enableText(const bool& enabled) {
|
||
|
m_text_enabled = enabled;
|
||
|
}
|
||
|
|
||
|
void GameListGrid::setIconSize(const QSize& size) const {
|
||
|
if (m_text_enabled) {
|
||
|
grid_item_delegate->setItemSize(
|
||
|
size + QSize(size.width() * m_margin_factor * 2,
|
||
|
size.height() * m_margin_factor * (m_text_factor + 1)));
|
||
|
} else {
|
||
|
grid_item_delegate->setItemSize(size + size * m_margin_factor * 2);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GameListItem* GameListGrid::addItem(const game_info& app, const QString& name, const int& row,
|
||
|
const int& col) {
|
||
|
GameListItem* item = new GameListItem;
|
||
|
item->set_icon_func([this, app, item](int) {
|
||
|
const qreal device_pixel_ratio = devicePixelRatioF();
|
||
|
|
||
|
// define size of expanded image, which is raw image size + margins
|
||
|
QSizeF exp_size_f;
|
||
|
if (m_text_enabled) {
|
||
|
exp_size_f =
|
||
|
m_icon_size + QSizeF(m_icon_size.width() * m_margin_factor * 2,
|
||
|
m_icon_size.height() * m_margin_factor * (m_text_factor + 1));
|
||
|
} else {
|
||
|
exp_size_f = m_icon_size + m_icon_size * m_margin_factor * 2;
|
||
|
}
|
||
|
|
||
|
// define offset for raw image placement
|
||
|
QPoint offset(m_icon_size.width() * m_margin_factor,
|
||
|
m_icon_size.height() * m_margin_factor);
|
||
|
const QSize exp_size = (exp_size_f * device_pixel_ratio).toSize();
|
||
|
|
||
|
// create empty canvas for expanded image
|
||
|
QImage exp_img(exp_size, QImage::Format_ARGB32);
|
||
|
exp_img.setDevicePixelRatio(device_pixel_ratio);
|
||
|
exp_img.fill(Qt::transparent);
|
||
|
|
||
|
// create background for image
|
||
|
QImage bg_img(app->pxmap.size(), QImage::Format_ARGB32);
|
||
|
bg_img.setDevicePixelRatio(device_pixel_ratio);
|
||
|
bg_img.fill(m_icon_color);
|
||
|
|
||
|
// place raw image inside expanded image
|
||
|
QPainter painter(&exp_img);
|
||
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||
|
painter.drawImage(offset, bg_img);
|
||
|
painter.drawPixmap(offset, app->pxmap);
|
||
|
app->pxmap = {};
|
||
|
painter.end();
|
||
|
|
||
|
// create item with expanded image, title and position
|
||
|
item->setData(Qt::ItemDataRole::DecorationRole, QPixmap::fromImage(exp_img));
|
||
|
});
|
||
|
if (m_text_enabled) {
|
||
|
item->setData(Qt::ItemDataRole::DisplayRole, name);
|
||
|
}
|
||
|
|
||
|
setItem(row, col, item);
|
||
|
return item;
|
||
|
}
|
||
|
|
||
|
qreal GameListGrid::getMarginFactor() const {
|
||
|
return m_margin_factor;
|
||
|
}
|
||
|
void GameListGrid::RefreshBackgroundImage() {
|
||
|
QPixmap blurredPixmap = QPixmap::fromImage(backgroundImage);
|
||
|
QPalette palette;
|
||
|
palette.setBrush(QPalette::Base, QBrush(blurredPixmap.scaled(size(), Qt::IgnoreAspectRatio)));
|
||
|
QColor transparentColor = QColor(135, 206, 235, 40);
|
||
|
palette.setColor(QPalette::Highlight, transparentColor);
|
||
|
this->setPalette(palette);
|
||
|
}
|
||
|
void GameListGrid::SetGridBackgroundImage(QTableWidgetItem* item) {
|
||
|
if (!item) {
|
||
|
// handle case where icon item does not exist
|
||
|
return;
|
||
|
}
|
||
|
QTableWidgetItem* iconItem = this->item(item->row(), item->column());
|
||
|
|
||
|
if (!iconItem) {
|
||
|
// handle case where icon item does not exist
|
||
|
return;
|
||
|
}
|
||
|
game_info gameinfo = GetGameInfoFromItem(iconItem);
|
||
|
QString pic1Path = QString::fromStdString(gameinfo->info.pic_path);
|
||
|
QString blurredPic1Path =
|
||
|
qApp->applicationDirPath() +
|
||
|
QString::fromStdString("/game_data/" + gameinfo->info.serial + "/pic1.png");
|
||
|
|
||
|
backgroundImage = QImage(blurredPic1Path);
|
||
|
if (backgroundImage.isNull()) {
|
||
|
QImage image(pic1Path);
|
||
|
backgroundImage = m_game_list_utils.BlurImage(image, image.rect(), 18);
|
||
|
|
||
|
std::filesystem::path img_path =
|
||
|
std::filesystem::path("game_data/") / gameinfo->info.serial;
|
||
|
std::filesystem::create_directories(img_path);
|
||
|
if (!backgroundImage.save(blurredPic1Path, "PNG")) {
|
||
|
// qDebug() << "Error: Unable to save image.";
|
||
|
}
|
||
|
}
|
||
|
QPixmap blurredPixmap = QPixmap::fromImage(backgroundImage);
|
||
|
QPalette palette;
|
||
|
palette.setBrush(QPalette::Base, QBrush(blurredPixmap.scaled(size(), Qt::IgnoreAspectRatio)));
|
||
|
QColor transparentColor = QColor(135, 206, 235, 40);
|
||
|
palette.setColor(QPalette::Highlight, transparentColor);
|
||
|
this->setPalette(palette);
|
||
|
}
|
||
|
|
||
|
void GameListGrid::resizeEvent(QResizeEvent* event) {
|
||
|
Q_EMIT ResizedWindowGrid(this->currentItem());
|
||
|
}
|