mirror of https://github.com/RPCS3/rpcs3.git
Qt: add naive lazy loading to screenshot manager
This commit is contained in:
parent
f27de28ee9
commit
844f9683ec
|
@ -8,47 +8,49 @@
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
#include <QListWidget>
|
#include <QListWidget>
|
||||||
#include <QScreen>
|
#include <QScreen>
|
||||||
|
#include <QScrollBar>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <QtConcurrent>
|
||||||
|
|
||||||
screenshot_manager_dialog::screenshot_manager_dialog(QWidget* parent) : QDialog(parent)
|
screenshot_manager_dialog::screenshot_manager_dialog(QWidget* parent) : QDialog(parent)
|
||||||
{
|
{
|
||||||
setWindowTitle(tr("Screenshots"));
|
setWindowTitle(tr("Screenshots"));
|
||||||
|
|
||||||
|
m_icon_size = QSize(160, 90);
|
||||||
|
|
||||||
m_grid = new QListWidget(this);
|
m_grid = new QListWidget(this);
|
||||||
m_grid->setViewMode(QListWidget::IconMode);
|
m_grid->setViewMode(QListWidget::IconMode);
|
||||||
m_grid->setMovement(QListWidget::Static);
|
m_grid->setMovement(QListWidget::Static);
|
||||||
m_grid->setResizeMode(QListWidget::Adjust);
|
m_grid->setResizeMode(QListWidget::Adjust);
|
||||||
m_grid->setIconSize(QSize(160, 90));
|
m_grid->setIconSize(m_icon_size);
|
||||||
m_grid->setGridSize(m_grid->iconSize() + QSize(10, 10));
|
m_grid->setGridSize(m_icon_size + QSize(10, 10));
|
||||||
|
|
||||||
const std::string screen_path = fs::get_config_dir() + "screenshots/";
|
const std::string screen_path = fs::get_config_dir() + "screenshots/";
|
||||||
const QStringList filter{ QStringLiteral("*.png") };
|
const QStringList filter{ QStringLiteral("*.png") };
|
||||||
QDirIterator dir_iter(QString::fromStdString(screen_path), filter, QDir::Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
|
QDirIterator dir_iter(QString::fromStdString(screen_path), filter, QDir::Files | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
|
||||||
|
|
||||||
|
QPixmap placeholder(m_icon_size);
|
||||||
|
placeholder.fill(Qt::gray);
|
||||||
|
m_placeholder = QIcon(placeholder);
|
||||||
|
|
||||||
while (dir_iter.hasNext())
|
while (dir_iter.hasNext())
|
||||||
{
|
{
|
||||||
const QString filepath = dir_iter.next();
|
const QString filepath = dir_iter.next();
|
||||||
|
|
||||||
QListWidgetItem* item = new QListWidgetItem;
|
QListWidgetItem* item = new QListWidgetItem;
|
||||||
item->setData(Qt::UserRole, filepath);
|
item->setData(item_role::source, filepath);
|
||||||
item->setIcon(QIcon(filepath));
|
item->setData(item_role::loaded, false);
|
||||||
|
item->setIcon(m_placeholder);
|
||||||
item->setToolTip(filepath);
|
item->setToolTip(filepath);
|
||||||
|
|
||||||
m_grid->addItem(item);
|
m_grid->addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(m_grid, &QListWidget::itemDoubleClicked, [this](QListWidgetItem* item)
|
m_icon_loader = new QFutureWatcher<thumbnail>(this);
|
||||||
{
|
connect(m_icon_loader, &QFutureWatcher<QIcon>::resultReadyAt, this, &screenshot_manager_dialog::update_icon);
|
||||||
if (!item)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString filepath = item->data(Qt::UserRole).toString();
|
connect(m_grid, &QListWidget::itemDoubleClicked, this, &screenshot_manager_dialog::show_preview);
|
||||||
|
connect(m_grid->verticalScrollBar(), &QScrollBar::valueChanged, this, &screenshot_manager_dialog::update_icons);
|
||||||
screenshot_preview* preview = new screenshot_preview(filepath);
|
|
||||||
preview->show();
|
|
||||||
});
|
|
||||||
|
|
||||||
QVBoxLayout* layout = new QVBoxLayout;
|
QVBoxLayout* layout = new QVBoxLayout;
|
||||||
layout->setContentsMargins(0, 0, 0, 0);
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
@ -57,3 +59,89 @@ screenshot_manager_dialog::screenshot_manager_dialog(QWidget* parent) : QDialog(
|
||||||
|
|
||||||
resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);
|
resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
screenshot_manager_dialog::~screenshot_manager_dialog()
|
||||||
|
{
|
||||||
|
m_icon_loader->cancel();
|
||||||
|
m_icon_loader->waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void screenshot_manager_dialog::show_preview(QListWidgetItem* item)
|
||||||
|
{
|
||||||
|
if (!item)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString filepath = item->data(Qt::UserRole).toString();
|
||||||
|
|
||||||
|
screenshot_preview* preview = new screenshot_preview(filepath);
|
||||||
|
preview->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void screenshot_manager_dialog::update_icon(int index)
|
||||||
|
{
|
||||||
|
const thumbnail tn = m_icon_loader->resultAt(index);
|
||||||
|
|
||||||
|
if (QListWidgetItem* item = m_grid->item(tn.index))
|
||||||
|
{
|
||||||
|
item->setIcon(tn.icon);
|
||||||
|
item->setData(item_role::loaded, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void screenshot_manager_dialog::update_icons(int value)
|
||||||
|
{
|
||||||
|
const QRect visible_rect = rect();
|
||||||
|
|
||||||
|
QList<thumbnail> thumbnails_to_load;
|
||||||
|
|
||||||
|
const bool forward = value >= m_scrollbar_value;
|
||||||
|
m_scrollbar_value = value;
|
||||||
|
|
||||||
|
const int first = forward ? 0 : (m_grid->count() - 1);
|
||||||
|
const int last = forward ? (m_grid->count() - 1) : 0;
|
||||||
|
|
||||||
|
for (int i = first; forward ? i <= last : i >= last; forward ? ++i : --i)
|
||||||
|
{
|
||||||
|
if (QListWidgetItem* item = m_grid->item(i))
|
||||||
|
{
|
||||||
|
const bool is_loaded = item->data(item_role::loaded).toBool();
|
||||||
|
const bool is_visible = visible_rect.intersects(m_grid->visualItemRect(item));
|
||||||
|
|
||||||
|
if (is_visible)
|
||||||
|
{
|
||||||
|
if (!is_loaded)
|
||||||
|
{
|
||||||
|
thumbnails_to_load.push_back({ QIcon(), item->data(item_role::source).toString() , i });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (is_loaded)
|
||||||
|
{
|
||||||
|
item->setIcon(m_placeholder);
|
||||||
|
item->setData(item_role::loaded, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_icon_loader->isRunning())
|
||||||
|
{
|
||||||
|
m_icon_loader->cancel();
|
||||||
|
m_icon_loader->waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::function<thumbnail(thumbnail)> load = [icon_size = m_icon_size](thumbnail tn) -> thumbnail
|
||||||
|
{
|
||||||
|
QPixmap pixmap(tn.path);
|
||||||
|
tn.icon = QIcon(pixmap.scaled(icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
|
return tn;
|
||||||
|
};
|
||||||
|
|
||||||
|
m_icon_loader->setFuture(QtConcurrent::mapped(thumbnails_to_load, load));
|
||||||
|
}
|
||||||
|
|
||||||
|
void screenshot_manager_dialog::resizeEvent(QResizeEvent* event)
|
||||||
|
{
|
||||||
|
QDialog::resizeEvent(event);
|
||||||
|
update_icons(m_scrollbar_value);
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QSize>
|
||||||
|
|
||||||
class QListWidget;
|
class QListWidget;
|
||||||
|
class QListWidgetItem;
|
||||||
|
|
||||||
class screenshot_manager_dialog : public QDialog
|
class screenshot_manager_dialog : public QDialog
|
||||||
{
|
{
|
||||||
|
@ -10,7 +14,40 @@ class screenshot_manager_dialog : public QDialog
|
||||||
|
|
||||||
public:
|
public:
|
||||||
screenshot_manager_dialog(QWidget* parent = nullptr);
|
screenshot_manager_dialog(QWidget* parent = nullptr);
|
||||||
|
~screenshot_manager_dialog();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent* event) override;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void update_icon(int index);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void signal_icon_change(int index, const QString& path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void show_preview(QListWidgetItem* item);
|
||||||
|
void update_icons(int value);
|
||||||
|
|
||||||
|
enum item_role
|
||||||
|
{
|
||||||
|
source = Qt::UserRole,
|
||||||
|
loaded = Qt::UserRole + 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct thumbnail
|
||||||
|
{
|
||||||
|
QIcon icon;
|
||||||
|
QString path;
|
||||||
|
int index = 0;
|
||||||
|
};
|
||||||
|
|
||||||
QListWidget* m_grid = nullptr;
|
QListWidget* m_grid = nullptr;
|
||||||
|
|
||||||
|
QFutureWatcher<thumbnail>* m_icon_loader;
|
||||||
|
|
||||||
|
QSize m_icon_size;
|
||||||
|
QIcon m_placeholder;
|
||||||
|
|
||||||
|
int m_scrollbar_value = 0;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue