AronaCore/core/window/window_manager.cpp

97 lines
2.9 KiB
C++

#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();
}
}