Route picker callbacks through platform services

This commit is contained in:
2026-06-03 04:07:09 +02:00
parent 1e0500a3f7
commit 0e77ca6ba8
7 changed files with 217 additions and 124 deletions

View File

@@ -63,6 +63,27 @@ void webgl_sync();
namespace {
std::string build_supported_files_filter(const std::vector<std::string>& types)
{
std::string filter = "Supported Files (";
bool first_type = true;
for (const auto& t : types)
{
filter.append(std::string(first_type ? "" : " ,") + "*." + t);
first_type = false;
}
filter.append(")");
filter.push_back(0);
first_type = true;
for (const auto& t : types)
{
filter.append(std::string(first_type ? "" : ";") + "*." + t);
first_type = false;
}
filter.push_back(0);
return filter;
}
class LegacyPlatformServices final : public pp::platform::PlatformServices {
public:
[[nodiscard]] std::string clipboard_text() override
@@ -123,6 +144,108 @@ public:
#endif
}
void pick_image(pp::platform::PickedPathCallback callback) override
{
#ifdef __IOS__
dispatch_async(dispatch_get_main_queue(), ^{
[App::I->ios_view pick_photo:callback];
});
#elif __OSX__
dispatch_async(dispatch_get_main_queue(), ^{
NSArray* fileTypes = [NSArray arrayWithObjects:@"png", @"PNG", @"jpg", @"JPG", @"jpeg", nil];
std::string path = [App::I->osx_view pick_file:fileTypes];
invoke_picked_path_if_selected(path, callback);
});
#elif __ANDROID__
android_pick_file(callback);
#elif _WIN32
std::string path = win32_open_file("Image Files (*.jpg, *.png)\0*.jpg;*.png");
invoke_picked_path_if_selected(path, callback);
#elif __LINUX__
if (auto p = tinyfd_openFileDialog("Open File", "", 0, nullptr, nullptr, false))
invoke_picked_path_if_selected(p, callback);
#elif __WEB__
webgl_pick_file(callback);
#else
(void)callback;
#endif
}
void pick_file(std::vector<std::string> file_types, pp::platform::PickedPathCallback callback) override
{
#ifdef __IOS__
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray<NSString*>* fileTypes = [NSMutableArray arrayWithCapacity:file_types.size()];
for (const auto& t : file_types)
[fileTypes addObject:[NSString stringWithCString:t.c_str() encoding:NSUTF8StringEncoding]];
[App::I->ios_view pick_file:fileTypes then:callback];
});
#elif __OSX__
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray<NSString*>* fileTypes = [NSMutableArray arrayWithCapacity:file_types.size()];
for (const auto& t : file_types)
[fileTypes addObject:[NSString stringWithCString:t.c_str() encoding:NSUTF8StringEncoding]];
std::string path = [App::I->osx_view pick_file:fileTypes];
invoke_picked_path_if_selected(path, callback);
});
#elif __ANDROID__
android_pick_file(callback);
#elif _WIN32
const std::string filter = build_supported_files_filter(file_types);
std::string path = win32_open_file(filter.c_str());
invoke_picked_path_if_selected(path, callback);
#elif __LINUX__
if (auto p = tinyfd_openFileDialog("Open File", "", 0, nullptr, nullptr, false))
invoke_picked_path_if_selected(p, callback);
#elif __WEB__
webgl_pick_file(callback);
#else
(void)file_types;
(void)callback;
#endif
}
void pick_save_file(std::vector<std::string> file_types, pp::platform::PickedPathCallback callback) override
{
#if __OSX__
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray<NSString*>* fileTypes = [NSMutableArray arrayWithCapacity:file_types.size()];
for (const auto& t : file_types)
[fileTypes addObject:[NSString stringWithCString:t.c_str() encoding:NSUTF8StringEncoding]];
std::string path = [App::I->osx_view pick_file_save:fileTypes];
invoke_picked_path_if_selected(path, callback);
});
#elif __ANDROID__
android_pick_file_save(callback);
#elif _WIN32
const std::string filter = build_supported_files_filter(file_types);
std::string path = win32_save_file(filter.c_str());
invoke_picked_path_if_selected(path, callback);
#else
(void)file_types;
(void)callback;
#endif
}
void pick_directory(pp::platform::PickedPathCallback callback) override
{
#ifdef __IOS__
(void)callback;
#elif __OSX__
dispatch_async(dispatch_get_main_queue(), ^{
std::string path = [App::I->osx_view pick_dir];
invoke_picked_path_if_selected(path, callback);
});
#elif __ANDROID__
(void)callback;
#elif _WIN32
std::string path = win32_open_dir();
invoke_picked_path_if_selected(path, callback);
#else
(void)callback;
#endif
}
void display_file(std::string_view path) override
{
const std::string value(path);
@@ -271,74 +394,13 @@ void App::hideKeyboard()
void App::pick_image(std::function<void(std::string path)> callback)
{
redraw = true;
#ifdef __IOS__
dispatch_async(dispatch_get_main_queue(), ^{
[ios_view pick_photo:callback];
});
#elif __OSX__
dispatch_async(dispatch_get_main_queue(), ^{
NSArray* fileTypes = [NSArray arrayWithObjects:@"png", @"PNG", @"jpg", @"JPG", @"jpeg", nil];
std::string path = [osx_view pick_file:fileTypes];
invoke_picked_path_if_selected(path, callback);
});
#elif __ANDROID__
android_pick_file(callback);
#elif _WIN32
std::string path = win32_open_file("Image Files (*.jpg, *.png)\0*.jpg;*.png");
invoke_picked_path_if_selected(path, callback);
#elif __LINUX__
if (auto p = tinyfd_openFileDialog("Open File", "", 0, nullptr, nullptr, false))
invoke_picked_path_if_selected(p, callback);
#elif __WEB__
webgl_pick_file(callback);
#endif
legacy_platform_services().pick_image(std::move(callback));
}
void App::pick_file(std::vector<std::string> types, std::function<void (std::string)> callback)
{
redraw = true;
#ifdef __IOS__
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray<NSString*>* fileTypes = [NSMutableArray arrayWithCapacity:types.size()];
for (const auto& t : types)
[fileTypes addObject:[NSString stringWithCString:t.c_str() encoding:NSUTF8StringEncoding]];
[ios_view pick_file:fileTypes then:callback];
});
#elif __OSX__
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray<NSString*>* fileTypes = [NSMutableArray arrayWithCapacity:types.size()];
for (const auto& t : types)
[fileTypes addObject:[NSString stringWithCString:t.c_str() encoding:NSUTF8StringEncoding]];
std::string path = [osx_view pick_file:fileTypes];
invoke_picked_path_if_selected(path, callback);
});
#elif __ANDROID__
android_pick_file(callback);
#elif _WIN32
std::string filter = "Supported Files (";
bool first_type = true;
for (auto& t : types)
{
filter.append(std::string(first_type ? "" : " ,") + "*." + t);
first_type = false;
}
filter.append(")");
filter.push_back(0);
first_type = true;
for (auto& t : types)
{
filter.append(std::string(first_type ? "" : ";") + "*." + t);
first_type = false;
}
filter.push_back(0);
std::string path = win32_open_file(filter.c_str());
invoke_picked_path_if_selected(path, callback);
#elif __LINUX__
if (auto p = tinyfd_openFileDialog("Open File", "", 0, nullptr, nullptr, false))
invoke_picked_path_if_selected(p, callback);
#elif __WEB__
webgl_pick_file(callback);
#endif
legacy_platform_services().pick_file(std::move(types), std::move(callback));
}
#if __IOS__
@@ -370,57 +432,14 @@ void App::pick_file_save(const std::string& type, const std::string& default_nam
void App::pick_file_save(std::vector<std::string> types, std::function<void(std::string)> callback)
{
redraw = true;
#if __OSX__
dispatch_async(dispatch_get_main_queue(), ^{
//NSArray* fileTypes = [NSArray arrayWithObjects:@"ppi", @"PPI", nil];
NSMutableArray<NSString*>* fileTypes = [NSMutableArray arrayWithCapacity:types.size()];
for (const auto& t : types)
[fileTypes addObject:[NSString stringWithCString:t.c_str() encoding:NSUTF8StringEncoding]];
std::string path = [osx_view pick_file_save:fileTypes];
invoke_picked_path_if_selected(path, callback);
});
#elif __ANDROID__
android_pick_file_save(callback);
#elif _WIN32
std::string filter = "Supported Files (";
bool first_type = true;
for (auto& t : types)
{
filter.append(std::string(first_type ? "" : " ,") + "*." + t);
first_type = false;
}
filter.append(")");
filter.push_back(0);
first_type = true;
for (auto& t : types)
{
filter.append(std::string(first_type ? "" : ";") + "*." + t);
first_type = false;
}
filter.push_back(0);
std::string path = win32_save_file(filter.c_str());
invoke_picked_path_if_selected(path, callback);
#endif
legacy_platform_services().pick_save_file(std::move(types), std::move(callback));
}
#endif
void App::pick_dir(std::function<void(std::string path)> callback)
{
redraw = true;
#ifdef __IOS__
// NOT IMPLEMENTED
#elif __OSX__
dispatch_async(dispatch_get_main_queue(), ^{
std::string path = [osx_view pick_dir];
invoke_picked_path_if_selected(path, callback);
});
#elif __ANDROID__
// NOT IMPLEMENTED
#elif _WIN32
// TODO: to be implemented
std::string path = win32_open_dir();
invoke_picked_path_if_selected(path, callback);
#endif
legacy_platform_services().pick_directory(std::move(callback));
}
void App::display_file(std::string path)