Browse Source

Horizontal mouse wheel: renamed io.MouseHorizWheel to io.MouseWheelH. Reorganized the code in NewFrame(). Examples: Updated GLFW+GL and SDL+GL accordingly. (#1463)

omar 7 years ago
parent
commit
0b1fecb792

+ 6 - 7
examples/opengl2_example/imgui_impl_glfw_gl2.cpp

@@ -31,8 +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 ImVec2       g_MouseWheel = ImVec2(0.0f, 0.0f);
 static GLuint       g_FontTexture = 0;
 
 // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
@@ -137,8 +136,8 @@ void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action,
 
 void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double xoffset, double yoffset)
 {
-    g_MouseHorizWheel += (float)xoffset; // Use fractional mouse wheel.
-    g_MouseWheel += (float)yoffset;
+    g_MouseWheel.x += (float)xoffset; // Use fractional mouse wheel.
+    g_MouseWheel.y += (float)yoffset;
 }
 
 void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow*, int key, int, int action, int mods)
@@ -297,9 +296,9 @@ void ImGui_ImplGlfwGL2_NewFrame()
         g_MouseJustPressed[i] = false;
     }
 
-    io.MouseHorizWheel = g_MouseHorizWheel;
-    io.MouseWheel = g_MouseWheel;
-    g_MouseHorizWheel = g_MouseWheel = 0.0f;
+    io.MouseWheel = g_MouseWheel.y;
+    io.MouseWheelH = g_MouseWheel.x;
+    g_MouseWheel.x = g_MouseWheel.x = 0.0f;
 
     // Hide OS mouse cursor if ImGui is drawing it
     glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL);

+ 6 - 7
examples/opengl3_example/imgui_impl_glfw_gl3.cpp

@@ -25,8 +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 ImVec2       g_MouseWheel = ImVec2(0.0f, 0.0f);
 static GLuint       g_FontTexture = 0;
 static int          g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
 static int          g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
@@ -158,8 +157,8 @@ void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action,
 
 void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double xoffset, double yoffset)
 {
-    g_MouseHorizWheel += (float)xoffset; // Use fractional mouse wheel.
-    g_MouseWheel += (float)yoffset;
+    g_MouseWheel.x += (float)xoffset; // Use fractional mouse wheel.
+    g_MouseWheel.y += (float)yoffset;
 }
 
 void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow*, int key, int, int action, int mods)
@@ -409,9 +408,9 @@ void ImGui_ImplGlfwGL3_NewFrame()
         g_MouseJustPressed[i] = false;
     }
 
-    io.MouseHorizWheel = g_MouseHorizWheel;
-    io.MouseWheel = g_MouseWheel;
-    g_MouseHorizWheel = g_MouseWheel = 0.0f;
+    io.MouseWheel = g_MouseWheel.y;
+    io.MouseWheelH = g_MouseWheel.x;
+    g_MouseWheel.x = g_MouseWheel.x = 0.0f;
 
     // Hide OS mouse cursor if ImGui is drawing it
     glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL);

+ 8 - 13
examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp

@@ -24,8 +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 ImVec2       g_MouseWheel = ImVec2(0.0f, 0.0f);
 static GLuint       g_FontTexture = 0;
 
 // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
@@ -133,14 +132,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)
-                g_MouseWheel = -1;
+            if (event->wheel.x > 0) g_MouseWheel.x = +1;
+            if (event->wheel.x < 0) g_MouseWheel.x = -1;
+            if (event->wheel.y > 0) g_MouseWheel.y = +1;
+            if (event->wheel.y < 0) g_MouseWheel.y = -1;
             return true;
         }
     case SDL_MOUSEBUTTONDOWN:
@@ -279,13 +274,13 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window)
     int mx, my;
     Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my);
     io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
-    io.MouseWheel = g_MouseWheel;
-    io.MouseHorizWheel = g_MouseHorizWheel;
+    io.MouseWheel = g_MouseWheel.y;
+    io.MouseWheelH = g_MouseWheel.x;
     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;
-    g_MouseWheel = g_MouseHorizWheel = 0.0f;
+    g_MouseWheel.x = g_MouseWheel.x = 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)   

+ 8 - 13
examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp

@@ -19,8 +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 ImVec2       g_MouseWheel = ImVec2(0.0f, 0.0f);
 static GLuint       g_FontTexture = 0;
 static int          g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
 static int          g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
@@ -155,14 +154,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)
-                g_MouseWheel = -1;
+            if (event->wheel.x > 0) g_MouseWheel.x = +1;
+            if (event->wheel.x < 0) g_MouseWheel.x = -1;
+            if (event->wheel.y > 0) g_MouseWheel.y = +1;
+            if (event->wheel.y < 0) g_MouseWheel.y = -1;
             return true;
         }
     case SDL_MOUSEBUTTONDOWN:
@@ -390,13 +385,13 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window)
     int mx, my;
     Uint32 mouse_buttons = SDL_GetMouseState(&mx, &my);
     io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
-    io.MouseWheel = g_MouseWheel;
-    io.MouseHorizWheel = g_MouseHorizWheel;
+    io.MouseWheel = g_MouseWheel.y;
+    io.MouseWheelH = g_MouseWheel.x;
     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;
-    g_MouseHorizWheel = g_MouseWheel = 0.0f;
+    g_MouseWheel.x = g_MouseWheel.x = 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)   

+ 29 - 31
imgui.cpp

@@ -2483,47 +2483,45 @@ void ImGui::NewFrame()
     if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload)
         g.HoveredWindow = g.HoveredRootWindow = NULL;
 
-    // Scale & Scrolling
-    if (g.HoveredWindow && g.IO.MouseWheel != 0.0f && !g.HoveredWindow->Collapsed)
+    // Mouse wheel scrolling, scale
+    if (g.HoveredWindow && !g.HoveredWindow->Collapsed && (g.IO.MouseWheel != 0.0f || g.IO.MouseWheelH != 0.0f))
     {
+        // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set).
         ImGuiWindow* window = g.HoveredWindow;
-        if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
-        {
-            // Zoom / Scale window
-            const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
-            const float scale = new_font_scale / window->FontWindowScale;
-            window->FontWindowScale = new_font_scale;
+        ImGuiWindow* scroll_window = window;
+        while ((scroll_window->Flags & ImGuiWindowFlags_ChildWindow) && (scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoScrollbar) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs) && scroll_window->ParentWindow)
+            scroll_window = scroll_window->ParentWindow;
+        const bool scroll_allowed = !(scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs);
 
-            const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
-            window->Pos += offset;
-            window->PosFloat += offset;
-            window->Size *= scale;
-            window->SizeFull *= scale;
-        }
-        else if (!g.IO.KeyCtrl)
+        if (g.IO.MouseWheel != 0.0f)
         {
-            // Mouse wheel Scrolling
-            // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set).
-            ImGuiWindow* scroll_window = window;
-            while ((scroll_window->Flags & ImGuiWindowFlags_ChildWindow) && (scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoScrollbar) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs) && scroll_window->ParentWindow)
-                scroll_window = scroll_window->ParentWindow;
-
-            if (!(scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs))
+            if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
+            {
+                // Zoom / Scale window
+                const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
+                const float scale = new_font_scale / window->FontWindowScale;
+                window->FontWindowScale = new_font_scale;
+
+                const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
+                window->Pos += offset;
+                window->PosFloat += offset;
+                window->Size *= scale;
+                window->SizeFull *= scale;
+            }
+            else if (!g.IO.KeyCtrl && scroll_allowed)
             {
+                // Mouse wheel vertical scrolling
                 float scroll_amount = 5 * scroll_window->CalcFontSize();
                 scroll_amount = (float)(int)ImMin(scroll_amount, (scroll_window->ContentsRegionRect.GetHeight() + scroll_window->WindowPadding.y * 2.0f) * 0.67f);
                 SetWindowScrollY(scroll_window, scroll_window->Scroll.y - g.IO.MouseWheel * scroll_amount);
             }
         }
-    }
-
-    // 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))
+        if (g.IO.MouseWheelH != 0.0f && scroll_allowed)
         {
-            SetWindowScrollX(window, window->Scroll.x - g.IO.MouseHorizWheel * 10.f);
+            // Mouse wheel horizontal scrolling (for hardware that supports it)
+            float scroll_amount = scroll_window->CalcFontSize();
+            if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse))
+                SetWindowScrollX(window, window->Scroll.x - g.IO.MouseWheelH * scroll_amount);
         }
     }
 
@@ -3040,7 +3038,7 @@ void ImGui::EndFrame()
     g.Windows.swap(g.WindowsSortBuffer);
 
     // Clear Input data for next frame
-    g.IO.MouseWheel = 0.0f;
+    g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
     memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
 
     g.FrameCountEnded = g.FrameCount;

+ 2 - 2
imgui.h

@@ -930,8 +930,8 @@ 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
+    float       MouseWheel;                 // Mouse wheel: 1 unit scrolls about 5 lines text. 
+    float       MouseWheelH;                // Mouse wheel (Horizontal). Most users don't have a mouse with an horizontal wheel, may not be filled by all back ends.
     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