Roms List improvements
This commit is contained in:
+3
-1
@@ -171,7 +171,9 @@ qt_add_executable(kaizen
|
|||||||
src/frontend/Settings/InputSettings.hpp
|
src/frontend/Settings/InputSettings.hpp
|
||||||
src/frontend/Settings/InputSettings.cpp
|
src/frontend/Settings/InputSettings.cpp
|
||||||
src/utils/Options.cpp
|
src/utils/Options.cpp
|
||||||
src/utils/File.cpp)
|
src/utils/File.cpp
|
||||||
|
src/frontend/RomsList.hpp
|
||||||
|
src/frontend/RomsList.cpp)
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(MIO_LIB mio::mio_full_winapi)
|
set(MIO_LIB mio::mio_full_winapi)
|
||||||
|
|||||||
+20
-65
@@ -11,55 +11,6 @@
|
|||||||
#include <Options.hpp>
|
#include <Options.hpp>
|
||||||
#include <Scheduler.hpp>
|
#include <Scheduler.hpp>
|
||||||
|
|
||||||
RomsListTable::RomsListTable() {
|
|
||||||
verticalHeader()->hide();
|
|
||||||
horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
|
|
||||||
setSizePolicy({QSizePolicy::Maximum, QSizePolicy::Maximum});
|
|
||||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
|
||||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
||||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
||||||
setSortingEnabled(true);
|
|
||||||
setColumnCount(4);
|
|
||||||
setHorizontalHeaderItem(0, new QTableWidgetItem("Name"));
|
|
||||||
setHorizontalHeaderItem(1, new QTableWidgetItem("Regions"));
|
|
||||||
setHorizontalHeaderItem(2, new QTableWidgetItem("Last played"));
|
|
||||||
setHorizontalHeaderItem(3, new QTableWidgetItem("Time played"));
|
|
||||||
|
|
||||||
std::jthread([&] {
|
|
||||||
populate(Options::GetRomsPath());
|
|
||||||
emit populateFinished();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void RomsListTable::populate(const std::string &romsPath) {
|
|
||||||
if (!romsPath.empty()) {
|
|
||||||
for (const auto &file : fs::recursive_directory_iterator{romsPath}) {
|
|
||||||
if (!file.is_regular_file())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto filename = file.path().string();
|
|
||||||
|
|
||||||
bool isPlain = std::ranges::any_of(std::array{".n64", ".z64", ".v64"},
|
|
||||||
[&](const std::string &ext) { return file.path().extension() == ext; });
|
|
||||||
|
|
||||||
bool isArchive =
|
|
||||||
std::ranges::any_of(std::array{".zip", ".7z", ".rar", ".tar"},
|
|
||||||
[&](const std::string &ext) { return file.path().extension() == ext; });
|
|
||||||
|
|
||||||
if (!isArchive && !isPlain)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto rom = n64::Mem::LoadROM(isArchive, filename);
|
|
||||||
auto regions = n64::GameDB::match(rom);
|
|
||||||
|
|
||||||
if (rom.gameNameDB.empty())
|
|
||||||
rom.gameNameDB = fs::path(filename).stem().string();
|
|
||||||
|
|
||||||
romsList.push_back(
|
|
||||||
{rom.header.countryCode, rom.header.version, filename, rom.gameNameDB, regions, "Never", "0h 00m 00s"});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::UserScope) {
|
KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::UserScope) {
|
||||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||||
@@ -67,6 +18,10 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
SDL_AddGamepadMapping(gamecontrollerdb_str);
|
SDL_AddGamepadMapping(gamecontrollerdb_str);
|
||||||
hide();
|
hide();
|
||||||
|
|
||||||
|
settingsWindow = new SettingsWindow();
|
||||||
|
|
||||||
|
romsListTable = new RomsListTable(settingsWindow->general);
|
||||||
|
|
||||||
vulkanWidget = new RenderWidget();
|
vulkanWidget = new RenderWidget();
|
||||||
vulkanWidget->hide();
|
vulkanWidget->hide();
|
||||||
|
|
||||||
@@ -74,16 +29,16 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
centralWidget->addWidget(romsListTable);
|
centralWidget->addWidget(romsListTable);
|
||||||
centralWidget->addWidget(romPathNotSet);
|
centralWidget->addWidget(romPathNotSet);
|
||||||
|
|
||||||
populateRomsListThread = QThread::create([&] {
|
if (Options::GetRomsPath().empty())
|
||||||
populateRomsList(Options::GetRomsPath());
|
centralWidget->setCurrentWidget(romPathNotSet);
|
||||||
emit populateRomsListFinished();
|
else
|
||||||
});
|
centralWidget->setCurrentWidget(romsListTable);
|
||||||
|
|
||||||
populateRomsListThread->start();
|
connect(romsListTable, &RomsListTable::cleared, this, [&] { centralWidget->setCurrentWidget(romPathNotSet); });
|
||||||
|
|
||||||
connect(this, &KaizenGui::populateRomsListFinished, this, [&] {
|
connect(romsListTable, &RomsListTable::populateFinished, this, [&] {
|
||||||
for (int i = 0; i < romsList.size(); i++) {
|
for (int i = 0; i < romsListTable->size(); i++) {
|
||||||
const auto &[countryCode, version, _, name, regions, lastPlayed, timePlayed] = romsList[i];
|
const auto &[countryCode, version, _, name, regions, lastPlayed, timePlayed] = (*romsListTable)[i];
|
||||||
|
|
||||||
romsListTable->insertRow(i);
|
romsListTable->insertRow(i);
|
||||||
romsListTable->setItem(
|
romsListTable->setItem(
|
||||||
@@ -95,11 +50,12 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
romsListTable->setItem(i, 2, new QTableWidgetItem(lastPlayed.c_str()));
|
romsListTable->setItem(i, 2, new QTableWidgetItem(lastPlayed.c_str()));
|
||||||
romsListTable->setItem(i, 3, new QTableWidgetItem(timePlayed.c_str()));
|
romsListTable->setItem(i, 3, new QTableWidgetItem(timePlayed.c_str()));
|
||||||
}
|
}
|
||||||
|
romsListTable->resizeRowsToContents();
|
||||||
|
centralWidget->setCurrentWidget(romsListTable);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(this, &KaizenGui::romsListNeedsPopulation, this, [&] { populateRomsListThread->start(); });
|
connect(romsListTable, &QTableWidget::cellDoubleClicked, this,
|
||||||
|
[&](int row, int) { LoadROM((*romsListTable)[row].path); });
|
||||||
connect(romsListTable, &QTableWidget::cellDoubleClicked, this, [&](int row, int) { LoadROM(romsList[row].path); });
|
|
||||||
|
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
|
|
||||||
@@ -123,7 +79,6 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
setWindowTitle("Kaizen " KAIZEN_VERSION_STR);
|
setWindowTitle("Kaizen " KAIZEN_VERSION_STR);
|
||||||
setMinimumSize(640, 480);
|
setMinimumSize(640, 480);
|
||||||
setCentralWidget(centralWidget);
|
setCentralWidget(centralWidget);
|
||||||
centralWidget->setLayout(new QVBoxLayout());
|
|
||||||
|
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
|
|
||||||
@@ -193,10 +148,7 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
connect(exit, &QAction::triggered, this, &QMainWindow::close);
|
connect(exit, &QAction::triggered, this, &QMainWindow::close);
|
||||||
auto emulationMenu = menuBar()->addMenu("Emulation");
|
auto emulationMenu = menuBar()->addMenu("Emulation");
|
||||||
auto settingsMenu = emulationMenu->addAction("Settings");
|
auto settingsMenu = emulationMenu->addAction("Settings");
|
||||||
settingsWindow = new SettingsWindow();
|
|
||||||
connect(settingsMenu, &QAction::triggered, settingsWindow, &SettingsWindow::show);
|
connect(settingsMenu, &QAction::triggered, settingsWindow, &SettingsWindow::show);
|
||||||
connect(settingsWindow->general, &GeneralSettings::romFolderSelected, this,
|
|
||||||
[&] { emit romsListNeedsPopulation(); });
|
|
||||||
|
|
||||||
connect(settingsWindow->cpu, &CPUSettings::cpuTypeChanged, this, [&] {
|
connect(settingsWindow->cpu, &CPUSettings::cpuTypeChanged, this, [&] {
|
||||||
core.cpuType = Options::GetCpuType();
|
core.cpuType = Options::GetCpuType();
|
||||||
@@ -239,7 +191,10 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
emulationMenu->addAction(stop);
|
emulationMenu->addAction(stop);
|
||||||
connect(stop, &QAction::triggered, this, [&] {
|
connect(stop, &QAction::triggered, this, [&] {
|
||||||
Scheduler::GetInstance().EnqueueRelative(0, STOP);
|
Scheduler::GetInstance().EnqueueRelative(0, STOP);
|
||||||
centralWidget->setCurrentWidget(currentHomeWidget);
|
if (Options::GetRomsPath().empty())
|
||||||
|
centralWidget->setCurrentWidget(romPathNotSet);
|
||||||
|
else
|
||||||
|
centralWidget->setCurrentWidget(romsListTable);
|
||||||
});
|
});
|
||||||
|
|
||||||
auto helpMenu = menuBar()->addMenu("Help");
|
auto helpMenu = menuBar()->addMenu("Help");
|
||||||
|
|||||||
@@ -7,33 +7,10 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QDropEvent>
|
#include <QDropEvent>
|
||||||
#include <QDragEnterEvent>
|
#include <QDragEnterEvent>
|
||||||
#include <QTableWidget>
|
#include <RomsList.hpp>
|
||||||
#include <Core.hpp>
|
#include <Core.hpp>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
class EmuThread;
|
|
||||||
|
|
||||||
struct RomsListEntry {
|
|
||||||
u8 countryCode, version;
|
|
||||||
std::string path;
|
|
||||||
std::string name;
|
|
||||||
std::string region;
|
|
||||||
std::string lastPlayed;
|
|
||||||
std::string timePlayed;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RomsListTable : public QTableWidget {
|
|
||||||
Q_OBJECT
|
|
||||||
std::vector<RomsListEntry> romsList;
|
|
||||||
|
|
||||||
public:
|
|
||||||
RomsListTable();
|
|
||||||
public slots:
|
|
||||||
void populate(const std::string &);
|
|
||||||
signals:
|
|
||||||
void populateFinished();
|
|
||||||
};
|
|
||||||
|
|
||||||
class KaizenGui final : QMainWindow {
|
class KaizenGui final : QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
void updateKeys();
|
void updateKeys();
|
||||||
@@ -51,12 +28,12 @@ class KaizenGui final : QMainWindow {
|
|||||||
|
|
||||||
QWidget *currentHomeWidget;
|
QWidget *currentHomeWidget;
|
||||||
QLabel *romPathNotSet = new QLabel(R"(Kaizen could not find any ROMs. Set the path in "Settings -> General")");
|
QLabel *romPathNotSet = new QLabel(R"(Kaizen could not find any ROMs. Set the path in "Settings -> General")");
|
||||||
RomsListTable *romsListTable = new RomsListTable();
|
RomsListTable *romsListTable;
|
||||||
QStackedWidget *centralWidget = new QStackedWidget();
|
QStackedWidget *centralWidget = new QStackedWidget();
|
||||||
SettingsWindow *settingsWindow;
|
SettingsWindow *settingsWindow;
|
||||||
RenderWidget *vulkanWidget;
|
RenderWidget *vulkanWidget;
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
QThread *emuThread, *populateRomsListThread;
|
QThread *emuThread;
|
||||||
QTimer *statusBarTimer, *SDLeventsTimer;
|
QTimer *statusBarTimer, *SDLeventsTimer;
|
||||||
QLabel *fpsLabel;
|
QLabel *fpsLabel;
|
||||||
QLabel *cpuTypeLabel;
|
QLabel *cpuTypeLabel;
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
#include <RomsList.hpp>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QThread>
|
||||||
|
#include <GeneralSettings.hpp>
|
||||||
|
#include <Options.hpp>
|
||||||
|
#include <Mem.hpp>
|
||||||
|
|
||||||
|
RomsListTable::RomsListTable(GeneralSettings *general) {
|
||||||
|
verticalHeader()->hide();
|
||||||
|
horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
|
||||||
|
setSizePolicy({QSizePolicy::Maximum, QSizePolicy::Maximum});
|
||||||
|
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
|
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
|
setSortingEnabled(true);
|
||||||
|
setColumnCount(4);
|
||||||
|
setHorizontalHeaderItem(0, new QTableWidgetItem("Name"));
|
||||||
|
setHorizontalHeaderItem(1, new QTableWidgetItem("Regions"));
|
||||||
|
setHorizontalHeaderItem(2, new QTableWidgetItem("Last played"));
|
||||||
|
setHorizontalHeaderItem(3, new QTableWidgetItem("Time played"));
|
||||||
|
|
||||||
|
connect(general, &GeneralSettings::romFolderSelected, this, [&] {
|
||||||
|
std::thread popThread([&] {
|
||||||
|
populate(Options::GetRomsPath());
|
||||||
|
emit populateFinished();
|
||||||
|
});
|
||||||
|
|
||||||
|
popThread.detach();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(general, &GeneralSettings::romFolderCleared, this, [&] {
|
||||||
|
for (int i = 0; i < rowCount(); i++)
|
||||||
|
removeRow(i);
|
||||||
|
romsList = {};
|
||||||
|
emit cleared();
|
||||||
|
});
|
||||||
|
|
||||||
|
std::thread popThread([&] {
|
||||||
|
populate(Options::GetRomsPath());
|
||||||
|
emit populateFinished();
|
||||||
|
});
|
||||||
|
|
||||||
|
popThread.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RomsListTable::populate(const std::string &romsPath) {
|
||||||
|
if (!romsPath.empty()) {
|
||||||
|
for (const auto &file : fs::recursive_directory_iterator{romsPath}) {
|
||||||
|
if (!file.is_regular_file())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto filename = file.path().string();
|
||||||
|
|
||||||
|
bool isPlain = std::ranges::any_of(std::array{".n64", ".z64", ".v64"},
|
||||||
|
[&](const std::string &ext) { return file.path().extension() == ext; });
|
||||||
|
|
||||||
|
bool isArchive =
|
||||||
|
std::ranges::any_of(std::array{".zip", ".7z", ".rar", ".tar"},
|
||||||
|
[&](const std::string &ext) { return file.path().extension() == ext; });
|
||||||
|
|
||||||
|
if (!isArchive && !isPlain)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto rom = n64::Mem::LoadROM(isArchive, filename);
|
||||||
|
auto regions = n64::GameDB::match(rom);
|
||||||
|
|
||||||
|
if (rom.gameNameDB.empty())
|
||||||
|
rom.gameNameDB = fs::path(filename).stem().string();
|
||||||
|
|
||||||
|
romsList.push_back(
|
||||||
|
{rom.header.countryCode, rom.header.version, filename, rom.gameNameDB, regions, "Never", "0h 00m 00s"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <common.hpp>
|
||||||
|
#include <QTableWidget>
|
||||||
|
|
||||||
|
class GeneralSettings;
|
||||||
|
|
||||||
|
struct RomsListEntry {
|
||||||
|
u8 countryCode, version;
|
||||||
|
std::string path;
|
||||||
|
std::string name;
|
||||||
|
std::string region;
|
||||||
|
std::string lastPlayed;
|
||||||
|
std::string timePlayed;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RomsListTable : public QTableWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
void populate(const std::string &);
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::vector<RomsListEntry> romsList;
|
||||||
|
RomsListTable(GeneralSettings *);
|
||||||
|
|
||||||
|
size_t size() { return romsList.size(); }
|
||||||
|
|
||||||
|
RomsListEntry &operator[](const size_t i) { return romsList[i]; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void populateFinished();
|
||||||
|
void cleared();
|
||||||
|
};
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <log.hpp>
|
#include <log.hpp>
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
GeneralSettings::GeneralSettings() : settings(QSettings::UserScope) {
|
GeneralSettings::GeneralSettings() : settings(QSettings::UserScope) {
|
||||||
selectedRomsFolderLabel = new QLabel(Options::GetRomsPath().c_str());
|
selectedRomsFolderLabel = new QLabel(Options::GetRomsPath().c_str());
|
||||||
@@ -19,6 +20,9 @@ GeneralSettings::GeneralSettings() : settings(QSettings::UserScope) {
|
|||||||
auto dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), QCoreApplication::applicationDirPath(),
|
auto dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), QCoreApplication::applicationDirPath(),
|
||||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||||
|
|
||||||
|
if (dir.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
selectedSavesFolderLabel->setText(dir);
|
selectedSavesFolderLabel->setText(dir);
|
||||||
Options::SetSavesPath(dir.toStdString());
|
Options::SetSavesPath(dir.toStdString());
|
||||||
settings.setValue("saves_path", dir);
|
settings.setValue("saves_path", dir);
|
||||||
@@ -29,6 +33,9 @@ GeneralSettings::GeneralSettings() : settings(QSettings::UserScope) {
|
|||||||
auto dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), QCoreApplication::applicationDirPath(),
|
auto dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), QCoreApplication::applicationDirPath(),
|
||||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
||||||
|
|
||||||
|
if (dir.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
selectedRomsFolderLabel->setText(dir);
|
selectedRomsFolderLabel->setText(dir);
|
||||||
Options::SetRomsPath(dir.toStdString());
|
Options::SetRomsPath(dir.toStdString());
|
||||||
settings.setValue("roms_path", dir);
|
settings.setValue("roms_path", dir);
|
||||||
@@ -38,12 +45,32 @@ GeneralSettings::GeneralSettings() : settings(QSettings::UserScope) {
|
|||||||
|
|
||||||
gl = new QGridLayout();
|
gl = new QGridLayout();
|
||||||
|
|
||||||
|
QPushButton *clearRoms = new QPushButton("Clear");
|
||||||
|
connect(clearRoms, &QPushButton::clicked, this, [&] {
|
||||||
|
selectedRomsFolderLabel->clear();
|
||||||
|
Options::SetRomsPath("");
|
||||||
|
settings.setValue("roms_path", "");
|
||||||
|
settings.sync();
|
||||||
|
emit romFolderCleared();
|
||||||
|
});
|
||||||
|
|
||||||
|
QPushButton *clearSaves = new QPushButton("Clear");
|
||||||
|
connect(clearSaves, &QPushButton::clicked, this, [&] {
|
||||||
|
selectedSavesFolderLabel->clear();
|
||||||
|
Options::SetSavesPath("");
|
||||||
|
settings.setValue("saves_path", "");
|
||||||
|
settings.sync();
|
||||||
|
});
|
||||||
|
|
||||||
gl->addWidget(new QLabel("ROMs path:"), 0, 0);
|
gl->addWidget(new QLabel("ROMs path:"), 0, 0);
|
||||||
gl->addWidget(selectedRomsFolderLabel, 0, 1);
|
gl->addWidget(selectedRomsFolderLabel, 0, 1);
|
||||||
gl->addWidget(romsFolderSelectButton, 0, 2);
|
gl->addWidget(romsFolderSelectButton, 0, 2);
|
||||||
|
gl->addWidget(clearRoms, 0, 3);
|
||||||
|
|
||||||
gl->addWidget(new QLabel("Saves path:"), 1, 0);
|
gl->addWidget(new QLabel("Saves path:"), 1, 0);
|
||||||
gl->addWidget(selectedSavesFolderLabel, 1, 1);
|
gl->addWidget(selectedSavesFolderLabel, 1, 1);
|
||||||
gl->addWidget(savesFolderSelectButton, 1, 2);
|
gl->addWidget(savesFolderSelectButton, 1, 2);
|
||||||
|
gl->addWidget(clearSaves, 1, 3);
|
||||||
|
|
||||||
setLayout(gl);
|
setLayout(gl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,4 +19,5 @@ class GeneralSettings final : public QWidget {
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void romFolderSelected();
|
void romFolderSelected();
|
||||||
|
void romFolderCleared();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user