mirror of
https://github.com/ocornut/imgui.git
synced 2025-10-02 16:18:33 +00:00

MacOS positions windows by their bottom-left corner why the rest of the world (including imgui) position windows by the top-left corner. This created an issue where collapsing imgui window would cause window header to remain at the bottom the full window rect. Likewise resizing window by using sizing handle caused window to grow upwards when we tried to expand window downwards. This workaround moves window to the opposite direction by the delta of size change creating an illusion that windows are positioned by their top-left corner.
776 lines
36 KiB
C++
776 lines
36 KiB
C++
// dear imgui: Platform Binding for GLFW
|
|
// This needs to be used along with a Renderer (e.g. OpenGL3, Vulkan..)
|
|
// (Info: GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan graphics context creation, etc.)
|
|
// (Requires: GLFW 3.1+)
|
|
|
|
// Implemented features:
|
|
// [X] Platform: Clipboard support.
|
|
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
|
// [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: 3 cursors types are missing from GLFW.
|
|
// [X] Platform: Keyboard arrays indexed using GLFW_KEY_* codes, e.g. ImGui::IsKeyPressed(GLFW_KEY_SPACE).
|
|
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
|
|
// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this.
|
|
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
|
|
// https://github.com/ocornut/imgui
|
|
|
|
// CHANGELOG
|
|
// (minor and older changes stripped away, please see git history for details)
|
|
// 2019-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
|
|
// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter().
|
|
// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
|
|
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
|
|
// 2018-11-07: Inputs: When installing our GLFW callbacks, we save user's previously installed ones - if any - and chain call them.
|
|
// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
|
|
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
|
|
// 2018-06-08: Misc: Extracted imgui_impl_glfw.cpp/.h away from the old combined GLFW+OpenGL/Vulkan examples.
|
|
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag.
|
|
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value, passed to glfwSetCursor()).
|
|
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
|
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
|
|
// 2018-01-25: Inputs: Added gamepad support if ImGuiConfigFlags_NavEnableGamepad is set.
|
|
// 2018-01-25: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set).
|
|
// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
|
|
// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert.
|
|
// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1).
|
|
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
|
|
|
|
#include "imgui.h"
|
|
#include "imgui_impl_glfw.h"
|
|
|
|
// GLFW
|
|
#include <GLFW/glfw3.h>
|
|
#ifdef _WIN32
|
|
#undef APIENTRY
|
|
#define GLFW_EXPOSE_NATIVE_WIN32
|
|
#include <GLFW/glfw3native.h> // for glfwGetWin32Window
|
|
#endif
|
|
#define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ GLFW_FLOATING
|
|
#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_HOVERED
|
|
#define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity
|
|
#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorContentScale
|
|
#define GLFW_HAS_VULKAN (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwCreateWindowSurface
|
|
#define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwFocusWindow
|
|
#define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_FOCUS_ON_SHOW
|
|
#define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorWorkarea
|
|
|
|
// Data
|
|
enum GlfwClientApi
|
|
{
|
|
GlfwClientApi_Unknown,
|
|
GlfwClientApi_OpenGL,
|
|
GlfwClientApi_Vulkan
|
|
};
|
|
static GLFWwindow* g_Window = NULL; // Main window
|
|
static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown;
|
|
static double g_Time = 0.0;
|
|
static bool g_MouseJustPressed[5] = { false, false, false, false, false };
|
|
static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 };
|
|
static bool g_WantUpdateMonitors = true;
|
|
|
|
// Chain GLFW callbacks for main viewport: our callbacks will call the user's previously installed callbacks, if any.
|
|
static GLFWmousebuttonfun g_PrevUserCallbackMousebutton = NULL;
|
|
static GLFWscrollfun g_PrevUserCallbackScroll = NULL;
|
|
static GLFWkeyfun g_PrevUserCallbackKey = NULL;
|
|
static GLFWcharfun g_PrevUserCallbackChar = NULL;
|
|
|
|
// Forward Declarations
|
|
static void ImGui_ImplGlfw_InitPlatformInterface();
|
|
static void ImGui_ImplGlfw_ShutdownPlatformInterface();
|
|
static void ImGui_ImplGlfw_UpdateMonitors();
|
|
|
|
static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data)
|
|
{
|
|
return glfwGetClipboardString((GLFWwindow*)user_data);
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
|
|
{
|
|
glfwSetClipboardString((GLFWwindow*)user_data, text);
|
|
}
|
|
|
|
void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
|
{
|
|
if (g_PrevUserCallbackMousebutton != NULL && window == g_Window)
|
|
g_PrevUserCallbackMousebutton(window, button, action, mods);
|
|
|
|
if (action == GLFW_PRESS && button >= 0 && button < IM_ARRAYSIZE(g_MouseJustPressed))
|
|
g_MouseJustPressed[button] = true;
|
|
}
|
|
|
|
void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
|
|
{
|
|
if (g_PrevUserCallbackScroll != NULL && window == g_Window)
|
|
g_PrevUserCallbackScroll(window, xoffset, yoffset);
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
io.MouseWheelH += (float)xoffset;
|
|
io.MouseWheel += (float)yoffset;
|
|
}
|
|
|
|
void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
|
{
|
|
if (g_PrevUserCallbackKey != NULL && window == g_Window)
|
|
g_PrevUserCallbackKey(window, key, scancode, action, mods);
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
if (action == GLFW_PRESS)
|
|
io.KeysDown[key] = true;
|
|
if (action == GLFW_RELEASE)
|
|
io.KeysDown[key] = false;
|
|
|
|
// Modifiers are not reliable across systems
|
|
io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL];
|
|
io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT];
|
|
io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT];
|
|
io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER];
|
|
}
|
|
|
|
void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
|
|
{
|
|
if (g_PrevUserCallbackChar != NULL && window == g_Window)
|
|
g_PrevUserCallbackChar(window, c);
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
io.AddInputCharacter(c);
|
|
}
|
|
|
|
static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api)
|
|
{
|
|
g_Window = window;
|
|
g_Time = 0.0;
|
|
|
|
// Setup back-end capabilities flags
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
|
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
|
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
|
#if GLFW_HAS_GLFW_HOVERED && defined(_WIN32)
|
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can set io.MouseHoveredViewport correctly (optional, not easy)
|
|
#endif
|
|
io.BackendPlatformName = "imgui_impl_glfw";
|
|
|
|
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
|
|
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB;
|
|
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
|
|
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
|
|
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
|
|
io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN;
|
|
io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP;
|
|
io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN;
|
|
io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME;
|
|
io.KeyMap[ImGuiKey_End] = GLFW_KEY_END;
|
|
io.KeyMap[ImGuiKey_Insert] = GLFW_KEY_INSERT;
|
|
io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE;
|
|
io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE;
|
|
io.KeyMap[ImGuiKey_Space] = GLFW_KEY_SPACE;
|
|
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
|
|
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
|
|
io.KeyMap[ImGuiKey_KeyPadEnter] = GLFW_KEY_KP_ENTER;
|
|
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
|
|
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
|
|
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;
|
|
io.KeyMap[ImGuiKey_X] = GLFW_KEY_X;
|
|
io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y;
|
|
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
|
|
|
|
io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
|
|
io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
|
|
io.ClipboardUserData = g_Window;
|
|
|
|
g_MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
|
g_MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
|
|
g_MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
|
|
g_MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR);
|
|
g_MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
|
|
g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
|
|
g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); // FIXME: GLFW doesn't have this.
|
|
g_MouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
|
|
|
|
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
|
|
g_PrevUserCallbackMousebutton = NULL;
|
|
g_PrevUserCallbackScroll = NULL;
|
|
g_PrevUserCallbackKey = NULL;
|
|
g_PrevUserCallbackChar = NULL;
|
|
if (install_callbacks)
|
|
{
|
|
g_PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback);
|
|
g_PrevUserCallbackScroll = glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback);
|
|
g_PrevUserCallbackKey = glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback);
|
|
g_PrevUserCallbackChar = glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback);
|
|
}
|
|
|
|
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
main_viewport->PlatformHandle = (void*)g_Window;
|
|
#ifdef _WIN32
|
|
main_viewport->PlatformHandleRaw = glfwGetWin32Window(g_Window);
|
|
#endif
|
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
ImGui_ImplGlfw_InitPlatformInterface();
|
|
|
|
g_ClientApi = client_api;
|
|
return true;
|
|
}
|
|
|
|
bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks)
|
|
{
|
|
return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_OpenGL);
|
|
}
|
|
|
|
bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks)
|
|
{
|
|
return ImGui_ImplGlfw_Init(window, install_callbacks, GlfwClientApi_Vulkan);
|
|
}
|
|
|
|
void ImGui_ImplGlfw_Shutdown()
|
|
{
|
|
ImGui_ImplGlfw_ShutdownPlatformInterface();
|
|
|
|
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
|
{
|
|
glfwDestroyCursor(g_MouseCursors[cursor_n]);
|
|
g_MouseCursors[cursor_n] = NULL;
|
|
}
|
|
g_ClientApi = GlfwClientApi_Unknown;
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_UpdateMousePosAndButtons()
|
|
{
|
|
// Update buttons
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
|
{
|
|
// If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
|
|
io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0;
|
|
g_MouseJustPressed[i] = false;
|
|
}
|
|
|
|
// Update mouse position
|
|
const ImVec2 mouse_pos_backup = io.MousePos;
|
|
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
|
io.MouseHoveredViewport = 0;
|
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
|
{
|
|
ImGuiViewport* viewport = platform_io.Viewports[n];
|
|
GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle;
|
|
IM_ASSERT(window != NULL);
|
|
#ifdef __EMSCRIPTEN__
|
|
const bool focused = true;
|
|
IM_ASSERT(platform_io.Viewports.Size == 1);
|
|
#else
|
|
const bool focused = glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0;
|
|
#endif
|
|
if (focused)
|
|
{
|
|
if (io.WantSetMousePos)
|
|
{
|
|
glfwSetCursorPos(window, (double)(mouse_pos_backup.x - viewport->Pos.x), (double)(mouse_pos_backup.y - viewport->Pos.y));
|
|
}
|
|
else
|
|
{
|
|
double mouse_x, mouse_y;
|
|
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
{
|
|
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
|
int window_x, window_y;
|
|
glfwGetWindowPos(window, &window_x, &window_y);
|
|
io.MousePos = ImVec2((float)mouse_x + window_x, (float)mouse_y + window_y);
|
|
}
|
|
else
|
|
{
|
|
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
|
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y);
|
|
}
|
|
}
|
|
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
|
io.MouseDown[i] |= glfwGetMouseButton(window, i) != 0;
|
|
}
|
|
|
|
// (Optional) When using multiple viewports: set io.MouseHoveredViewport to the viewport the OS mouse cursor is hovering.
|
|
// Important: this information is not easy to provide and many high-level windowing library won't be able to provide it correctly, because
|
|
// - This is _ignoring_ viewports with the ImGuiViewportFlags_NoInputs flag (pass-through windows).
|
|
// - This is _regardless_ of whether another viewport is focused or being dragged from.
|
|
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the back-end, imgui will ignore this field and infer the information by relying on the
|
|
// rectangles and last focused time of every viewports it knows about. It will be unaware of other windows that may be sitting between or over your windows.
|
|
// [GLFW] FIXME: This is currently only correct on Win32. See what we do below with the WM_NCHITTEST, missing an equivalent for other systems.
|
|
// See https://github.com/glfw/glfw/issues/1236 if you want to help in making this a GLFW feature.
|
|
#if GLFW_HAS_GLFW_HOVERED && defined(_WIN32)
|
|
if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !(viewport->Flags & ImGuiViewportFlags_NoInputs))
|
|
io.MouseHoveredViewport = viewport->ID;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_UpdateMouseCursor()
|
|
{
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
if ((io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) || glfwGetInputMode(g_Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
|
return;
|
|
|
|
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
|
{
|
|
GLFWwindow* window = (GLFWwindow*)platform_io.Viewports[n]->PlatformHandle;
|
|
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
|
{
|
|
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
|
}
|
|
else
|
|
{
|
|
// Show OS mouse cursor
|
|
// FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here.
|
|
glfwSetCursor(window, g_MouseCursors[imgui_cursor] ? g_MouseCursors[imgui_cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]);
|
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_UpdateGamepads()
|
|
{
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
|
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
|
return;
|
|
|
|
// Update gamepad inputs
|
|
#define MAP_BUTTON(NAV_NO, BUTTON_NO) { if (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS) io.NavInputs[NAV_NO] = 1.0f; }
|
|
#define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) { float v = (axes_count > AXIS_NO) ? axes[AXIS_NO] : V0; v = (v - V0) / (V1 - V0); if (v > 1.0f) v = 1.0f; if (io.NavInputs[NAV_NO] < v) io.NavInputs[NAV_NO] = v; }
|
|
int axes_count = 0, buttons_count = 0;
|
|
const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &axes_count);
|
|
const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &buttons_count);
|
|
MAP_BUTTON(ImGuiNavInput_Activate, 0); // Cross / A
|
|
MAP_BUTTON(ImGuiNavInput_Cancel, 1); // Circle / B
|
|
MAP_BUTTON(ImGuiNavInput_Menu, 2); // Square / X
|
|
MAP_BUTTON(ImGuiNavInput_Input, 3); // Triangle / Y
|
|
MAP_BUTTON(ImGuiNavInput_DpadLeft, 13); // D-Pad Left
|
|
MAP_BUTTON(ImGuiNavInput_DpadRight, 11); // D-Pad Right
|
|
MAP_BUTTON(ImGuiNavInput_DpadUp, 10); // D-Pad Up
|
|
MAP_BUTTON(ImGuiNavInput_DpadDown, 12); // D-Pad Down
|
|
MAP_BUTTON(ImGuiNavInput_FocusPrev, 4); // L1 / LB
|
|
MAP_BUTTON(ImGuiNavInput_FocusNext, 5); // R1 / RB
|
|
MAP_BUTTON(ImGuiNavInput_TweakSlow, 4); // L1 / LB
|
|
MAP_BUTTON(ImGuiNavInput_TweakFast, 5); // R1 / RB
|
|
MAP_ANALOG(ImGuiNavInput_LStickLeft, 0, -0.3f, -0.9f);
|
|
MAP_ANALOG(ImGuiNavInput_LStickRight,0, +0.3f, +0.9f);
|
|
MAP_ANALOG(ImGuiNavInput_LStickUp, 1, +0.3f, +0.9f);
|
|
MAP_ANALOG(ImGuiNavInput_LStickDown, 1, -0.3f, -0.9f);
|
|
#undef MAP_BUTTON
|
|
#undef MAP_ANALOG
|
|
if (axes_count > 0 && buttons_count > 0)
|
|
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
|
else
|
|
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
|
}
|
|
|
|
void ImGui_ImplGlfw_NewFrame()
|
|
{
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
|
|
|
|
// Setup display size (every frame to accommodate for window resizing)
|
|
int w, h;
|
|
int display_w, display_h;
|
|
glfwGetWindowSize(g_Window, &w, &h);
|
|
glfwGetFramebufferSize(g_Window, &display_w, &display_h);
|
|
io.DisplaySize = ImVec2((float)w, (float)h);
|
|
if (w > 0 && h > 0)
|
|
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
|
|
if (g_WantUpdateMonitors)
|
|
ImGui_ImplGlfw_UpdateMonitors();
|
|
|
|
// Setup time step
|
|
double current_time = glfwGetTime();
|
|
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f);
|
|
g_Time = current_time;
|
|
|
|
ImGui_ImplGlfw_UpdateMousePosAndButtons();
|
|
ImGui_ImplGlfw_UpdateMouseCursor();
|
|
|
|
// Update game controllers (if enabled and available)
|
|
ImGui_ImplGlfw_UpdateGamepads();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------
|
|
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
// This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously.
|
|
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
//--------------------------------------------------------------------------------------------------------
|
|
|
|
struct ImGuiViewportDataGlfw
|
|
{
|
|
GLFWwindow* Window;
|
|
bool WindowOwned;
|
|
|
|
ImGuiViewportDataGlfw() { Window = NULL; WindowOwned = false; }
|
|
~ImGuiViewportDataGlfw() { IM_ASSERT(Window == NULL); }
|
|
};
|
|
|
|
static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window)
|
|
{
|
|
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
|
viewport->PlatformRequestClose = true;
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int, int)
|
|
{
|
|
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
|
viewport->PlatformRequestMove = true;
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
|
|
{
|
|
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
|
viewport->PlatformRequestResize = true;
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
|
|
{
|
|
ImGuiViewportDataGlfw* data = IM_NEW(ImGuiViewportDataGlfw)();
|
|
viewport->PlatformUserData = data;
|
|
|
|
// GLFW 3.2 unfortunately always set focus on glfwCreateWindow() if GLFW_VISIBLE is set, regardless of GLFW_FOCUSED
|
|
// With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
|
|
glfwWindowHint(GLFW_VISIBLE, false);
|
|
glfwWindowHint(GLFW_FOCUSED, false);
|
|
#if GLFW_HAS_FOCUS_ON_SHOW
|
|
glfwWindowHint(GLFW_FOCUS_ON_SHOW, false);
|
|
#endif
|
|
glfwWindowHint(GLFW_DECORATED, (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? false : true);
|
|
#if GLFW_HAS_WINDOW_TOPMOST
|
|
glfwWindowHint(GLFW_FLOATING, (viewport->Flags & ImGuiViewportFlags_TopMost) ? true : false);
|
|
#endif
|
|
GLFWwindow* share_window = (g_ClientApi == GlfwClientApi_OpenGL) ? g_Window : NULL;
|
|
data->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", NULL, share_window);
|
|
data->WindowOwned = true;
|
|
viewport->PlatformHandle = (void*)data->Window;
|
|
#ifdef _WIN32
|
|
viewport->PlatformHandleRaw = glfwGetWin32Window(data->Window);
|
|
#endif
|
|
glfwSetWindowPos(data->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);
|
|
|
|
// Install callbacks for secondary viewports
|
|
glfwSetMouseButtonCallback(data->Window, ImGui_ImplGlfw_MouseButtonCallback);
|
|
glfwSetScrollCallback(data->Window, ImGui_ImplGlfw_ScrollCallback);
|
|
glfwSetKeyCallback(data->Window, ImGui_ImplGlfw_KeyCallback);
|
|
glfwSetCharCallback(data->Window, ImGui_ImplGlfw_CharCallback);
|
|
glfwSetWindowCloseCallback(data->Window, ImGui_ImplGlfw_WindowCloseCallback);
|
|
glfwSetWindowPosCallback(data->Window, ImGui_ImplGlfw_WindowPosCallback);
|
|
glfwSetWindowSizeCallback(data->Window, ImGui_ImplGlfw_WindowSizeCallback);
|
|
if (g_ClientApi == GlfwClientApi_OpenGL)
|
|
{
|
|
glfwMakeContextCurrent(data->Window);
|
|
glfwSwapInterval(0);
|
|
}
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport)
|
|
{
|
|
if (ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData)
|
|
{
|
|
if (data->WindowOwned)
|
|
{
|
|
#if GLFW_HAS_GLFW_HOVERED && defined(_WIN32)
|
|
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
|
::RemovePropA(hwnd, "IMGUI_VIEWPORT");
|
|
#endif
|
|
glfwDestroyWindow(data->Window);
|
|
}
|
|
data->Window = NULL;
|
|
IM_DELETE(data);
|
|
}
|
|
viewport->PlatformUserData = viewport->PlatformHandle = NULL;
|
|
}
|
|
|
|
// FIXME-VIEWPORT: Implement same work-around for Linux/OSX in the meanwhile.
|
|
#if defined(_WIN32) && GLFW_HAS_GLFW_HOVERED
|
|
static WNDPROC g_GlfwWndProc = NULL;
|
|
static LRESULT CALLBACK WndProcNoInputs(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (msg == WM_NCHITTEST)
|
|
{
|
|
// Let mouse pass-through the window. This will allow the back-end to set io.MouseHoveredViewport properly (which is OPTIONAL).
|
|
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
|
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
|
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
|
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
|
if (viewport->Flags & ImGuiViewportFlags_NoInputs)
|
|
return HTTRANSPARENT;
|
|
}
|
|
return ::CallWindowProc(g_GlfwWndProc, hWnd, msg, wParam, lParam);
|
|
}
|
|
#endif
|
|
|
|
static void ImGui_ImplGlfw_ShowWindow(ImGuiViewport* viewport)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
|
|
#if defined(_WIN32)
|
|
// GLFW hack: Hide icon from task bar
|
|
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
|
if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon)
|
|
{
|
|
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
|
ex_style &= ~WS_EX_APPWINDOW;
|
|
ex_style |= WS_EX_TOOLWINDOW;
|
|
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
|
}
|
|
|
|
// GLFW hack: install hook for WM_NCHITTEST message handler
|
|
#if GLFW_HAS_GLFW_HOVERED && defined(_WIN32)
|
|
::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport);
|
|
if (g_GlfwWndProc == NULL)
|
|
g_GlfwWndProc = (WNDPROC)::GetWindowLongPtr(hwnd, GWLP_WNDPROC);
|
|
::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WndProcNoInputs);
|
|
#endif
|
|
|
|
#if !GLFW_HAS_FOCUS_ON_SHOW
|
|
// GLFW hack: GLFW 3.2 has a bug where glfwShowWindow() also activates/focus the window.
|
|
// The fix was pushed to GLFW repository on 2018/01/09 and should be included in GLFW 3.3 via a GLFW_FOCUS_ON_SHOW window attribute.
|
|
// See https://github.com/glfw/glfw/issues/1189
|
|
// FIXME-VIEWPORT: Implement same work-around for Linux/OSX in the meanwhile.
|
|
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
|
{
|
|
::ShowWindow(hwnd, SW_SHOWNA);
|
|
return;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
glfwShowWindow(data->Window);
|
|
}
|
|
|
|
static ImVec2 ImGui_ImplGlfw_GetWindowPos(ImGuiViewport* viewport)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
int x = 0, y = 0;
|
|
glfwGetWindowPos(data->Window, &x, &y);
|
|
return ImVec2((float)x, (float)y);
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
glfwSetWindowPos(data->Window, (int)pos.x, (int)pos.y);
|
|
}
|
|
|
|
static ImVec2 ImGui_ImplGlfw_GetWindowSize(ImGuiViewport* viewport)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
int w = 0, h = 0;
|
|
glfwGetWindowSize(data->Window, &w, &h);
|
|
return ImVec2((float)w, (float)h);
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
#if __APPLE__
|
|
// Native OS windows are positioned from the bottom-left corner on macOS, whereas on other platforms they are
|
|
// positioned from the upper-left corner. GLFW makes an effort to convert macOS style coordinates, however it
|
|
// doesn't handle it when changing size. We are manually moving the window in order for changes of size to be based
|
|
// on the upper-left corner.
|
|
int x, y, width, height;
|
|
glfwGetWindowPos(data->Window, &x, &y);
|
|
glfwGetWindowSize(data->Window, &width, &height);
|
|
glfwSetWindowPos(data->Window, x, y - height + size.y);
|
|
#endif
|
|
glfwSetWindowSize(data->Window, (int)size.x, (int)size.y);
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
glfwSetWindowTitle(data->Window, title);
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_SetWindowFocus(ImGuiViewport* viewport)
|
|
{
|
|
#if GLFW_HAS_FOCUS_WINDOW
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
glfwFocusWindow(data->Window);
|
|
#else
|
|
// FIXME: What are the effect of not having this function? At the moment imgui doesn't actually call SetWindowFocus - we set that up ahead, will answer that question later.
|
|
(void)viewport;
|
|
#endif
|
|
}
|
|
|
|
static bool ImGui_ImplGlfw_GetWindowFocus(ImGuiViewport* viewport)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
return glfwGetWindowAttrib(data->Window, GLFW_FOCUSED) != 0;
|
|
}
|
|
|
|
static bool ImGui_ImplGlfw_GetWindowMinimized(ImGuiViewport* viewport)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
return glfwGetWindowAttrib(data->Window, GLFW_ICONIFIED) != 0;
|
|
}
|
|
|
|
#if GLFW_HAS_WINDOW_ALPHA
|
|
static void ImGui_ImplGlfw_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
glfwSetWindowOpacity(data->Window, alpha);
|
|
}
|
|
#endif
|
|
|
|
static void ImGui_ImplGlfw_RenderWindow(ImGuiViewport* viewport, void*)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
if (g_ClientApi == GlfwClientApi_OpenGL)
|
|
glfwMakeContextCurrent(data->Window);
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_SwapBuffers(ImGuiViewport* viewport, void*)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
if (g_ClientApi == GlfwClientApi_OpenGL)
|
|
{
|
|
glfwMakeContextCurrent(data->Window);
|
|
glfwSwapBuffers(data->Window);
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------------
|
|
// IME (Input Method Editor) basic support for e.g. Asian language users
|
|
//--------------------------------------------------------------------------------------------------------
|
|
|
|
// We provide a Win32 implementation because this is such a common issue for IME users
|
|
#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS) && !defined(__GNUC__)
|
|
#define HAS_WIN32_IME 1
|
|
#include <imm.h>
|
|
#ifdef _MSC_VER
|
|
#pragma comment(lib, "imm32")
|
|
#endif
|
|
static void ImGui_ImplWin32_SetImeInputPos(ImGuiViewport* viewport, ImVec2 pos)
|
|
{
|
|
COMPOSITIONFORM cf = { CFS_FORCE_POSITION, { (LONG)(pos.x - viewport->Pos.x), (LONG)(pos.y - viewport->Pos.y) }, { 0, 0, 0, 0 } };
|
|
if (HWND hwnd = (HWND)viewport->PlatformHandleRaw)
|
|
if (HIMC himc = ::ImmGetContext(hwnd))
|
|
{
|
|
::ImmSetCompositionWindow(himc, &cf);
|
|
::ImmReleaseContext(hwnd, himc);
|
|
}
|
|
}
|
|
#else
|
|
#define HAS_WIN32_IME 0
|
|
#endif
|
|
|
|
//--------------------------------------------------------------------------------------------------------
|
|
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
|
|
//--------------------------------------------------------------------------------------------------------
|
|
|
|
// Avoid including <vulkan.h> so we can build without it
|
|
#if GLFW_HAS_VULKAN
|
|
#ifndef VULKAN_H_
|
|
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
|
|
#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
|
|
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
|
|
#else
|
|
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
|
|
#endif
|
|
VK_DEFINE_HANDLE(VkInstance)
|
|
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
|
|
struct VkAllocationCallbacks;
|
|
enum VkResult { VK_RESULT_MAX_ENUM = 0x7FFFFFFF };
|
|
#endif // VULKAN_H_
|
|
extern "C" { extern GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); }
|
|
static int ImGui_ImplGlfw_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
|
|
{
|
|
ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData;
|
|
IM_ASSERT(g_ClientApi == GlfwClientApi_Vulkan);
|
|
VkResult err = glfwCreateWindowSurface((VkInstance)vk_instance, data->Window, (const VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface);
|
|
return (int)err;
|
|
}
|
|
#endif // GLFW_HAS_VULKAN
|
|
|
|
// FIXME-PLATFORM: GLFW doesn't export monitor work area (see https://github.com/glfw/glfw/pull/989)
|
|
static void ImGui_ImplGlfw_UpdateMonitors()
|
|
{
|
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
int monitors_count = 0;
|
|
GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count);
|
|
platform_io.Monitors.resize(0);
|
|
for (int n = 0; n < monitors_count; n++)
|
|
{
|
|
ImGuiPlatformMonitor monitor;
|
|
int x, y;
|
|
glfwGetMonitorPos(glfw_monitors[n], &x, &y);
|
|
const GLFWvidmode* vid_mode = glfwGetVideoMode(glfw_monitors[n]);
|
|
#if GLFW_HAS_MONITOR_WORK_AREA
|
|
monitor.MainPos = ImVec2((float)x, (float)y);
|
|
monitor.MainSize = ImVec2((float)vid_mode->width, (float)vid_mode->height);
|
|
int w, h;
|
|
glfwGetMonitorWorkarea(glfw_monitors[n], &x, &y, &w, &h);
|
|
monitor.WorkPos = ImVec2((float)x, (float)y);;
|
|
monitor.WorkSize = ImVec2((float)w, (float)h);
|
|
#else
|
|
monitor.MainPos = monitor.WorkPos = ImVec2((float)x, (float)y);
|
|
monitor.MainSize = monitor.WorkSize = ImVec2((float)vid_mode->width, (float)vid_mode->height);
|
|
#endif
|
|
#if GLFW_HAS_PER_MONITOR_DPI
|
|
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
|
|
float x_scale, y_scale;
|
|
glfwGetMonitorContentScale(glfw_monitors[n], &x_scale, &y_scale);
|
|
monitor.DpiScale = x_scale;
|
|
#endif
|
|
platform_io.Monitors.push_back(monitor);
|
|
}
|
|
g_WantUpdateMonitors = false;
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
|
{
|
|
g_WantUpdateMonitors = true;
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_InitPlatformInterface()
|
|
{
|
|
// Register platform interface (will be coupled with a renderer interface)
|
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
platform_io.Platform_CreateWindow = ImGui_ImplGlfw_CreateWindow;
|
|
platform_io.Platform_DestroyWindow = ImGui_ImplGlfw_DestroyWindow;
|
|
platform_io.Platform_ShowWindow = ImGui_ImplGlfw_ShowWindow;
|
|
platform_io.Platform_SetWindowPos = ImGui_ImplGlfw_SetWindowPos;
|
|
platform_io.Platform_GetWindowPos = ImGui_ImplGlfw_GetWindowPos;
|
|
platform_io.Platform_SetWindowSize = ImGui_ImplGlfw_SetWindowSize;
|
|
platform_io.Platform_GetWindowSize = ImGui_ImplGlfw_GetWindowSize;
|
|
platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus;
|
|
platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus;
|
|
platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized;
|
|
platform_io.Platform_SetWindowTitle = ImGui_ImplGlfw_SetWindowTitle;
|
|
platform_io.Platform_RenderWindow = ImGui_ImplGlfw_RenderWindow;
|
|
platform_io.Platform_SwapBuffers = ImGui_ImplGlfw_SwapBuffers;
|
|
#if GLFW_HAS_WINDOW_ALPHA
|
|
platform_io.Platform_SetWindowAlpha = ImGui_ImplGlfw_SetWindowAlpha;
|
|
#endif
|
|
#if GLFW_HAS_VULKAN
|
|
platform_io.Platform_CreateVkSurface = ImGui_ImplGlfw_CreateVkSurface;
|
|
#endif
|
|
#if HAS_WIN32_IME
|
|
platform_io.Platform_SetImeInputPos = ImGui_ImplWin32_SetImeInputPos;
|
|
#endif
|
|
|
|
// Note: monitor callback are broken GLFW 3.2 and earlier (see github.com/glfw/glfw/issues/784)
|
|
ImGui_ImplGlfw_UpdateMonitors();
|
|
glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
|
|
|
|
// Register main window handle (which is owned by the main application, not by us)
|
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
ImGuiViewportDataGlfw* data = IM_NEW(ImGuiViewportDataGlfw)();
|
|
data->Window = g_Window;
|
|
data->WindowOwned = false;
|
|
main_viewport->PlatformUserData = data;
|
|
main_viewport->PlatformHandle = (void*)g_Window;
|
|
}
|
|
|
|
static void ImGui_ImplGlfw_ShutdownPlatformInterface()
|
|
{
|
|
}
|