Skip to content

Commit

Permalink
Examples: GLFW: User previously installed GLFW callbacks are now save…
Browse files Browse the repository at this point in the history
…d and chain-called by the default callbacks. (#1759)
  • Loading branch information
ocornut committed Nov 8, 2018
1 parent 9d155c7 commit 7723543
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 21 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ Other Changes:
in particular, points_count==0 could lead to a memory stomp if the draw list was previously empty.
- Examples: DirectX10, DirectX11: Removed seemingly unnecessary calls to invalidate and recreate device objects
in the WM_SIZE handler. (#2088) [@ice1000]
- Examples: GLFW: User previously installed GLFW callbacks are now saved and chain-called by the default callbacks. (#1759)
- Examples: OpenGL3+GLFW: Fixed error condition when using the GLAD loader. (#2157) [@blackball]
- Examples: OpenGL3+GLFW/SDL: Made main.cpp compile with IMGUI_IMPL_OPENGL_LOADER_CUSTOM (may be missing init). (#2178) [@doug-moen]

Expand Down
1 change: 0 additions & 1 deletion examples/example_glfw_opengl2/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ int main(int, char**)
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls

// Setup Platform/Renderer bindings
// If you have already installed GLFW callbacks in your app, call ImGui_ImplGlfw_InitForOpenGL() with install_callbacks=false and call them yourself.
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL2_Init();

Expand Down
1 change: 0 additions & 1 deletion examples/example_glfw_opengl3/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ int main(int, char**)
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls

// Setup Platform/Renderer bindings
// If you have already installed GLFW callbacks in your app, call ImGui_ImplGlfw_InitForOpenGL() with install_callbacks=false and call them yourself.
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glsl_version);

Expand Down
1 change: 0 additions & 1 deletion examples/example_glfw_vulkan/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,6 @@ int main(int, char**)
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls

// Setup Platform/Renderer bindings
// If you have already installed GLFW callbacks in your app, call ImGui_ImplGlfw_InitForVulkan() with install_callbacks=false and call the functions yourself.
ImGui_ImplGlfw_InitForVulkan(window, true);
ImGui_ImplVulkan_InitInfo init_info = {};
init_info.Instance = g_Instance;
Expand Down
52 changes: 38 additions & 14 deletions examples/imgui_impl_glfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 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.
Expand Down Expand Up @@ -51,11 +52,17 @@ enum GlfwClientApi
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 };
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)
{
Expand All @@ -67,36 +74,48 @@ static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
glfwSetClipboardString((GLFWwindow*)user_data, text);
}

void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/)
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*, double xoffset, double yoffset)
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*, int key, int, int action, int mods)
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;

(void)mods; // Modifiers are not reliable across systems
// 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*, unsigned int c)
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);
Expand Down Expand Up @@ -151,12 +170,17 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
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)
{
glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback);
glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback);
glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback);
glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback);
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;
Expand Down
6 changes: 2 additions & 4 deletions examples/imgui_impl_glfw.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool in
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();

// GLFW callbacks are installed by default if you call the InitXXX function with 'install_callbacks=true'.
// If you already have GLFW callbacks installed by your application, call the InitXXX function with install_callbacks=false,
// then call the functions yourselves from your own GLFW callbacks.
// You may also handle inputs yourself and use those as a reference.
// InitXXX function with 'install_callbacks=true': install GLFW callbacks. They will call user's previously installed callbacks, if any.
// InitXXX function with 'install_callbacks=false': do not install GLFW callbacks. You will need to call them yourself from your own GLFW callbacks.
IMGUI_IMPL_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
Expand Down

0 comments on commit 7723543

Please sign in to comment.