From f3e510a9bf508337244433f8c1dcc6c120dcc990 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 19 Jan 2018 10:46:54 +0100 Subject: [PATCH] Examples: SDL: Using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. (#1559) Digging into sdl window/mouse stuff will also be useful for multi-viewport work. --- .../imgui_impl_sdl_gl2.cpp | 28 +++++++++++------ .../imgui_impl_sdl_gl3.cpp | 30 ++++++++++++------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 802a31be..6bcd4c38 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -270,23 +270,33 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); g_Time = current_time; - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + // Setup mouse inputs (we already got mouse wheel, keyboard keys & characters from our event handler) int mx, my; Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); - else - io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX); - + io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + io.MouseWheel = g_MouseWheel; io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // 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[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - io.MouseWheel = g_MouseWheel; g_MouseWheel = 0.0f; + // We need to use SDL_CaptureMouse() to easily retrieve mouse coordinates outside of the client area. This is only supported from SDL 2.0.4 (released Jan 2016) +#if (SDL_MAJOR_VERSION >= 2) && (SDL_MINOR_VERSION >= 0) && (SDL_PATCHLEVEL >= 4) + if ((SDL_GetWindowFlags(window) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_MOUSE_CAPTURE)) != 0) + io.MousePos = ImVec2((float)mx, (float)my); + bool any_mouse_button_down = false; + for (int n = 0; n < IM_ARRAYSIZE(io.MouseDown); n++) + any_mouse_button_down |= io.MouseDown[n]; + if (any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) == 0) + SDL_CaptureMouse(SDL_TRUE); + if (!any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) != 0) + SDL_CaptureMouse(SDL_FALSE); +#else + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0) + io.MousePos = ImVec2((float)mx, (float)my); +#endif + // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index e9a1393c..ef1957a5 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -381,23 +381,33 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f); g_Time = current_time; - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + // Setup mouse inputs (we already got mouse wheel, keyboard keys & characters from our event handler) int mx, my; Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); - else - io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - - io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // 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.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + io.MouseWheel = g_MouseWheel; + io.MouseDown[0] = g_MousePressed[0] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0; // 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[1] = g_MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; io.MouseDown[2] = g_MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - io.MouseWheel = g_MouseWheel; g_MouseWheel = 0.0f; + // We need to use SDL_CaptureMouse() to easily retrieve mouse coordinates outside of the client area. This is only supported from SDL 2.0.4 (released Jan 2016) +#if (SDL_MAJOR_VERSION >= 2) && (SDL_MINOR_VERSION >= 0) && (SDL_PATCHLEVEL >= 4) + if ((SDL_GetWindowFlags(window) & (SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_MOUSE_CAPTURE)) != 0) + io.MousePos = ImVec2((float)mx, (float)my); + bool any_mouse_button_down = false; + for (int n = 0; n < IM_ARRAYSIZE(io.MouseDown); n++) + any_mouse_button_down |= io.MouseDown[n]; + if (any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) == 0) + SDL_CaptureMouse(SDL_TRUE); + if (!any_mouse_button_down && (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE) != 0) + SDL_CaptureMouse(SDL_FALSE); +#else + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS) != 0) + io.MousePos = ImVec2((float)mx, (float)my); +#endif + // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1);