Examples: GLFW: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). (#1495)

This commit is contained in:
omar 2018-02-20 14:18:02 +01:00
parent 11b12488e8
commit d534207622
3 changed files with 95 additions and 10 deletions

View File

@ -19,6 +19,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
// 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL2 in their name. // 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL2 in their name.
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL2_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL2_RenderDrawData() in the .h file so you can call it yourself.
// 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: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
@ -45,10 +46,13 @@
#include <GLFW/glfw3native.h> #include <GLFW/glfw3native.h>
#endif #endif
// Data // GLFW data
static GLFWwindow* g_Window = NULL; static GLFWwindow* g_Window = NULL;
static double g_Time = 0.0f; static double g_Time = 0.0f;
static bool g_MouseJustPressed[3] = { false, false, false }; static bool g_MouseJustPressed[3] = { false, false, false };
static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 };
// OpenGL data
static GLuint g_FontTexture = 0; static GLuint g_FontTexture = 0;
// OpenGL2 Render function. // OpenGL2 Render function.
@ -259,6 +263,16 @@ bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks)
io.ImeWindowHandle = glfwGetWin32Window(g_Window); io.ImeWindowHandle = glfwGetWin32Window(g_Window);
#endif #endif
// Load cursors
// FIXME: GLFW doesn't expose suitable cursors for ResizeAll, ResizeNESW, ResizeNWSE. We revert to arrow cursor for those.
g_MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
g_MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
if (install_callbacks) if (install_callbacks)
ImGui_ImplGlfw_InstallCallbacks(window); ImGui_ImplGlfw_InstallCallbacks(window);
@ -267,6 +281,12 @@ bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks)
void ImGui_ImplGlfwGL2_Shutdown() void ImGui_ImplGlfwGL2_Shutdown()
{ {
// Destroy GLFW mouse cursors
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++)
glfwDestroyCursor(g_MouseCursors[cursor_n]);
memset(g_MouseCursors, 0, sizeof(g_MouseCursors));
// Destroy OpenGL objects
ImGui_ImplGlfwGL2_InvalidateDeviceObjects(); ImGui_ImplGlfwGL2_InvalidateDeviceObjects();
} }
@ -317,8 +337,17 @@ void ImGui_ImplGlfwGL2_NewFrame()
g_MouseJustPressed[i] = false; g_MouseJustPressed[i] = false;
} }
// Hide OS mouse cursor if ImGui is drawing it // Update mouse cursor
glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); ImGuiMouseCursor cursor = ImGui::GetMouseCursor();
if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None)
{
glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
}
else
{
glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
glfwSetCursor(g_Window, g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]);
}
// Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application.
ImGui::NewFrame(); ImGui::NewFrame();

View File

@ -13,6 +13,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
// 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL3 in their name. // 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL3 in their name.
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL3_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL3_RenderDrawData() in the .h file so you can call it yourself.
// 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: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
@ -42,10 +43,13 @@
#include <GLFW/glfw3native.h> #include <GLFW/glfw3native.h>
#endif #endif
// Data // GLFW data
static GLFWwindow* g_Window = NULL; static GLFWwindow* g_Window = NULL;
static double g_Time = 0.0f; static double g_Time = 0.0f;
static bool g_MouseJustPressed[3] = { false, false, false }; static bool g_MouseJustPressed[3] = { false, false, false };
static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 };
// OpenGL3 data
static GLuint g_FontTexture = 0; static GLuint g_FontTexture = 0;
static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
@ -374,6 +378,16 @@ bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks)
io.ImeWindowHandle = glfwGetWin32Window(g_Window); io.ImeWindowHandle = glfwGetWin32Window(g_Window);
#endif #endif
// Load cursors
// FIXME: GLFW doesn't expose suitable cursors for ResizeAll, ResizeNESW, ResizeNWSE. We revert to arrow cursor for those.
g_MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
g_MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
if (install_callbacks) if (install_callbacks)
ImGui_ImplGlfw_InstallCallbacks(window); ImGui_ImplGlfw_InstallCallbacks(window);
@ -382,6 +396,12 @@ bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks)
void ImGui_ImplGlfwGL3_Shutdown() void ImGui_ImplGlfwGL3_Shutdown()
{ {
// Destroy GLFW mouse cursors
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++)
glfwDestroyCursor(g_MouseCursors[cursor_n]);
memset(g_MouseCursors, 0, sizeof(g_MouseCursors));
// Destroy OpenGL objects
ImGui_ImplGlfwGL3_InvalidateDeviceObjects(); ImGui_ImplGlfwGL3_InvalidateDeviceObjects();
} }
@ -432,8 +452,17 @@ void ImGui_ImplGlfwGL3_NewFrame()
g_MouseJustPressed[i] = false; g_MouseJustPressed[i] = false;
} }
// Hide OS mouse cursor if ImGui is drawing it // Update mouse cursor
glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); ImGuiMouseCursor cursor = ImGui::GetMouseCursor();
if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None)
{
glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
}
else
{
glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
glfwSetCursor(g_Window, g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]);
}
// Gamepad navigation mapping [BETA] // Gamepad navigation mapping [BETA]
memset(io.NavInputs, 0, sizeof(io.NavInputs)); memset(io.NavInputs, 0, sizeof(io.NavInputs));

View File

@ -10,6 +10,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
// 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include Vulkan in their name. // 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include Vulkan in their name.
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback, ImGui_ImplGlfwVulkan_Render() calls ImGui_ImplGlfwVulkan_RenderDrawData() itself. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback, ImGui_ImplGlfwVulkan_Render() calls ImGui_ImplGlfwVulkan_RenderDrawData() itself.
// 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: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
@ -37,12 +38,13 @@
#include <GLFW/glfw3native.h> #include <GLFW/glfw3native.h>
#endif #endif
// GLFW Data // GLFW data
static GLFWwindow* g_Window = NULL; static GLFWwindow* g_Window = NULL;
static double g_Time = 0.0f; static double g_Time = 0.0f;
static bool g_MouseJustPressed[3] = { false, false, false }; static bool g_MouseJustPressed[3] = { false, false, false };
static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 };
// Vulkan Data // Vulkan data
static VkAllocationCallbacks* g_Allocator = NULL; static VkAllocationCallbacks* g_Allocator = NULL;
static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE; static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE;
static VkDevice g_Device = VK_NULL_HANDLE; static VkDevice g_Device = VK_NULL_HANDLE;
@ -797,6 +799,16 @@ bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, Im
io.ImeWindowHandle = glfwGetWin32Window(g_Window); io.ImeWindowHandle = glfwGetWin32Window(g_Window);
#endif #endif
// Load cursors
// FIXME: GLFW doesn't expose suitable cursors for ResizeAll, ResizeNESW, ResizeNWSE. We revert to arrow cursor for those.
g_MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
g_MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
if (install_callbacks) if (install_callbacks)
ImGui_ImplGlfw_InstallCallbacks(window); ImGui_ImplGlfw_InstallCallbacks(window);
@ -807,6 +819,12 @@ bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, Im
void ImGui_ImplGlfwVulkan_Shutdown() void ImGui_ImplGlfwVulkan_Shutdown()
{ {
// Destroy GLFW mouse cursors
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++)
glfwDestroyCursor(g_MouseCursors[cursor_n]);
memset(g_MouseCursors, 0, sizeof(g_MouseCursors));
// Destroy Vulkan objects
ImGui_ImplGlfwVulkan_InvalidateDeviceObjects(); ImGui_ImplGlfwVulkan_InvalidateDeviceObjects();
} }
@ -846,8 +864,17 @@ void ImGui_ImplGlfwVulkan_NewFrame()
g_MouseJustPressed[i] = false; g_MouseJustPressed[i] = false;
} }
// Hide OS mouse cursor if ImGui is drawing it // Update mouse cursor
glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); ImGuiMouseCursor cursor = ImGui::GetMouseCursor();
if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None)
{
glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
}
else
{
glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
glfwSetCursor(g_Window, g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]);
}
// Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application.
ImGui::NewFrame(); ImGui::NewFrame();