imgui docking, native window getter

This commit is contained in:
2025-11-20 21:43:52 +08:00
parent 041b99e0eb
commit e0e101b0a2
5 changed files with 51 additions and 254 deletions

View File

@ -14,145 +14,6 @@
namespace Prism namespace Prism
{ {
namespace Utils
{
ImGuiKey GLFWKeyToImGuiKey(const int keycode)
{
switch (keycode)
{
case GLFW_KEY_TAB: return ImGuiKey_Tab;
case GLFW_KEY_LEFT: return ImGuiKey_LeftArrow;
case GLFW_KEY_RIGHT: return ImGuiKey_RightArrow;
case GLFW_KEY_UP: return ImGuiKey_UpArrow;
case GLFW_KEY_DOWN: return ImGuiKey_DownArrow;
case GLFW_KEY_PAGE_UP: return ImGuiKey_PageUp;
case GLFW_KEY_PAGE_DOWN: return ImGuiKey_PageDown;
case GLFW_KEY_HOME: return ImGuiKey_Home;
case GLFW_KEY_END: return ImGuiKey_End;
case GLFW_KEY_INSERT: return ImGuiKey_Insert;
case GLFW_KEY_DELETE: return ImGuiKey_Delete;
case GLFW_KEY_BACKSPACE: return ImGuiKey_Backspace;
case GLFW_KEY_SPACE: return ImGuiKey_Space;
case GLFW_KEY_ENTER: return ImGuiKey_Enter;
case GLFW_KEY_ESCAPE: return ImGuiKey_Escape;
case GLFW_KEY_APOSTROPHE: return ImGuiKey_Apostrophe;
case GLFW_KEY_COMMA: return ImGuiKey_Comma;
case GLFW_KEY_MINUS: return ImGuiKey_Minus;
case GLFW_KEY_PERIOD: return ImGuiKey_Period;
case GLFW_KEY_SLASH: return ImGuiKey_Slash;
case GLFW_KEY_SEMICOLON: return ImGuiKey_Semicolon;
case GLFW_KEY_EQUAL: return ImGuiKey_Equal;
case GLFW_KEY_LEFT_BRACKET: return ImGuiKey_LeftBracket;
case GLFW_KEY_BACKSLASH: return ImGuiKey_Backslash;
case GLFW_KEY_RIGHT_BRACKET: return ImGuiKey_RightBracket;
case GLFW_KEY_GRAVE_ACCENT: return ImGuiKey_GraveAccent;
case GLFW_KEY_CAPS_LOCK: return ImGuiKey_CapsLock;
case GLFW_KEY_SCROLL_LOCK: return ImGuiKey_ScrollLock;
case GLFW_KEY_NUM_LOCK: return ImGuiKey_NumLock;
case GLFW_KEY_PRINT_SCREEN: return ImGuiKey_PrintScreen;
case GLFW_KEY_PAUSE: return ImGuiKey_Pause;
case GLFW_KEY_KP_0: return ImGuiKey_Keypad0;
case GLFW_KEY_KP_1: return ImGuiKey_Keypad1;
case GLFW_KEY_KP_2: return ImGuiKey_Keypad2;
case GLFW_KEY_KP_3: return ImGuiKey_Keypad3;
case GLFW_KEY_KP_4: return ImGuiKey_Keypad4;
case GLFW_KEY_KP_5: return ImGuiKey_Keypad5;
case GLFW_KEY_KP_6: return ImGuiKey_Keypad6;
case GLFW_KEY_KP_7: return ImGuiKey_Keypad7;
case GLFW_KEY_KP_8: return ImGuiKey_Keypad8;
case GLFW_KEY_KP_9: return ImGuiKey_Keypad9;
case GLFW_KEY_KP_DECIMAL: return ImGuiKey_KeypadDecimal;
case GLFW_KEY_KP_DIVIDE: return ImGuiKey_KeypadDivide;
case GLFW_KEY_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
case GLFW_KEY_KP_SUBTRACT: return ImGuiKey_KeypadSubtract;
case GLFW_KEY_KP_ADD: return ImGuiKey_KeypadAdd;
case GLFW_KEY_KP_ENTER: return ImGuiKey_KeypadEnter;
case GLFW_KEY_KP_EQUAL: return ImGuiKey_KeypadEqual;
case GLFW_KEY_LEFT_SHIFT: return ImGuiKey_LeftShift;
case GLFW_KEY_LEFT_CONTROL: return ImGuiKey_LeftCtrl;
case GLFW_KEY_LEFT_ALT: return ImGuiKey_LeftAlt;
case GLFW_KEY_LEFT_SUPER: return ImGuiKey_LeftSuper;
case GLFW_KEY_RIGHT_SHIFT: return ImGuiKey_RightShift;
case GLFW_KEY_RIGHT_CONTROL: return ImGuiKey_RightCtrl;
case GLFW_KEY_RIGHT_ALT: return ImGuiKey_RightAlt;
case GLFW_KEY_RIGHT_SUPER: return ImGuiKey_RightSuper;
case GLFW_KEY_MENU: return ImGuiKey_Menu;
case GLFW_KEY_0: return ImGuiKey_0;
case GLFW_KEY_1: return ImGuiKey_1;
case GLFW_KEY_2: return ImGuiKey_2;
case GLFW_KEY_3: return ImGuiKey_3;
case GLFW_KEY_4: return ImGuiKey_4;
case GLFW_KEY_5: return ImGuiKey_5;
case GLFW_KEY_6: return ImGuiKey_6;
case GLFW_KEY_7: return ImGuiKey_7;
case GLFW_KEY_8: return ImGuiKey_8;
case GLFW_KEY_9: return ImGuiKey_9;
case GLFW_KEY_A: return ImGuiKey_A;
case GLFW_KEY_B: return ImGuiKey_B;
case GLFW_KEY_C: return ImGuiKey_C;
case GLFW_KEY_D: return ImGuiKey_D;
case GLFW_KEY_E: return ImGuiKey_E;
case GLFW_KEY_F: return ImGuiKey_F;
case GLFW_KEY_G: return ImGuiKey_G;
case GLFW_KEY_H: return ImGuiKey_H;
case GLFW_KEY_I: return ImGuiKey_I;
case GLFW_KEY_J: return ImGuiKey_J;
case GLFW_KEY_K: return ImGuiKey_K;
case GLFW_KEY_L: return ImGuiKey_L;
case GLFW_KEY_M: return ImGuiKey_M;
case GLFW_KEY_N: return ImGuiKey_N;
case GLFW_KEY_O: return ImGuiKey_O;
case GLFW_KEY_P: return ImGuiKey_P;
case GLFW_KEY_Q: return ImGuiKey_Q;
case GLFW_KEY_R: return ImGuiKey_R;
case GLFW_KEY_S: return ImGuiKey_S;
case GLFW_KEY_T: return ImGuiKey_T;
case GLFW_KEY_U: return ImGuiKey_U;
case GLFW_KEY_V: return ImGuiKey_V;
case GLFW_KEY_W: return ImGuiKey_W;
case GLFW_KEY_X: return ImGuiKey_X;
case GLFW_KEY_Y: return ImGuiKey_Y;
case GLFW_KEY_Z: return ImGuiKey_Z;
case GLFW_KEY_F1: return ImGuiKey_F1;
case GLFW_KEY_F2: return ImGuiKey_F2;
case GLFW_KEY_F3: return ImGuiKey_F3;
case GLFW_KEY_F4: return ImGuiKey_F4;
case GLFW_KEY_F5: return ImGuiKey_F5;
case GLFW_KEY_F6: return ImGuiKey_F6;
case GLFW_KEY_F7: return ImGuiKey_F7;
case GLFW_KEY_F8: return ImGuiKey_F8;
case GLFW_KEY_F9: return ImGuiKey_F9;
case GLFW_KEY_F10: return ImGuiKey_F10;
case GLFW_KEY_F11: return ImGuiKey_F11;
case GLFW_KEY_F12: return ImGuiKey_F12;
default: return ImGuiKey_None;
}
}
void UpdateKeyModifiers(ImGuiIO& io, int keycode, bool pressed)
{
switch (keycode)
{
case GLFW_KEY_LEFT_CONTROL:
case GLFW_KEY_RIGHT_CONTROL:
io.AddKeyEvent(ImGuiMod_Ctrl, pressed);
break;
case GLFW_KEY_LEFT_SHIFT:
case GLFW_KEY_RIGHT_SHIFT:
io.AddKeyEvent(ImGuiMod_Shift, pressed);
break;
case GLFW_KEY_LEFT_ALT:
case GLFW_KEY_RIGHT_ALT:
io.AddKeyEvent(ImGuiMod_Alt, pressed);
break;
case GLFW_KEY_LEFT_SUPER:
case GLFW_KEY_RIGHT_SUPER:
io.AddKeyEvent(ImGuiMod_Super, pressed);
break;
}
}
}
ImGuiLayer::ImGuiLayer() ImGuiLayer::ImGuiLayer()
: Layer("ImGui Layer") : Layer("ImGui Layer")
{ {
@ -169,126 +30,70 @@ namespace Prism
void ImGuiLayer::OnAttach() void ImGuiLayer::OnAttach()
{ {
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoTaskBarIcons;
//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoMerge;
// Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
//ImGui::StyleColorsClassic();
ImGuiIO& io = ImGui::GetIO(); // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; ImGuiStyle& style = ImGui::GetStyle();
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
style.WindowRounding = 0.0f;
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
}
Application& app = Application::Get();
GLFWwindow* window = (GLFWwindow*)app.GetWindow().GetNativeWindow();
// Setup Platform/Renderer bindings
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init("#version 410"); ImGui_ImplOpenGL3_Init("#version 410");
} }
void ImGuiLayer::OnDetach() void ImGuiLayer::OnDetach()
{ {
Layer::OnDetach(); ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
} }
void ImGuiLayer::OnUpdate() void ImGuiLayer::OnUpdate()
{ {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
static bool show_demo_window = true;
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
Application& app = Application::Get(); Application& app = Application::Get();
io.DisplaySize = ImVec2(app.GetWindow().GetWidth(), app.GetWindow().GetHeight()); io.DisplaySize = ImVec2(app.GetWindow().GetWidth(), app.GetWindow().GetHeight());
// TODO: Hazel timing // Rendering
float time = (float)glfwGetTime();
io.DeltaTime = m_Time > 0.0 ? (time - m_Time) : (1.0f / 60.0f);
m_Time = time;
ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame();
static bool show = true;
ImGui::ShowDemoWindow(&show);
ImGui::Render(); ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
void ImGuiLayer::OnEvent(Event& e) if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{ {
EventDispatcher dispatcher(e); GLFWwindow* backup_current_context = glfwGetCurrentContext();
dispatcher.Dispatch<MouseButtonPressedEvent>(HZ_BIND_EVENT_FN(ImGuiLayer::OnMouseButtonPressedEvent)); ImGui::UpdatePlatformWindows();
dispatcher.Dispatch<MouseButtonReleasedEvent>(HZ_BIND_EVENT_FN(ImGuiLayer::OnMouseButtonReleasedEvent)); ImGui::RenderPlatformWindowsDefault();
dispatcher.Dispatch<MouseMovedEvent>(HZ_BIND_EVENT_FN(ImGuiLayer::OnMouseMovedEvent)); glfwMakeContextCurrent(backup_current_context);
dispatcher.Dispatch<MouseScrolledEvent>(HZ_BIND_EVENT_FN(ImGuiLayer::OnMouseScrolledEvent)); }
dispatcher.Dispatch<KeyPressedEvent>(HZ_BIND_EVENT_FN(ImGuiLayer::OnKeyPressedEvent));
dispatcher.Dispatch<KeyReleasedEvent>(HZ_BIND_EVENT_FN(ImGuiLayer::OnKeyReleasedEvent));
dispatcher.Dispatch<WindowResizeEvent>(HZ_BIND_EVENT_FN(ImGuiLayer::OnWindowResizeEvent));
} }
bool ImGuiLayer::OnMouseButtonPressedEvent(const MouseButtonPressedEvent& e)
{
ImGuiIO& io = ImGui::GetIO();
io.MouseDown[e.GetMouseButton()] = true;
return false;
}
bool ImGuiLayer::OnMouseButtonReleasedEvent(const MouseButtonReleasedEvent& e)
{
ImGuiIO& io = ImGui::GetIO();
io.MouseDown[e.GetMouseButton()] = false;
return false;
}
bool ImGuiLayer::OnMouseMovedEvent(MouseMovedEvent& e)
{
ImGuiIO& io = ImGui::GetIO();
io.MousePos = ImVec2(e.GetX(), e.GetY());
return false;
}
bool ImGuiLayer::OnMouseScrolledEvent(MouseScrolledEvent& e)
{
ImGuiIO& io = ImGui::GetIO();
io.MouseWheelH += e.GetOffsetX();
io.MouseWheel += e.GetOffsetY();
return false;
}
bool ImGuiLayer::OnKeyPressedEvent(KeyPressedEvent& e)
{
ImGuiIO& io = ImGui::GetIO();
ImGuiKey key = Utils::GLFWKeyToImGuiKey(e.GetKeyCode());
if (key != ImGuiKey_None)
{
io.AddKeyEvent(key, false);
}
Utils::UpdateKeyModifiers(io, e.GetKeyCode(), false);
return false;
}
bool ImGuiLayer::OnKeyReleasedEvent(KeyReleasedEvent& e)
{
ImGuiIO& io = ImGui::GetIO();
ImGuiKey key = Utils::GLFWKeyToImGuiKey(e.GetKeyCode());
if (key != ImGuiKey_None)
{
io.AddKeyEvent(key, false);
}
Utils::UpdateKeyModifiers(io, e.GetKeyCode(), false);
return false;
}
bool ImGuiLayer::OnWindowResizeEvent(WindowResizeEvent& e)
{
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2(e.GetWidth(), e.GetHeight());
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
glViewport(0, 0, e.GetWidth(), e.GetHeight());
return false;
}
} }

View File

@ -23,16 +23,6 @@ namespace Prism
virtual void OnAttach() override; virtual void OnAttach() override;
virtual void OnDetach() override; virtual void OnDetach() override;
virtual void OnUpdate() override; virtual void OnUpdate() override;
virtual void OnEvent(Event& e) override;
private:
bool OnMouseButtonPressedEvent(const MouseButtonPressedEvent& e);
bool OnMouseButtonReleasedEvent(const MouseButtonReleasedEvent& e);
bool OnMouseMovedEvent(MouseMovedEvent& e);
bool OnMouseScrolledEvent(MouseScrolledEvent& e);
bool OnKeyPressedEvent(KeyPressedEvent& e);
bool OnKeyReleasedEvent(KeyReleasedEvent& e);
bool OnWindowResizeEvent(WindowResizeEvent& e);
private: private:
float m_Time = 0.0f; float m_Time = 0.0f;

View File

@ -43,6 +43,8 @@ namespace Prism
virtual bool const IsVSync() const = 0; virtual bool const IsVSync() const = 0;
static Window* Create(const WindowProps& props = WindowProps()); static Window* Create(const WindowProps& props = WindowProps());
virtual void* GetNativeWindow() const = 0;
}; };
} }

View File

@ -12,18 +12,18 @@
namespace Prism namespace Prism
{ {
bool WindowsInput::IsKeyPressedImpl(int keycode) bool WindowsInput::IsKeyPressedImpl(const int keycode)
{ {
auto& window = static_cast<WindowsWindow&>(Application::Get().GetWindow()); auto& window = static_cast<WindowsWindow&>(Application::Get().GetWindow());
auto state = glfwGetKey(window.GetGLFWwindow(), keycode); auto state = glfwGetKey((GLFWwindow*)window.GetNativeWindow(), keycode);
return state == GLFW_PRESS || state == GLFW_REPEAT; return state == GLFW_PRESS || state == GLFW_REPEAT;
} }
bool WindowsInput::IsMouseButtonPressedImpl(int button) bool WindowsInput::IsMouseButtonPressedImpl(const int button)
{ {
auto& window = static_cast<WindowsWindow&>(Application::Get().GetWindow()); auto& window = static_cast<WindowsWindow&>(Application::Get().GetWindow());
auto state = glfwGetMouseButton(window.GetGLFWwindow(), button); auto state = glfwGetMouseButton((GLFWwindow*)window.GetNativeWindow(), button);
return state == GLFW_PRESS; return state == GLFW_PRESS;
} }
@ -32,7 +32,7 @@ namespace Prism
auto& window = static_cast<WindowsWindow&>(Application::Get().GetWindow()); auto& window = static_cast<WindowsWindow&>(Application::Get().GetWindow());
double xpos, ypos; double xpos, ypos;
glfwGetCursorPos(window.GetGLFWwindow(), &xpos, &ypos); glfwGetCursorPos((GLFWwindow*)window.GetNativeWindow(), &xpos, &ypos);
return (float)xpos; return (float)xpos;
} }
@ -42,7 +42,7 @@ namespace Prism
auto& window = static_cast<WindowsWindow&>(Application::Get().GetWindow()); auto& window = static_cast<WindowsWindow&>(Application::Get().GetWindow());
double xpos, ypos; double xpos, ypos;
glfwGetCursorPos(window.GetGLFWwindow(), &xpos, &ypos); glfwGetCursorPos((GLFWwindow*)window.GetNativeWindow(), &xpos, &ypos);
return (float)ypos; return (float)ypos;
} }

View File

@ -25,7 +25,7 @@ namespace Prism
bool const IsVSync() const override { return m_Data.VSync; } bool const IsVSync() const override { return m_Data.VSync; }
void SetVSync(bool enable) override; void SetVSync(bool enable) override;
inline GLFWwindow* GetGLFWwindow() const { return m_Window; } inline void* GetNativeWindow() const { return m_Window; }
private: private:
virtual void Init(const WindowProps& props); virtual void Init(const WindowProps& props);