Qt: Add recent games list
This commit is contained in:
@@ -108,6 +108,9 @@ struct EmulatorConfig {
|
||||
std::filesystem::path defaultRomPath = "";
|
||||
std::filesystem::path filePath;
|
||||
|
||||
static constexpr size_t maxRecentGames = 8;
|
||||
std::vector<std::filesystem::path> recentlyPlayed;
|
||||
|
||||
// Frontend window settings
|
||||
struct WindowSettings {
|
||||
static constexpr int defaultX = 200;
|
||||
@@ -132,6 +135,8 @@ struct EmulatorConfig {
|
||||
void load();
|
||||
void save();
|
||||
|
||||
void addToRecentGames(const std::filesystem::path& path);
|
||||
|
||||
static LanguageCodes languageCodeFromString(std::string inString);
|
||||
static const char* languageCodeToString(LanguageCodes code);
|
||||
};
|
||||
|
||||
@@ -103,6 +103,7 @@ class MainWindow : public QMainWindow {
|
||||
std::vector<EmulatorMessage> messageQueue;
|
||||
|
||||
QMenuBar* menuBar = nullptr;
|
||||
QMenu* recentsMenu = nullptr;
|
||||
InputMappings keyboardMappings;
|
||||
ScreenWidget* screen;
|
||||
AboutWindow* aboutWindow;
|
||||
@@ -123,6 +124,8 @@ class MainWindow : public QMainWindow {
|
||||
void emuThreadMainLoop();
|
||||
void selectLuaFile();
|
||||
void selectROM();
|
||||
void loadROMFromPath(const std::filesystem::path& path);
|
||||
void updateRecentsMenu();
|
||||
void dumpDspFirmware();
|
||||
void dumpRomFS();
|
||||
void showAboutMenu();
|
||||
|
||||
@@ -50,6 +50,23 @@ void EmulatorConfig::load() {
|
||||
circlePadProEnabled = toml::find_or<toml::boolean>(general, "EnableCirclePadPro", true);
|
||||
fastmemEnabled = toml::find_or<toml::boolean>(general, "EnableFastmem", enableFastmemDefault);
|
||||
systemLanguage = languageCodeFromString(toml::find_or<std::string>(general, "SystemLanguage", "en"));
|
||||
|
||||
// Load recent games list
|
||||
if (general.contains("RecentGames") && general.at("RecentGames").is_array()) {
|
||||
const auto& recentsArray = general.at("RecentGames").as_array();
|
||||
recentlyPlayed.clear();
|
||||
|
||||
for (const auto& item : recentsArray) {
|
||||
if (item.is_string()) {
|
||||
std::filesystem::path gamePath = toml::get<std::string>(item);
|
||||
|
||||
recentlyPlayed.push_back(gamePath);
|
||||
if (recentlyPlayed.size() >= maxRecentGames) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,6 +200,12 @@ void EmulatorConfig::save() {
|
||||
data["General"]["EnableCirclePadPro"] = circlePadProEnabled;
|
||||
data["General"]["EnableFastmem"] = fastmemEnabled;
|
||||
|
||||
toml::array recentsArray;
|
||||
for (const auto& gamePath : recentlyPlayed) {
|
||||
recentsArray.push_back(gamePath.string());
|
||||
}
|
||||
data["General"]["RecentGames"] = recentsArray;
|
||||
|
||||
data["Window"]["AppVersionOnWindow"] = windowSettings.showAppVersion;
|
||||
data["Window"]["RememberWindowPosition"] = windowSettings.rememberPosition;
|
||||
data["Window"]["WindowPosX"] = windowSettings.x;
|
||||
@@ -278,3 +301,17 @@ const char* EmulatorConfig::languageCodeToString(LanguageCodes code) {
|
||||
return codes[static_cast<u32>(code)];
|
||||
}
|
||||
}
|
||||
void EmulatorConfig::addToRecentGames(const std::filesystem::path& path) {
|
||||
// Remove path if it's already in the list
|
||||
auto it = std::find(recentlyPlayed.begin(), recentlyPlayed.end(), path);
|
||||
if (it != recentlyPlayed.end()) {
|
||||
recentlyPlayed.erase(it);
|
||||
}
|
||||
|
||||
recentlyPlayed.insert(recentlyPlayed.begin(), path);
|
||||
|
||||
// Limit how many games can be saved
|
||||
if (recentlyPlayed.size() > maxRecentGames) {
|
||||
recentlyPlayed.resize(maxRecentGames);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,11 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
|
||||
|
||||
// Create and bind actions for them
|
||||
auto loadGameAction = fileMenu->addAction(tr("Load game"));
|
||||
|
||||
recentsMenu = fileMenu->addMenu(tr("Recents"));
|
||||
updateRecentsMenu();
|
||||
|
||||
fileMenu->addSeparator();
|
||||
auto loadLuaAction = fileMenu->addAction(tr("Load Lua script"));
|
||||
auto openAppFolderAction = fileMenu->addAction(tr("Open Panda3DS folder"));
|
||||
|
||||
@@ -140,6 +145,10 @@ MainWindow::MainWindow(QApplication* app, QWidget* parent) : QMainWindow(parent)
|
||||
if (!emu->loadROM(romPath)) {
|
||||
// For some reason just .c_str() doesn't show the proper path
|
||||
Helpers::warn("Failed to load ROM file: %s", romPath.string().c_str());
|
||||
} else {
|
||||
emu->getConfig().addToRecentGames(romPath);
|
||||
emu->getConfig().save();
|
||||
updateRecentsMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,11 +249,48 @@ void MainWindow::selectROM() {
|
||||
);
|
||||
|
||||
if (!path.isEmpty()) {
|
||||
std::filesystem::path* p = new std::filesystem::path(path.toStdU16String());
|
||||
loadROMFromPath(std::filesystem::path(path.toStdU16String()));
|
||||
}
|
||||
}
|
||||
|
||||
EmulatorMessage message{.type = MessageType::LoadROM};
|
||||
message.path.p = p;
|
||||
sendMessage(message);
|
||||
void MainWindow::loadROMFromPath(const std::filesystem::path& path) {
|
||||
std::filesystem::path* p = new std::filesystem::path(path);
|
||||
|
||||
EmulatorMessage message{.type = MessageType::LoadROM};
|
||||
message.path.p = p;
|
||||
sendMessage(message);
|
||||
|
||||
emu->getConfig().addToRecentGames(path);
|
||||
emu->getConfig().save();
|
||||
updateRecentsMenu();
|
||||
}
|
||||
|
||||
void MainWindow::updateRecentsMenu() {
|
||||
recentsMenu->clear();
|
||||
const auto& recentGames = emu->getConfig().recentlyPlayed;
|
||||
|
||||
if (recentGames.empty()) {
|
||||
// Add a disabled "No recent games" item
|
||||
QAction* noRecentsAction = recentsMenu->addAction(tr("No recent games"));
|
||||
noRecentsAction->setEnabled(false);
|
||||
} else {
|
||||
for (const auto& gamePath : recentGames) {
|
||||
QString displayName = QString::fromStdU16String(gamePath.filename().u16string());
|
||||
QAction* action = recentsMenu->addAction(displayName);
|
||||
|
||||
// Store the full path in the action's data, set tooltip to show full path
|
||||
action->setData(QString::fromStdU16String(gamePath.u16string()));
|
||||
action->setToolTip(QString::fromStdU16String(gamePath.u16string()));
|
||||
connect(action, &QAction::triggered, this, [this, gamePath]() { loadROMFromPath(gamePath); });
|
||||
}
|
||||
|
||||
recentsMenu->addSeparator();
|
||||
QAction* clearAction = recentsMenu->addAction(tr("Clear recent games"));
|
||||
connect(clearAction, &QAction::triggered, this, [this]() {
|
||||
emu->getConfig().recentlyPlayed.clear();
|
||||
emu->getConfig().save();
|
||||
updateRecentsMenu();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user