Inject Windows platform services

This commit is contained in:
2026-06-03 04:14:47 +02:00
parent 0e77ca6ba8
commit ead7f58285
6 changed files with 166 additions and 82 deletions

View File

@@ -26,6 +26,10 @@
#include "layout.h"
#include "app_core/document_session.h"
namespace pp::platform {
class PlatformServices;
}
#if defined(__OBJC__) && defined(__IOS__)
#import <Foundation/Foundation.h>
#import "GameViewController.h"
@@ -156,6 +160,7 @@ public:
float display_density = 1.f;
float zoom = 1.f;
int idle_ms = 100;
pp::platform::PlatformServices* platform_services_ = nullptr;
#if defined(__IOS__) && defined(__OBJC__)
GameViewController* ios_view;
@@ -184,6 +189,8 @@ public:
void pick_dir(std::function<void(std::string path)> callback);
void display_file(std::string path);
void share_file(std::string path);
void set_platform_services(pp::platform::PlatformServices* services) noexcept;
[[nodiscard]] pp::platform::PlatformServices* platform_services() const noexcept;
void showKeyboard();
void hideKeyboard();
void initLog();

View File

@@ -44,13 +44,6 @@ void android_pick_file(std::function<void(std::string)> callback);
void android_pick_file_save(std::function<void(std::string)> callback);
std::string android_get_clipboard();
bool android_set_clipboard(const std::string& s);
#elif _WIN32
std::string win32_open_file(const char* filter);
std::string win32_save_file(const char* filter);
std::string win32_open_dir();
void win32_show_cursor(bool visible);
bool win32_clipboard_set_text(const std::string & s);
std::string win32_clipboard_get_text();
#elif __APPLE__
#elif __LINUX__
#include <tinyfiledialogs.h>
@@ -63,34 +56,12 @@ 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;
}
// DEBT-0017: fallback for platforms that do not inject PlatformServices yet.
class LegacyPlatformServices final : public pp::platform::PlatformServices {
public:
[[nodiscard]] std::string clipboard_text() override
{
#if _WIN32
return win32_clipboard_get_text();
#elif __IOS__
#if __IOS__
return [App::I->ios_view clipboard_get_string];
#elif __OSX__
return [App::I->osx_view clipboard_get_string];
@@ -104,9 +75,7 @@ public:
[[nodiscard]] bool set_clipboard_text(std::string_view text) override
{
const std::string value(text);
#if _WIN32
return win32_clipboard_set_text(value);
#elif __IOS__
#if __IOS__
return [App::I->ios_view clipboard_set_string:value];
#elif __OSX__
return [App::I->osx_view clipboard_set_string:value];
@@ -119,9 +88,7 @@ public:
void set_cursor_visible(bool visible) override
{
#ifdef _WIN32
win32_show_cursor(visible);
#elif __OSX__
#ifdef __OSX__
[App::I->osx_view show_cursor:visible];
#else
(void)visible;
@@ -158,9 +125,6 @@ public:
});
#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);
@@ -190,10 +154,6 @@ public:
});
#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);
@@ -217,10 +177,6 @@ public:
});
#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;
@@ -238,9 +194,6 @@ public:
});
#elif __ANDROID__
(void)callback;
#elif _WIN32
std::string path = win32_open_dir();
invoke_picked_path_if_selected(path, callback);
#else
(void)callback;
#endif
@@ -283,15 +236,35 @@ public:
return services;
}
[[nodiscard]] pp::platform::PlatformServices& active_platform_services()
{
if (App::I)
{
if (auto* services = App::I->platform_services())
return *services;
}
return legacy_platform_services();
}
}
void App::set_platform_services(pp::platform::PlatformServices* services) noexcept
{
platform_services_ = services;
}
pp::platform::PlatformServices* App::platform_services() const noexcept
{
return platform_services_;
}
std::string App::clipboard_get_text()
{
if (pp::app::plan_clipboard_read() != pp::app::ClipboardReadAction::read_text)
return {};
return legacy_platform_services().clipboard_text();
return active_platform_services().clipboard_text();
}
bool App::clipboard_set_text(const std::string& s)
@@ -299,7 +272,7 @@ bool App::clipboard_set_text(const std::string& s)
if (pp::app::plan_clipboard_write(s) != pp::app::ClipboardWriteAction::write_text)
return false;
return legacy_platform_services().set_clipboard_text(s);
return active_platform_services().set_clipboard_text(s);
}
void App::stacktrace()
@@ -347,9 +320,9 @@ void App::show_cursor()
return;
#ifdef _WIN32
legacy_platform_services().set_cursor_visible(true);
active_platform_services().set_cursor_visible(true);
#elif __OSX__
legacy_platform_services().set_cursor_visible(true);
active_platform_services().set_cursor_visible(true);
#endif
}
@@ -359,9 +332,9 @@ void App::hide_cursor()
return;
#ifdef _WIN32
legacy_platform_services().set_cursor_visible(false);
active_platform_services().set_cursor_visible(false);
#elif __OSX__
legacy_platform_services().set_cursor_visible(false);
active_platform_services().set_cursor_visible(false);
#endif
}
@@ -372,9 +345,9 @@ void App::showKeyboard()
if (!should_dispatch_keyboard_visibility(true))
return;
#ifdef __IOS__
legacy_platform_services().set_virtual_keyboard_visible(true);
active_platform_services().set_virtual_keyboard_visible(true);
#elif __ANDROID__
legacy_platform_services().set_virtual_keyboard_visible(true);
active_platform_services().set_virtual_keyboard_visible(true);
#endif
}
@@ -385,22 +358,22 @@ void App::hideKeyboard()
if (!should_dispatch_keyboard_visibility(false))
return;
#ifdef __IOS__
legacy_platform_services().set_virtual_keyboard_visible(false);
active_platform_services().set_virtual_keyboard_visible(false);
#elif __ANDROID__
legacy_platform_services().set_virtual_keyboard_visible(false);
active_platform_services().set_virtual_keyboard_visible(false);
#endif
}
void App::pick_image(std::function<void(std::string path)> callback)
{
redraw = true;
legacy_platform_services().pick_image(std::move(callback));
active_platform_services().pick_image(std::move(callback));
}
void App::pick_file(std::vector<std::string> types, std::function<void (std::string)> callback)
{
redraw = true;
legacy_platform_services().pick_file(std::move(types), std::move(callback));
active_platform_services().pick_file(std::move(types), std::move(callback));
}
#if __IOS__
@@ -432,14 +405,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;
legacy_platform_services().pick_save_file(std::move(types), std::move(callback));
active_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;
legacy_platform_services().pick_directory(std::move(callback));
active_platform_services().pick_directory(std::move(callback));
}
void App::display_file(std::string path)
@@ -447,7 +420,7 @@ void App::display_file(std::string path)
if (pp::app::plan_display_file(path) == pp::app::DisplayFileAction::ignore_empty_path)
return;
legacy_platform_services().display_file(path);
active_platform_services().display_file(path);
}
void App::share_file(std::string path)
@@ -458,7 +431,7 @@ void App::share_file(std::string path)
message_box("Sharing failed", "Please save the document before sharing it.");
return;
}
legacy_platform_services().share_file(path);
active_platform_services().share_file(path);
}
bool App::mouse_down(int button, float x, float y, float pressure, kEventSource source, bool eraser)

View File

@@ -5,6 +5,7 @@
#include "texture.h"
#include "image.h"
#include "app.h"
#include "platform_api/platform_services.h"
#include "canvas.h"
#include "keymap.h"
#include "hmd.h"
@@ -351,6 +352,104 @@ std::string win32_open_dir()
return Buffer;
}
namespace {
void invoke_selected_path(
const std::string& path,
const pp::platform::PickedPathCallback& callback)
{
if (!path.empty())
callback(path);
}
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 WindowsPlatformServices final : public pp::platform::PlatformServices {
public:
[[nodiscard]] std::string clipboard_text() override
{
return win32_clipboard_get_text();
}
[[nodiscard]] bool set_clipboard_text(std::string_view text) override
{
return win32_clipboard_set_text(std::string(text));
}
void set_cursor_visible(bool visible) override
{
win32_show_cursor(visible);
}
void set_virtual_keyboard_visible(bool visible) override
{
(void)visible;
}
void display_file(std::string_view path) override
{
(void)path;
}
void share_file(std::string_view path) override
{
(void)path;
}
void pick_image(pp::platform::PickedPathCallback callback) override
{
const std::string path = win32_open_file("Image Files (*.jpg, *.png)\0*.jpg;*.png");
invoke_selected_path(path, callback);
}
void pick_file(std::vector<std::string> file_types, pp::platform::PickedPathCallback callback) override
{
const std::string filter = build_supported_files_filter(file_types);
const std::string path = win32_open_file(filter.c_str());
invoke_selected_path(path, callback);
}
void pick_save_file(std::vector<std::string> file_types, pp::platform::PickedPathCallback callback) override
{
const std::string filter = build_supported_files_filter(file_types);
const std::string path = win32_save_file(filter.c_str());
invoke_selected_path(path, callback);
}
void pick_directory(pp::platform::PickedPathCallback callback) override
{
const std::string path = win32_open_dir();
invoke_selected_path(path, callback);
}
};
[[nodiscard]] WindowsPlatformServices& windows_platform_services()
{
static WindowsPlatformServices services;
return services;
}
}
int read_WMI_info()
{
// see: http://win32easy.blogspot.co.uk/2011/03/wmi-in-c-query-everyting-from-your-os.html
@@ -841,6 +940,7 @@ int main(int argc, char** argv)
PIXELFORMATDESCRIPTOR pfd;
App::I = new App();
App::I->set_platform_services(&windows_platform_services());
App::I->initLog();
init_shcore_API();