diff --git a/backends/imgui_impl_allegro5.cpp b/backends/imgui_impl_allegro5.cpp index 2a5868d83fbd..cef70e636d30 100644 --- a/backends/imgui_impl_allegro5.cpp +++ b/backends/imgui_impl_allegro5.cpp @@ -17,6 +17,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). // 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. @@ -469,29 +470,28 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev) case ALLEGRO_EVENT_MOUSE_AXES: if (ev->mouse.display == bd->Display) { - io.MouseWheel += ev->mouse.dz; - io.MouseWheelH -= ev->mouse.dw; - io.MousePos = ImVec2(ev->mouse.x, ev->mouse.y); + io.AddMousePosEvent(ev->mouse.x, ev->mouse.y); + io.AddMouseWheelEvent(-ev->mouse.dw, ev->mouse.dz); } return true; case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: case ALLEGRO_EVENT_MOUSE_BUTTON_UP: - if (ev->mouse.display == bd->Display && ev->mouse.button <= 5) - io.MouseDown[ev->mouse.button - 1] = (ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN); + if (ev->mouse.display == bd->Display && ev->mouse.button > 0 && ev->mouse.button <= 5) + io.AddMouseButtonEvent(ev->mouse.button - 1, ev->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN); return true; case ALLEGRO_EVENT_TOUCH_MOVE: if (ev->touch.display == bd->Display) - io.MousePos = ImVec2(ev->touch.x, ev->touch.y); + io.AddMousePosEvent(ev->touch.x, ev->touch.y); return true; case ALLEGRO_EVENT_TOUCH_BEGIN: case ALLEGRO_EVENT_TOUCH_END: case ALLEGRO_EVENT_TOUCH_CANCEL: if (ev->touch.display == bd->Display && ev->touch.primary) - io.MouseDown[0] = (ev->type == ALLEGRO_EVENT_TOUCH_BEGIN); + io.AddMouseButtonEvent(0, ev->type == ALLEGRO_EVENT_TOUCH_BEGIN); return true; case ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY: if (ev->mouse.display == bd->Display) - io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); return true; case ALLEGRO_EVENT_KEY_CHAR: if (ev->keyboard.display == bd->Display) diff --git a/backends/imgui_impl_android.cpp b/backends/imgui_impl_android.cpp index 380e4f9de40d..82f388a5fb3f 100644 --- a/backends/imgui_impl_android.cpp +++ b/backends/imgui_impl_android.cpp @@ -19,6 +19,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2021-03-04: Initial version. @@ -227,26 +228,25 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(AInputEvent* input_event) if((AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_FINGER) || (AMotionEvent_getToolType(input_event, event_pointer_index) == AMOTION_EVENT_TOOL_TYPE_UNKNOWN)) { - io.MouseDown[0] = (event_action == AMOTION_EVENT_ACTION_DOWN); - io.MousePos = ImVec2(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); + io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); + io.AddMouseButtonEvent(0, event_action == AMOTION_EVENT_ACTION_DOWN); } break; case AMOTION_EVENT_ACTION_BUTTON_PRESS: case AMOTION_EVENT_ACTION_BUTTON_RELEASE: { int32_t button_state = AMotionEvent_getButtonState(input_event); - io.MouseDown[0] = ((button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0); - io.MouseDown[1] = ((button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0); - io.MouseDown[2] = ((button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0); + io.AddMouseButtonEvent(0, (button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0); + io.AddMouseButtonEvent(1, (button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0); + io.AddMouseButtonEvent(2, (button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0); } break; case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse) case AMOTION_EVENT_ACTION_MOVE: // Touch pointer moves while DOWN - io.MousePos = ImVec2(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); + io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index)); break; case AMOTION_EVENT_ACTION_SCROLL: - io.MouseWheel = AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_VSCROLL, event_pointer_index); - io.MouseWheelH = AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_HSCROLL, event_pointer_index); + io.AddMouseWheelEvent(AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_HSCROLL, event_pointer_index), AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_VSCROLL, event_pointer_index)); break; default: break; diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index ae98581f1dfb..4dea6238bf0b 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -16,6 +16,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). // 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates. // 2022-01-12: *BREAKING CHANGE*: Now using glfwSetCursorPosCallback(). If you called ImGui_ImplGlfw_InitXXX() with install_callbacks = false, you MUST install glfwSetCursorPosCallback() and forward it to the backend via ImGui_ImplGlfw_CursorPosCallback(). // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. @@ -86,7 +87,6 @@ struct ImGui_ImplGlfw_Data GlfwClientApi ClientApi; double Time; GLFWwindow* MouseWindow; - bool MouseJustPressed[ImGuiMouseButton_COUNT]; GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT]; bool InstalledCallbacks; @@ -257,8 +257,10 @@ void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int acti bd->PrevUserCallbackMousebutton(window, button, action, mods); ImGui_ImplGlfw_UpdateKeyModifiers(mods); - if (action == GLFW_PRESS && button >= 0 && button < IM_ARRAYSIZE(bd->MouseJustPressed)) - bd->MouseJustPressed[button] = true; + + ImGuiIO& io = ImGui::GetIO(); + if (button >= 0 && button < ImGuiMouseButton_COUNT) + io.AddMouseButtonEvent(button, action == GLFW_PRESS); } void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset) @@ -268,8 +270,7 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo bd->PrevUserCallbackScroll(window, xoffset, yoffset); ImGuiIO& io = ImGui::GetIO(); - io.MouseWheelH += (float)xoffset; - io.MouseWheel += (float)yoffset; + io.AddMouseWheelEvent((float)xoffset, (float)yoffset); } static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode) @@ -333,7 +334,7 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y) bd->PrevUserCallbackCursorPos(window, x, y); ImGuiIO& io = ImGui::GetIO(); - io.MousePos = ImVec2((float)x, (float)y); + io.AddMousePosEvent((float)x, (float)y); } void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered) @@ -348,7 +349,7 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered) if (!entered && bd->MouseWindow == window) { bd->MouseWindow = NULL; - io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); } } @@ -501,16 +502,9 @@ static void ImGui_ImplGlfw_UpdateMouseData() { double mouse_x, mouse_y; glfwGetCursorPos(bd->Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); + io.AddMousePosEvent((float)mouse_x, (float)mouse_y); } } - - // Update buttons - for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) - { - io.MouseDown[i] = bd->MouseJustPressed[i] || glfwGetMouseButton(bd->Window, i) != 0; - bd->MouseJustPressed[i] = false; - } } static void ImGui_ImplGlfw_UpdateMouseCursor() diff --git a/backends/imgui_impl_glut.cpp b/backends/imgui_impl_glut.cpp index a316c895c6c3..85ee838d92ce 100644 --- a/backends/imgui_impl_glut.cpp +++ b/backends/imgui_impl_glut.cpp @@ -20,6 +20,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2019-04-03: Misc: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. // 2019-03-25: Misc: Made io.DeltaTime always above zero. @@ -264,26 +265,22 @@ void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y) void ImGui_ImplGLUT_MouseFunc(int glut_button, int state, int x, int y) { ImGuiIO& io = ImGui::GetIO(); - io.MousePos = ImVec2((float)x, (float)y); + io.AddMousePosEvent((float)x, (float)y); int button = -1; if (glut_button == GLUT_LEFT_BUTTON) button = 0; if (glut_button == GLUT_RIGHT_BUTTON) button = 1; if (glut_button == GLUT_MIDDLE_BUTTON) button = 2; - if (button != -1 && state == GLUT_DOWN) - io.MouseDown[button] = true; - if (button != -1 && state == GLUT_UP) - io.MouseDown[button] = false; + if (button != -1 && state == GLUT_DOWN || state == GLUT_UP) + io.AddMouseButtonEvent(button, state == GLUT_DOWN); } #ifdef __FREEGLUT_EXT_H__ void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y) { ImGuiIO& io = ImGui::GetIO(); - io.MousePos = ImVec2((float)x, (float)y); - if (dir > 0) - io.MouseWheel += 1.0; - else if (dir < 0) - io.MouseWheel -= 1.0; + io.AddMousePosEvent((float)x, (float)y); + if (dir != 0) + io.AddMouseWheelEvent(0.0f, dir > 0 ? 1.0f : -1.0f); (void)button; // Unused } #endif @@ -297,5 +294,5 @@ void ImGui_ImplGLUT_ReshapeFunc(int w, int h) void ImGui_ImplGLUT_MotionFunc(int x, int y) { ImGuiIO& io = ImGui::GetIO(); - io.MousePos = ImVec2((float)x, (float)y); + io.AddMousePosEvent((float)x, (float)y); } diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 146fff1e3e3d..58e5a09f6b94 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -23,6 +23,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). // 2022-01-12: Inputs: Added basic Platform IME support, hooking the io.SetPlatformImeDataFn() function. // 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range. // 2021-12-13: *BREAKING CHANGE* Add NSView parameter to ImGui_ImplOSX_Init(). Generally fix keyboard support. Using kVK_* codes for keyboard keys. @@ -51,8 +52,6 @@ static double g_Time = 0.0; static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static bool g_MouseCursorHidden = false; -static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {}; -static bool g_MouseDown[ImGuiMouseButton_COUNT] = {}; static ImFocusObserver* g_FocusObserver = nil; static KeyEventResponder* g_KeyEventResponder = nil; static NSTextInputContext* g_InputContext = nil; @@ -450,17 +449,9 @@ void ImGui_ImplOSX_Shutdown() g_FocusObserver = NULL; } -static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() +static void ImGui_ImplOSX_UpdateMouseCursor() { - // Update buttons ImGuiIO& io = ImGui::GetIO(); - for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) - { - // 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[i] = g_MouseJustPressed[i] || g_MouseDown[i]; - g_MouseJustPressed[i] = false; - } - if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) return; @@ -562,7 +553,7 @@ void ImGui_ImplOSX_NewFrame(NSView* view) io.DeltaTime = (float)(current_time - g_Time); g_Time = current_time; - ImGui_ImplOSX_UpdateMouseCursorAndButtons(); + ImGui_ImplOSX_UpdateMouseCursor(); ImGui_ImplOSX_UpdateGamepads(); ImGui_ImplOSX_UpdateImePosWithView(view); } @@ -574,16 +565,16 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown) { int button = (int)[event buttonNumber]; - if (button >= 0 && button < IM_ARRAYSIZE(g_MouseDown)) - g_MouseDown[button] = g_MouseJustPressed[button] = true; + if (button >= 0 && button < ImGuiMouseButton_COUNT) + io.AddMouseButtonEvent(button, true); return io.WantCaptureMouse; } if (event.type == NSEventTypeLeftMouseUp || event.type == NSEventTypeRightMouseUp || event.type == NSEventTypeOtherMouseUp) { int button = (int)[event buttonNumber]; - if (button >= 0 && button < IM_ARRAYSIZE(g_MouseDown)) - g_MouseDown[button] = false; + if (button >= 0 && button < ImGuiMouseButton_COUNT) + io.AddMouseButtonEvent(button, false); return io.WantCaptureMouse; } @@ -592,7 +583,7 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) NSPoint mousePoint = event.locationInWindow; mousePoint = [view convertPoint:mousePoint fromView:nil]; mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y); - io.MousePos = ImVec2((float)mousePoint.x, (float)mousePoint.y); + io.AddMousePosEvent((float)mousePoint.x, (float)mousePoint.y); } if (event.type == NSEventTypeScrollWheel) @@ -632,11 +623,9 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) wheel_dx = [event deltaX]; wheel_dy = [event deltaY]; } + if (wheel_dx != 0.0 || wheel_dx != 0.0) + io.AddMouseWheelEvent((float)wheel_dx * 0.1f, (float)wheel_dy * 0.1f); - if (fabs(wheel_dx) > 0.0) - io.MouseWheelH += (float)wheel_dx * 0.1f; - if (fabs(wheel_dy) > 0.0) - io.MouseWheel += (float)wheel_dy * 0.1f; return io.WantCaptureMouse; } diff --git a/backends/imgui_impl_sdl.cpp b/backends/imgui_impl_sdl.cpp index 480846b981bf..a04233c7105a 100644 --- a/backends/imgui_impl_sdl.cpp +++ b/backends/imgui_impl_sdl.cpp @@ -18,6 +18,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). // 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates. // 2022-01-12: Update mouse inputs using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API. // 2022-01-12: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. @@ -78,7 +79,6 @@ struct ImGui_ImplSDL2_Data SDL_Window* Window; Uint64 Time; int MouseButtonsDown; - bool MousePressed[3]; SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT]; char* ClipboardTextData; bool MouseCanUseGlobalState; @@ -248,15 +248,14 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) { case SDL_MOUSEMOTION: { - io.MousePos = ImVec2((float)event->motion.x, (float)event->motion.y); + io.AddMousePosEvent((float)event->motion.x, (float)event->motion.y); return true; } case SDL_MOUSEWHEEL: { - if (event->wheel.x > 0) io.MouseWheelH += 1; - if (event->wheel.x < 0) io.MouseWheelH -= 1; - if (event->wheel.y > 0) io.MouseWheel += 1; - if (event->wheel.y < 0) io.MouseWheel -= 1; + float wheel_x = (event->wheel.x > 0) ? 1.0f : (event->wheel.x < 0) ? -1.0f : 0.0f; + float wheel_y = (event->wheel.y > 0) ? 1.0f : (event->wheel.y < 0) ? -1.0f : 0.0f; + io.AddMouseWheelEvent(wheel_x, wheel_y); return true; } case SDL_MOUSEBUTTONDOWN: @@ -268,8 +267,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) if (event->button.button == SDL_BUTTON_MIDDLE) { mouse_button = 2; } if (mouse_button == -1) break; - if (event->type == SDL_MOUSEBUTTONDOWN) - bd->MousePressed[mouse_button] = true; + io.AddMouseButtonEvent(mouse_button, (event->type == SDL_MOUSEBUTTONDOWN)); bd->MouseButtonsDown = (event->type == SDL_MOUSEBUTTONDOWN) ? (bd->MouseButtonsDown | (1 << mouse_button)) : (bd->MouseButtonsDown & ~(1 << mouse_button)); return true; } @@ -290,7 +288,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) case SDL_WINDOWEVENT: { if (event->window.event == SDL_WINDOWEVENT_LEAVE) - io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); if (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) io.AddFocusEvent(true); else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST) @@ -438,16 +436,9 @@ static void ImGui_ImplSDL2_UpdateMouseData() int window_x, window_y, mouse_x_global, mouse_y_global; SDL_GetGlobalMouseState(&mouse_x_global, &mouse_y_global); SDL_GetWindowPosition(bd->Window, &window_x, &window_y); - io.MousePos = ImVec2((float)(mouse_x_global - window_x), (float)(mouse_y_global - window_y)); + io.AddMousePosEvent((float)(mouse_x_global - window_x), (float)(mouse_y_global - window_y)); } } - - // Update buttons - Uint32 mouse_buttons = SDL_GetMouseState(NULL, NULL); - io.MouseDown[0] = bd->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] = bd->MousePressed[1] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - io.MouseDown[2] = bd->MousePressed[2] || (mouse_buttons & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; - bd->MousePressed[0] = bd->MousePressed[1] = bd->MousePressed[2] = false; } static void ImGui_ImplSDL2_UpdateMouseCursor() diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 2b140b54e492..db3462fa123b 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -34,6 +34,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). // 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before a key event (not in NewFrame) to fix input queue with very low framerates. // 2022-01-12: Inputs: Update mouse inputs using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback to provide it when focused but not hovered/captured. More standard and will allow us to pass it to future input queue API. // 2022-01-12: Inputs: Maintain our own copy of MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. @@ -265,7 +266,7 @@ static void ImGui_ImplWin32_UpdateMouseData() { POINT pos; if (::GetCursorPos(&pos) && ::ScreenToClient(bd->hWnd, &pos)) - io.MousePos = ImVec2((float)pos.x, (float)pos.y); + io.AddMousePosEvent((float)pos.x, (float)pos.y); } } } @@ -510,13 +511,13 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA ::TrackMouseEvent(&tme); bd->MouseTracked = true; } - io.MousePos = ImVec2((float)GET_X_LPARAM(lParam), (float)GET_Y_LPARAM(lParam)); + io.AddMousePosEvent((float)GET_X_LPARAM(lParam), (float)GET_Y_LPARAM(lParam)); break; case WM_MOUSELEAVE: if (bd->MouseHwnd == hwnd) bd->MouseHwnd = NULL; bd->MouseTracked = false; - io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); break; case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: @@ -531,7 +532,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA if (bd->MouseButtonsDown == 0 && ::GetCapture() == NULL) ::SetCapture(hwnd); bd->MouseButtonsDown |= 1 << button; - io.MouseDown[button] = true; + io.AddMouseButtonEvent(button, true); return 0; } case WM_LBUTTONUP: @@ -547,14 +548,14 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA bd->MouseButtonsDown &= ~(1 << button); if (bd->MouseButtonsDown == 0 && ::GetCapture() == hwnd) ::ReleaseCapture(); - io.MouseDown[button] = false; + io.AddMouseButtonEvent(button, false); return 0; } case WM_MOUSEWHEEL: - io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; + io.AddMouseWheelEvent(0.0f, (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA); return 0; case WM_MOUSEHWHEEL: - io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; + io.AddMouseWheelEvent((float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA, 0.0f); return 0; case WM_KEYDOWN: case WM_KEYUP: diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 69f7b4fdca01..3104582cf56f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -38,7 +38,10 @@ HOW TO UPDATE? Breaking Changes: - Removed support for pre-C++11 compilers. We'll stop supporting VS2010. (#4537) -- Reworked IO keyboard input system. (#2625, #3724) [@thedmd, @ocornut] +- Reworked IO mouse input API: (#4858) [@thedmd, @ocornut] + - Added io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions, + obsoleting writing directly to io.MousePos, io.MouseDown[], io.MouseWheel, etc. +- Reworked IO keyboard input API: (#2625, #3724) [@thedmd, @ocornut] - Added io.AddKeyEvent() function, obsoleting writing directly to io.KeyMap[], io.KeysDown[] arrays. - Added io.AddKeyModsEvent() function, obsoleting writing directly to io.KeyCtrl, io.KeyShift etc. - Added io.SetKeyEventNativeData() function (optional) to pass native and old legacy indices. @@ -47,9 +50,10 @@ Breaking Changes: - Obsoleted GetKeyIndex(): it is now unnecessary and will now return the same value. - All keyboard related functions taking 'int user_key_index' now take 'ImGuiKey key': - IsKeyDown(), IsKeyPressed(), IsKeyReleased(), GetKeyPressedAmount(). - - All backends were updated to use io.AddKeyEvent(). + - Added io.ConfigInputEventQueue (defaulting to true) to disable input queue trickling. - Backward compatibility: - - Old backends populating those arrays should still work! (for a while) + - All backends updated to use new functions. + - Old backends populating those arrays should still work! - Calling e.g. IsKeyPressed(MY_NATIVE_KEY_XXX) will still work! (for a while) - Those legacy arrays will only be disabled if '#define IMGUI_DISABLE_OBSOLETE_KEYIO' is set in your imconfig. In a few versions, IMGUI_DISABLE_OBSOLETE_FUNCTIONS will automatically enable IMGUI_DISABLE_OBSOLETE_KEYIO, @@ -104,16 +108,21 @@ Other Changes: We are now converting GLFW untranslated keycodes back to translated keycodes in order to match the behavior of every other backend, and facilitate the use of GLFW with lettered-shortcuts API. (#456, #2625) - Backends: GLFW: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) +- Backends: GLFW: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858) - Backends: GLFW: Update mouse position using glfwSetCursorPosCallback() + fallback when focused but not hovered/captured. - Backends: Win32: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) - Backends: Win32: Update mouse position using WM_MOUSEMOVE/WM_MOUSELEAVE + fallback when focused but not hovered/captured. +- Backends: Win32: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858) - Backends: Win32: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. - Backends: SDL: Pass localized keys (matching keyboard layout). Fix e.g. CTRL+A, CTRL+Z, CTRL+Y shortcuts. - Backends: SDL: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) - Backends: SDL: Update mouse position using SDL_MOUSEMOTION/SDL_WINDOWEVENT_LEAVE + fallback when focused but not hovered/captured. +- Backends: SDL: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858) - Backends: SDL: Maintain a MouseButtonsDown mask instead of using ImGui::IsAnyMouseDown() which will be obsoleted. - Backends: Allegro5: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) +- Backends: Allegro5: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858) - Backends: Android, GLUT, OSX: Submit keys using io.AddKeyEvent(). Submit keymods using io.AddKeyModsEvent() at the same time. (#2625) +- Backends: Android, GLUT, OSX: Submit mouse data using io.AddMousePosEvent(), AddMouseButtonEvent(), AddMouseWheelEvent() functions. (#4858) - Backends: OpenGL3: Fixed a buffer overflow in imgui_impl_opengl3_loader.h init (added in 1.86). (#4468, #4830) [@dymk] It would generally not have noticeable side-effect at runtime but would be detected by runtime checkers. - Backends: Metal: Added Apple Metal C++ API support. (#4824, #4746) [@luigifcruz] diff --git a/imgui.cpp b/imgui.cpp index b84b2b0f89b1..c4a3f902b125 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1262,7 +1262,7 @@ void ImGuiIO::AddKeyEvent(ImGuiKey key, bool down) KeysData[keydata_index].Down = down; } -// [Optional] Call add AddKeyEvent(). +// [Optional] Call after AddKeyEvent(). // Specify native keycode, scancode + Specify index for legacy <1.87 IsKeyXXX() functions with native indices. // If you are writing a backend in 2022 or don't use IsKeyXXX() with native values that are not ImGuiKey values, you can avoid calling this. void ImGuiIO::SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index) @@ -1294,6 +1294,32 @@ void ImGuiIO::AddKeyModsEvent(ImGuiKeyModFlags modifiers) KeySuper = (modifiers & ImGuiKeyModFlags_Super) != 0; } +// Queue a mouse move event +void ImGuiIO::AddMousePosEvent(float x, float y) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(&g.IO == this && "Can only add events to current context."); + g.IO.MousePos = ImVec2(x, y); +} + +void ImGuiIO::AddMouseWheelEvent(float wheel_x, float wheel_y) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(&g.IO == this && "Can only add events to current context."); + if (wheel_x == 0.0f && wheel_y == 0.0f) + return; + g.IO.MouseWheelH += wheel_x; + g.IO.MouseWheel += wheel_y; +} + +void ImGuiIO::AddMouseButtonEvent(int mouse_button, bool down) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(&g.IO == this && "Can only add events to current context."); + IM_ASSERT(mouse_button >= 0 && mouse_button < ImGuiMouseButton_COUNT); + g.IO.MouseDown[mouse_button] = down; +} + void ImGuiIO::AddFocusEvent(bool focused) { // We intentionally overwrite this and process in NewFrame(), in order to give a chance diff --git a/imgui.h b/imgui.h index 1f5df0cc04ef..e7b9091adbb3 100644 --- a/imgui.h +++ b/imgui.h @@ -65,7 +65,7 @@ Index of this file: // Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) #define IMGUI_VERSION "1.87 WIP" -#define IMGUI_VERSION_NUM 18606 +#define IMGUI_VERSION_NUM 18607 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_HAS_TABLE @@ -1994,10 +1994,14 @@ struct ImGuiIO // Input Functions IMGUI_API void AddKeyEvent(ImGuiKey key, bool down); // Queue a new key down/up event. Key should be "translated" (as in, generally ImGuiKey_A matches the key end-user would use to emit an 'A' character) IMGUI_API void AddKeyModsEvent(ImGuiKeyModFlags modifiers);// Queue a change of Ctrl/Shift/Alt/Super modifiers + IMGUI_API void AddMousePosEvent(float x, float y); // Queue a mouse position update. Use -FLT_MAX,-FLT_MAX to signify no mouse (e.g. app not focused and not hovered) + IMGUI_API void AddMouseButtonEvent(int button, bool down); // Queue a mouse button change + IMGUI_API void AddMouseWheelEvent(float wh_x, float wh_y); // Queue a mouse wheel update IMGUI_API void AddFocusEvent(bool focused); // Queue an hosting application/platform windows gain or loss of focus IMGUI_API void AddInputCharacter(unsigned int c); // Queue new character input IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue new character input from an UTF-16 character, it can be a surrogate IMGUI_API void AddInputCharactersUTF8(const char* str); // Queue new characters input from an UTF-8 string + IMGUI_API void ClearInputCharacters(); // [Internal] Clear the text input buffer manually IMGUI_API void ClearInputKeys(); // [Internal] Release all keys IMGUI_API void SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index = -1); // [Optional] Specify index for legacy <1.87 IsKeyXXX() functions with native indices + specify native keycode, scancode.