forked from erincatto/box2d-lite
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Clone imgui impl files to make xcode happy. Fixed VC code gen.
- Loading branch information
Showing
6 changed files
with
618 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,322 @@ | ||
// 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). | ||
|
||
// 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) | ||
// 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/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 | ||
|
||
// Data | ||
enum GlfwClientApi | ||
{ | ||
GlfwClientApi_Unknown, | ||
GlfwClientApi_OpenGL, | ||
GlfwClientApi_Vulkan | ||
}; | ||
static GLFWwindow* g_Window = NULL; | ||
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 }; | ||
|
||
// Chain GLFW callbacks: 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; | ||
|
||
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) | ||
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) | ||
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) | ||
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) | ||
g_PrevUserCallbackChar(window, c); | ||
|
||
ImGuiIO& io = ImGui::GetIO(); | ||
if (c > 0 && c < 0x10000) | ||
io.AddInputCharacter((unsigned short)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.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_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; | ||
#if defined(_WIN32) | ||
io.ImeWindowHandle = (void*)glfwGetWin32Window(g_Window); | ||
#endif | ||
|
||
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); | ||
} | ||
|
||
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() | ||
{ | ||
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); | ||
#ifdef __EMSCRIPTEN__ | ||
const bool focused = true; // Emscripten | ||
#else | ||
const bool focused = glfwGetWindowAttrib(g_Window, GLFW_FOCUSED) != 0; | ||
#endif | ||
if (focused) | ||
{ | ||
if (io.WantSetMousePos) | ||
{ | ||
glfwSetCursorPos(g_Window, (double)mouse_pos_backup.x, (double)mouse_pos_backup.y); | ||
} | ||
else | ||
{ | ||
double mouse_x, mouse_y; | ||
glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); | ||
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); | ||
} | ||
} | ||
} | ||
|
||
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(); | ||
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) | ||
{ | ||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor | ||
glfwSetInputMode(g_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(g_Window, g_MouseCursors[imgui_cursor] ? g_MouseCursors[imgui_cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); | ||
glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); | ||
} | ||
} | ||
|
||
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); | ||
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); | ||
|
||
// 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(); | ||
|
||
// Gamepad navigation mapping [BETA] | ||
memset(io.NavInputs, 0, sizeof(io.NavInputs)); | ||
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) | ||
{ | ||
// 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; | ||
} | ||
} |
Oops, something went wrong.