diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp index 364d9288..8aa6395a 100644 --- a/examples/opengl2_example/imgui_impl_glfw.cpp +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -31,6 +31,7 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; +static float g_MouseHorizWheel = 0.0f; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -136,9 +137,10 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, g_MouseJustPressed[button] = true; } -void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel. + g_MouseHorizWheel += (float)xoffset; // Use fractional mouse wheel. + g_MouseWheel += (float)yoffset; } void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -296,8 +298,9 @@ void ImGui_ImplGlfwGL2_NewFrame() g_MouseJustPressed[i] = false; } + io.MouseHorizWheel = g_MouseHorizWheel; io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; + g_MouseHorizWheel = g_MouseWheel = 0.0f; // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 7d924fcf..01accf0c 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -25,6 +25,7 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; +static float g_MouseHorizWheel = 0.0f; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; @@ -155,9 +156,10 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, g_MouseJustPressed[button] = true; } -void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel. + g_MouseHorizWheel += (float)xoffset; // Use fractional mouse wheel. + g_MouseWheel += (float)yoffset; } void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow*, int key, int, int action, int mods) @@ -408,8 +410,9 @@ void ImGui_ImplGlfwGL3_NewFrame() g_MouseJustPressed[i] = false; } + io.MouseHorizWheel = g_MouseHorizWheel; io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; + g_MouseHorizWheel = g_MouseWheel = 0.0f; // Hide OS mouse cursor if ImGui is drawing it glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp index 66f3ed5a..b0a2553d 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -24,6 +24,7 @@ // Data static double g_Time = 0.0f; static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseHorizWheel = 0.0f; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; @@ -134,6 +135,10 @@ bool ImGui_ImplSdlGL2_ProcessEvent(SDL_Event* event) { case SDL_MOUSEWHEEL: { + if (event->wheel.x > 0) + g_MouseHorizWheel = 1; + if (event->wheel.x < 0) + g_MouseHorizWheel = -1; if (event->wheel.y > 0) g_MouseWheel = 1; if (event->wheel.y < 0) @@ -285,8 +290,9 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + io.MouseHorizWheel = g_MouseHorizWheel; io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; + g_MouseWheel = g_MouseHorizWheel = 0.0f; // 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 68e27a68..933669cf 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -19,6 +19,7 @@ // Data static double g_Time = 0.0f; static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseHorizWheel = 0.0f; static float g_MouseWheel = 0.0f; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; @@ -154,6 +155,10 @@ bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event) { case SDL_MOUSEWHEEL: { + if (event->wheel.x > 0) + g_MouseHorizWheel = 1; + if (event->wheel.x < 0) + g_MouseHorizWheel = -1; if (event->wheel.y > 0) g_MouseWheel = 1; if (event->wheel.y < 0) @@ -396,8 +401,9 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + io.MouseHorizWheel = g_MouseHorizWheel; io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; + g_MouseHorizWheel = g_MouseWheel = 0.0f; // Hide OS mouse cursor if ImGui is drawing it SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); diff --git a/imgui.cpp b/imgui.cpp index 211bd299..f13cfb4d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -628,6 +628,7 @@ static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); static ImFont* GetDefaultFont(); static void SetCurrentFont(ImFont* font); static void SetCurrentWindow(ImGuiWindow* window); +static void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x); static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y); static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond); static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond); @@ -2430,6 +2431,16 @@ void ImGui::NewFrame() } } + // Horizontal wheel scrolling; for consistency, only allowed if Ctrl is not pressed. + if (g.HoveredWindow && g.IO.MouseHorizWheel != 0.0f && !g.HoveredWindow->Collapsed) + { + ImGuiWindow* window = g.HoveredWindow; + if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) + { + SetWindowScrollX(window, window->Scroll.x - g.IO.MouseHorizWheel * 10.f); + } + } + // Pressing TAB activate widget focus if (g.ActiveId == 0 && g.NavWindow != NULL && g.NavWindow->Active && IsKeyPressedMap(ImGuiKey_Tab, false)) g.NavWindow->FocusIdxTabRequestNext = 0; @@ -5244,6 +5255,13 @@ ImVec2 ImGui::GetWindowPos() return window->Pos; } +static void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x) +{ + window->DC.CursorMaxPos.x += window->Scroll.x; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it. + window->Scroll.x = new_scroll_x; + window->DC.CursorMaxPos.x -= window->Scroll.x; +} + static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y) { window->DC.CursorMaxPos.y += window->Scroll.y; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it. diff --git a/imgui.h b/imgui.h index 4599d705..d45b5e86 100644 --- a/imgui.h +++ b/imgui.h @@ -856,6 +856,7 @@ struct ImGuiIO ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) bool MouseDown[5]; // Mouse buttons: left, right, middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. + float MouseHorizWheel; // Horizontal mouse wheel bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). bool KeyCtrl; // Keyboard modifier pressed: Control bool KeyShift; // Keyboard modifier pressed: Shift