Extract Windows platform services
This commit is contained in:
216
src/platform_windows/windows_platform_services.cpp
Normal file
216
src/platform_windows/windows_platform_services.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
#include "pch.h"
|
||||
#include "platform_windows/windows_platform_services.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
extern HWND hWnd;
|
||||
extern std::deque<std::packaged_task<void()>> main_tasklist;
|
||||
extern std::mutex main_task_mutex;
|
||||
|
||||
namespace {
|
||||
|
||||
void show_cursor(bool visible)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(main_task_mutex);
|
||||
main_tasklist.emplace_back([=] {
|
||||
if (visible)
|
||||
while (ShowCursor(true) < 0);
|
||||
else
|
||||
while (ShowCursor(false) >= 0);
|
||||
});
|
||||
}
|
||||
|
||||
std::string clipboard_text()
|
||||
{
|
||||
std::string ret;
|
||||
if (OpenClipboard(hWnd))
|
||||
{
|
||||
if (HANDLE h = GetClipboardData(CF_TEXT))
|
||||
{
|
||||
if (char* s = static_cast<char*>(GlobalLock(h)))
|
||||
{
|
||||
ret = s;
|
||||
GlobalUnlock(h);
|
||||
}
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool set_clipboard_text(const std::string& s)
|
||||
{
|
||||
bool success = false;
|
||||
if (OpenClipboard(hWnd))
|
||||
{
|
||||
// owned by SetClipboardData
|
||||
if (HGLOBAL h = GlobalAlloc(GMEM_MOVEABLE, s.size() + 1))
|
||||
{
|
||||
if (char* p = static_cast<char*>(GlobalLock(h)))
|
||||
{
|
||||
std::copy(s.begin(), s.end(), p);
|
||||
p[s.size()] = 0;
|
||||
GlobalUnlock(h);
|
||||
success = true;
|
||||
}
|
||||
EmptyClipboard();
|
||||
SetClipboardData(CF_TEXT, h);
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
std::string open_file(const char* filter)
|
||||
{
|
||||
OPENFILENAMEA ofn;
|
||||
char fileName[MAX_PATH] = "";
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = hWnd;
|
||||
ofn.lpstrFilter = filter;
|
||||
ofn.lpstrFile = fileName;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
|
||||
ofn.lpstrDefExt = "";
|
||||
ofn.lpstrInitialDir = "";
|
||||
if (GetOpenFileNameA(&ofn) != NULL)
|
||||
return fileName;
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string save_file(const char* filter)
|
||||
{
|
||||
OPENFILENAMEA ofn;
|
||||
char fileName[MAX_PATH] = "";
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = hWnd;
|
||||
ofn.lpstrFilter = filter;
|
||||
ofn.lpstrFile = fileName;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_OVERWRITEPROMPT;
|
||||
ofn.lpstrDefExt = "";
|
||||
ofn.lpstrInitialDir = "";
|
||||
if (GetSaveFileNameA(&ofn) != NULL)
|
||||
return fileName;
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string open_directory()
|
||||
{
|
||||
BROWSEINFOA bi;
|
||||
char Buffer[MAX_PATH];
|
||||
ZeroMemory(Buffer, MAX_PATH);
|
||||
ZeroMemory(&bi, sizeof(bi));
|
||||
bi.hwndOwner = hWnd;
|
||||
bi.pszDisplayName = Buffer;
|
||||
bi.lpszTitle = "Title";
|
||||
bi.ulFlags = BIF_EDITBOX | BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_SHAREABLE;
|
||||
LPCITEMIDLIST pFolder = SHBrowseForFolderA(&bi);
|
||||
if (pFolder == NULL)
|
||||
return "";
|
||||
if (!SHGetPathFromIDListA(pFolder, Buffer))
|
||||
return "";
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
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 ::clipboard_text();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool set_clipboard_text(std::string_view text) override
|
||||
{
|
||||
return ::set_clipboard_text(std::string(text));
|
||||
}
|
||||
|
||||
void set_cursor_visible(bool visible) override
|
||||
{
|
||||
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 = 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 = 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 = save_file(filter.c_str());
|
||||
invoke_selected_path(path, callback);
|
||||
}
|
||||
|
||||
void pick_directory(pp::platform::PickedPathCallback callback) override
|
||||
{
|
||||
const std::string path = open_directory();
|
||||
invoke_selected_path(path, callback);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace pp::platform::windows {
|
||||
|
||||
PlatformServices& platform_services()
|
||||
{
|
||||
static WindowsPlatformServices services;
|
||||
return services;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user