新增glfw, 用于创建插件窗口
This commit is contained in:
96
core/window/window_manager.cpp
Normal file
96
core/window/window_manager.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "window_manager.h"
|
||||
|
||||
#include "audio/plugin_host/plugin_host.h"
|
||||
#include "audio/plugin_host/plugin_host_manager.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
#include "GLFW/glfw3native.h"
|
||||
|
||||
void window_manager::init(singleton_initliazer& initliazer) {
|
||||
singleton_t<window_manager>::init(initliazer);
|
||||
auto plugin_host = initliazer.require<plugin_host_manager>();
|
||||
plugin_host->on_instrument_removed.add_raw(this, &window_manager::destroy_plugin_window);
|
||||
if (!glfwInit())
|
||||
return;
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
}
|
||||
|
||||
void window_manager::release(singleton_release_guard& release_guard) {
|
||||
singleton_t<window_manager>::release(release_guard);
|
||||
release_guard.require_release<plugin_host_manager>();
|
||||
|
||||
windows_.clear();
|
||||
host_infos_.clear();
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
std::shared_ptr<GLFWwindow> window_manager::create_window(int width, int height, const char* title) {
|
||||
auto* window = glfwCreateWindow(width, height, title, nullptr, nullptr);
|
||||
std::shared_ptr<GLFWwindow> w = std::shared_ptr<GLFWwindow>(window, [](GLFWwindow* w) {
|
||||
glfwDestroyWindow(w);
|
||||
});
|
||||
windows_.push_back(w);
|
||||
return w;
|
||||
}
|
||||
|
||||
void* window_manager::create_plugin_window(plugin_host* host) {
|
||||
uint32_t width, height;
|
||||
host->get_editor_size(width, height);
|
||||
if (width == 0 || height == 0)
|
||||
return nullptr;
|
||||
auto w = create_window(width, height, host->name.c_str());
|
||||
host_info info;
|
||||
host_info& window_info = host_infos_[host];
|
||||
window_info.window = w;
|
||||
glfwSetWindowCloseCallback(w.get(), [](GLFWwindow* window) {
|
||||
get_window_manager()->on_host_window_close(window);
|
||||
});
|
||||
#if PLATFORM_WINDOWS
|
||||
HWND hwnd = glfwGetWin32Window(w.get());
|
||||
return hwnd;
|
||||
#elif PLATFORM_LINUX
|
||||
return glfwGetX11Window(w.get());
|
||||
#elif PLATFORM_MACOS
|
||||
return glfwGetCocoaWindow(w.get());
|
||||
#endif
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void window_manager::destroy_plugin_window(plugin_host* host) {
|
||||
const auto& find = host_infos_.find(host);
|
||||
if (find == host_infos_.end()) {
|
||||
return;
|
||||
}
|
||||
auto window = find->second.window;
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
auto f = std::ranges::find_if(windows_, [window](const std::weak_ptr<GLFWwindow>& w) {
|
||||
return w.lock() == window;
|
||||
});
|
||||
windows_.erase(f);
|
||||
on_host_window_close(window.get());
|
||||
}
|
||||
|
||||
void window_manager::update() {
|
||||
glfwPollEvents();
|
||||
for (auto& info : host_infos_) {
|
||||
if (!info.second.window) {
|
||||
continue;
|
||||
}
|
||||
info.first->idle_editor();
|
||||
}
|
||||
}
|
||||
|
||||
void window_manager::on_host_window_close(GLFWwindow* window) {
|
||||
auto f = std::ranges::find_if(host_infos_, [window](const std::pair<plugin_host*, host_info>& info) {
|
||||
return info.second.window.get() == window;
|
||||
});
|
||||
if (f != host_infos_.end()) {
|
||||
f->first->close_editor();
|
||||
int x, y;
|
||||
glfwGetWindowPos(window, &x, &y);
|
||||
f->second.x = x;
|
||||
f->second.y = y;
|
||||
f->second.window.reset();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user