Add file browser support on Linux through portable-file-dialogs

This commit is contained in:
Henrik Rydgård 2025-03-29 08:43:30 +01:00
parent fe4ca6fb63
commit 5f8f40e592
5 changed files with 106 additions and 11 deletions

View file

@ -104,6 +104,7 @@ enum class BrowseFileType {
SOUND_EFFECT,
ZIP,
SYMBOL_MAP,
SYMBOL_MAP_NOCASH,
ATRAC3,
ANY,
};

View file

@ -24,6 +24,8 @@ SDLJoystick *joystick = NULL;
#include <thread>
#include <locale>
#include "ext/portable-file-dialogs/portable-file-dialogs.h"
#include "Common/System/Display.h"
#include "Common/System/System.h"
#include "Common/System/Request.h"
@ -221,6 +223,47 @@ void System_Vibrate(int length_ms) {
// Ignore on PC
}
static void InitializeFilters(std::vector<std::string> &filters, BrowseFileType type) {
switch (type) {
case BrowseFileType::BOOTABLE:
filters.push_back("All supported file types (*.iso *.cso *.chd *.pbp *.elf *.prx *.zip *.ppdmp)");
filters.push_back("*.pbp *.elf *.iso *.cso *.chd *.prx *.zip *.ppdmp");
break;
case BrowseFileType::INI:
filters.push_back("Ini files");
filters.push_back("*.ini");
break;
case BrowseFileType::ZIP:
filters.push_back("ZIP files");
filters.push_back("*.zip");
break;
case BrowseFileType::DB:
filters.push_back("Cheat db files");
filters.push_back("*.db");
break;
case BrowseFileType::SOUND_EFFECT:
filters.push_back("Sound effect files (wav, mp3)");
filters.push_back("*.wav *.mp3");
break;
case BrowseFileType::SYMBOL_MAP:
filters.push_back("PPSSPP Symbol Map files (ppmap)");
filters.push_back("*.ppmap");
break;
case BrowseFileType::SYMBOL_MAP_NOCASH:
filters.push_back("No$ symbol Map files (sym)");
filters.push_back("*.sym");
break;
case BrowseFileType::ATRAC3:
filters.push_back("Atrac3 files (at3)");
filters.push_back("*.at3");
break;
case BrowseFileType::ANY:
break;
}
filters.push_back("All files (*.*)");
filters.push_back("*");
}
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string &param1, const std::string &param2, int64_t param3, int64_t param4) {
switch (type) {
case SystemRequestType::RESTART_APP:
@ -288,6 +331,44 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string
DarwinFileSystemServices::presentDirectoryPanel(callback, /* allowFiles = */ false, /* allowDirectories = */ true);
return true;
}
#else
case SystemRequestType::BROWSE_FOR_FILE:
case SystemRequestType::BROWSE_FOR_FILE_SAVE:
{
// TODO: Add non-blocking support.
const BrowseFileType browseType = (BrowseFileType)param3;
std::string initialFilename = param2;
const std::string &title = param1;
std::vector<std::string> filters;
InitializeFilters(filters, browseType);
if (type == SystemRequestType::BROWSE_FOR_FILE) {
std::vector<std::string> result = pfd::open_file(title, initialFilename, filters).result();
if (!result.empty()) {
g_requestManager.PostSystemSuccess(requestId, result[0]);
} else {
g_requestManager.PostSystemFailure(requestId);
}
} else {
std::string result = pfd::save_file(title, initialFilename, filters).result();
if (!result.empty()) {
g_requestManager.PostSystemSuccess(requestId, result);
} else {
g_requestManager.PostSystemFailure(requestId);
}
}
return true;
}
case SystemRequestType::BROWSE_FOR_FOLDER:
{
// TODO: Add non-blocking support.
std::string result = pfd::select_folder(param1, param2).result();
if (!result.empty()) {
g_requestManager.PostSystemSuccess(requestId, result);
} else {
g_requestManager.PostSystemFailure(requestId);
}
return true;
}
#endif
case SystemRequestType::TOGGLE_FULLSCREEN_STATE:
{
@ -612,10 +693,12 @@ bool System_GetPropertyBool(SystemProperty prop) {
case SYSPROP_SUPPORTS_HTTPS:
return !g_Config.bDisableHTTPS;
#endif
#if PPSSPP_PLATFORM(MAC)
case SYSPROP_HAS_FOLDER_BROWSER:
case SYSPROP_HAS_FILE_BROWSER:
#if PPSSPP_PLATFORM(MAC)
return true;
#else
return pfd::settings::available();
#endif
case SYSPROP_HAS_ACCELEROMETER:
#if defined(MOBILE_DEVICE)

View file

@ -88,7 +88,13 @@ void DarwinFileSystemServices::presentDirectoryPanel(
[panel setAllowedFileTypes:[NSArray arrayWithObject:@"db"]];
break;
case BrowseFileType::SOUND_EFFECT:
[panel setAllowedFileTypes:[NSArray arrayWithObject:@"wav"]];
[panel setAllowedFileTypes:[NSArray arrayWithObject:@"wav", @"mp3"]];
break;
case BrowseFileType::SYMBOL_MAP:
[panel setAllowedFileTypes:[NSArray arrayWithObject:@"ppsym"]];
break;
case BrowseFileType::SYMBOL_MAP_NOCASH:
[panel setAllowedFileTypes:[NSArray arrayWithObject:@"sym"]];
break;
case BrowseFileType::ATRAC3:
[panel setAllowedFileTypes:[NSArray arrayWithObject:@"at3"]];

View file

@ -519,6 +519,9 @@ bool System_MakeRequest(SystemRequestType type, int requestId, const std::string
case BrowseFileType::SYMBOL_MAP:
supportedExtensions = { ".ppmap" };
break;
case BrowseFileType::SYMBOL_MAP_NOCASH:
supportedExtensions = { ".sym" };
break;
case BrowseFileType::DB:
supportedExtensions = { ".db" };
break;

View file

@ -539,6 +539,8 @@ static std::wstring MakeWindowsFilter(BrowseFileType type) {
return FinalizeFilter(L"Sound effect files (*.wav *.mp3)|*.wav;*.mp3|All files (*.*)|*.*||");
case BrowseFileType::SYMBOL_MAP:
return FinalizeFilter(L"Symbol map files (*.ppmap)|*.ppmap|All files (*.*)|*.*||");
case BrowseFileType::SYMBOL_MAP_NOCASH:
return FinalizeFilter(L"No$ symbol map files (*.sym)|*.sym|All files (*.*)|*.*||");
case BrowseFileType::ATRAC3:
return FinalizeFilter(L"ATRAC3/3+ files (*.at3)|*.at3|All files (*.*)|*.*||");
case BrowseFileType::ANY: