|
@@ -4248,204 +4248,6 @@ static bool IsWindowActiveAndVisible(ImGuiWindow* window)
|
|
return (window->Active) && (!window->Hidden);
|
|
return (window->Active) && (!window->Hidden);
|
|
}
|
|
}
|
|
|
|
|
|
-static void UpdateAliasKey(ImGuiKey key, bool v, float analog_value)
|
|
|
|
-{
|
|
|
|
- IM_ASSERT(ImGui::IsAliasKey(key));
|
|
|
|
- ImGuiKeyData* key_data = ImGui::GetKeyData(key);
|
|
|
|
- key_data->Down = v;
|
|
|
|
- key_data->AnalogValue = analog_value;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// [Internal] Do not use directly
|
|
|
|
-static ImGuiKeyChord GetMergedModsFromKeys()
|
|
|
|
-{
|
|
|
|
- ImGuiKeyChord mods = 0;
|
|
|
|
- if (ImGui::IsKeyDown(ImGuiMod_Ctrl)) { mods |= ImGuiMod_Ctrl; }
|
|
|
|
- if (ImGui::IsKeyDown(ImGuiMod_Shift)) { mods |= ImGuiMod_Shift; }
|
|
|
|
- if (ImGui::IsKeyDown(ImGuiMod_Alt)) { mods |= ImGuiMod_Alt; }
|
|
|
|
- if (ImGui::IsKeyDown(ImGuiMod_Super)) { mods |= ImGuiMod_Super; }
|
|
|
|
- return mods;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void ImGui::UpdateKeyboardInputs()
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- ImGuiIO& io = g.IO;
|
|
|
|
-
|
|
|
|
- // Import legacy keys or verify they are not used
|
|
|
|
-#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
|
|
- if (io.BackendUsingLegacyKeyArrays == 0)
|
|
|
|
- {
|
|
|
|
- // Backend used new io.AddKeyEvent() API: Good! Verify that old arrays are never written to externally.
|
|
|
|
- for (int n = 0; n < ImGuiKey_LegacyNativeKey_END; n++)
|
|
|
|
- IM_ASSERT((io.KeysDown[n] == false || IsKeyDown((ImGuiKey)n)) && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- if (g.FrameCount == 0)
|
|
|
|
- for (int n = ImGuiKey_LegacyNativeKey_BEGIN; n < ImGuiKey_LegacyNativeKey_END; n++)
|
|
|
|
- IM_ASSERT(g.IO.KeyMap[n] == -1 && "Backend is not allowed to write to io.KeyMap[0..511]!");
|
|
|
|
-
|
|
|
|
- // Build reverse KeyMap (Named -> Legacy)
|
|
|
|
- for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++)
|
|
|
|
- if (io.KeyMap[n] != -1)
|
|
|
|
- {
|
|
|
|
- IM_ASSERT(IsLegacyKey((ImGuiKey)io.KeyMap[n]));
|
|
|
|
- io.KeyMap[io.KeyMap[n]] = n;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Import legacy keys into new ones
|
|
|
|
- for (int n = ImGuiKey_LegacyNativeKey_BEGIN; n < ImGuiKey_LegacyNativeKey_END; n++)
|
|
|
|
- if (io.KeysDown[n] || io.BackendUsingLegacyKeyArrays == 1)
|
|
|
|
- {
|
|
|
|
- const ImGuiKey key = (ImGuiKey)(io.KeyMap[n] != -1 ? io.KeyMap[n] : n);
|
|
|
|
- IM_ASSERT(io.KeyMap[n] == -1 || IsNamedKey(key));
|
|
|
|
- io.KeysData[key].Down = io.KeysDown[n];
|
|
|
|
- if (key != n)
|
|
|
|
- io.KeysDown[key] = io.KeysDown[n]; // Allow legacy code using io.KeysDown[GetKeyIndex()] with old backends
|
|
|
|
- io.BackendUsingLegacyKeyArrays = 1;
|
|
|
|
- }
|
|
|
|
- if (io.BackendUsingLegacyKeyArrays == 1)
|
|
|
|
- {
|
|
|
|
- GetKeyData(ImGuiMod_Ctrl)->Down = io.KeyCtrl;
|
|
|
|
- GetKeyData(ImGuiMod_Shift)->Down = io.KeyShift;
|
|
|
|
- GetKeyData(ImGuiMod_Alt)->Down = io.KeyAlt;
|
|
|
|
- GetKeyData(ImGuiMod_Super)->Down = io.KeySuper;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
|
|
- const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
|
|
|
|
- if (io.BackendUsingLegacyNavInputArray && nav_gamepad_active)
|
|
|
|
- {
|
|
|
|
- #define MAP_LEGACY_NAV_INPUT_TO_KEY1(_KEY, _NAV1) do { io.KeysData[_KEY].Down = (io.NavInputs[_NAV1] > 0.0f); io.KeysData[_KEY].AnalogValue = io.NavInputs[_NAV1]; } while (0)
|
|
|
|
- #define MAP_LEGACY_NAV_INPUT_TO_KEY2(_KEY, _NAV1, _NAV2) do { io.KeysData[_KEY].Down = (io.NavInputs[_NAV1] > 0.0f) || (io.NavInputs[_NAV2] > 0.0f); io.KeysData[_KEY].AnalogValue = ImMax(io.NavInputs[_NAV1], io.NavInputs[_NAV2]); } while (0)
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceDown, ImGuiNavInput_Activate);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceRight, ImGuiNavInput_Cancel);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceLeft, ImGuiNavInput_Menu);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceUp, ImGuiNavInput_Input);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadLeft, ImGuiNavInput_DpadLeft);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadRight, ImGuiNavInput_DpadRight);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadUp, ImGuiNavInput_DpadUp);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadDown, ImGuiNavInput_DpadDown);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY2(ImGuiKey_GamepadL1, ImGuiNavInput_FocusPrev, ImGuiNavInput_TweakSlow);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY2(ImGuiKey_GamepadR1, ImGuiNavInput_FocusNext, ImGuiNavInput_TweakFast);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickLeft, ImGuiNavInput_LStickLeft);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickRight, ImGuiNavInput_LStickRight);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickUp, ImGuiNavInput_LStickUp);
|
|
|
|
- MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickDown, ImGuiNavInput_LStickDown);
|
|
|
|
- #undef NAV_MAP_KEY
|
|
|
|
- }
|
|
|
|
-#endif
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
- // Update aliases
|
|
|
|
- for (int n = 0; n < ImGuiMouseButton_COUNT; n++)
|
|
|
|
- UpdateAliasKey(MouseButtonToKey(n), io.MouseDown[n], io.MouseDown[n] ? 1.0f : 0.0f);
|
|
|
|
- UpdateAliasKey(ImGuiKey_MouseWheelX, io.MouseWheelH != 0.0f, io.MouseWheelH);
|
|
|
|
- UpdateAliasKey(ImGuiKey_MouseWheelY, io.MouseWheel != 0.0f, io.MouseWheel);
|
|
|
|
-
|
|
|
|
- // Synchronize io.KeyMods and io.KeyXXX values.
|
|
|
|
- // - New backends (1.87+): send io.AddKeyEvent(ImGuiMod_XXX) -> -> (here) deriving io.KeyMods + io.KeyXXX from key array.
|
|
|
|
- // - Legacy backends: set io.KeyXXX bools -> (above) set key array from io.KeyXXX -> (here) deriving io.KeyMods + io.KeyXXX from key array.
|
|
|
|
- // So with legacy backends the 4 values will do a unnecessary back-and-forth but it makes the code simpler and future facing.
|
|
|
|
- io.KeyMods = GetMergedModsFromKeys();
|
|
|
|
- io.KeyCtrl = (io.KeyMods & ImGuiMod_Ctrl) != 0;
|
|
|
|
- io.KeyShift = (io.KeyMods & ImGuiMod_Shift) != 0;
|
|
|
|
- io.KeyAlt = (io.KeyMods & ImGuiMod_Alt) != 0;
|
|
|
|
- io.KeySuper = (io.KeyMods & ImGuiMod_Super) != 0;
|
|
|
|
-
|
|
|
|
- // Clear gamepad data if disabled
|
|
|
|
- if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0)
|
|
|
|
- for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++)
|
|
|
|
- {
|
|
|
|
- io.KeysData[i - ImGuiKey_KeysData_OFFSET].Down = false;
|
|
|
|
- io.KeysData[i - ImGuiKey_KeysData_OFFSET].AnalogValue = 0.0f;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Update keys
|
|
|
|
- for (int i = 0; i < ImGuiKey_KeysData_SIZE; i++)
|
|
|
|
- {
|
|
|
|
- ImGuiKeyData* key_data = &io.KeysData[i];
|
|
|
|
- key_data->DownDurationPrev = key_data->DownDuration;
|
|
|
|
- key_data->DownDuration = key_data->Down ? (key_data->DownDuration < 0.0f ? 0.0f : key_data->DownDuration + io.DeltaTime) : -1.0f;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Update keys/input owner (named keys only): one entry per key
|
|
|
|
- for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1))
|
|
|
|
- {
|
|
|
|
- ImGuiKeyData* key_data = &io.KeysData[key - ImGuiKey_KeysData_OFFSET];
|
|
|
|
- ImGuiKeyOwnerData* owner_data = &g.KeysOwnerData[key - ImGuiKey_NamedKey_BEGIN];
|
|
|
|
- owner_data->OwnerCurr = owner_data->OwnerNext;
|
|
|
|
- if (!key_data->Down) // Important: ownership is released on the frame after a release. Ensure a 'MouseDown -> CloseWindow -> MouseUp' chain doesn't lead to someone else seeing the MouseUp.
|
|
|
|
- owner_data->OwnerNext = ImGuiKeyOwner_None;
|
|
|
|
- owner_data->LockThisFrame = owner_data->LockUntilRelease = owner_data->LockUntilRelease && key_data->Down; // Clear LockUntilRelease when key is not Down anymore
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- UpdateKeyRoutingTable(&g.KeysRoutingTable);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void ImGui::UpdateMouseInputs()
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- ImGuiIO& io = g.IO;
|
|
|
|
-
|
|
|
|
- // Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well)
|
|
|
|
- if (IsMousePosValid(&io.MousePos))
|
|
|
|
- io.MousePos = g.MouseLastValidPos = ImFloorSigned(io.MousePos);
|
|
|
|
-
|
|
|
|
- // If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta
|
|
|
|
- if (IsMousePosValid(&io.MousePos) && IsMousePosValid(&io.MousePosPrev))
|
|
|
|
- io.MouseDelta = io.MousePos - io.MousePosPrev;
|
|
|
|
- else
|
|
|
|
- io.MouseDelta = ImVec2(0.0f, 0.0f);
|
|
|
|
-
|
|
|
|
- // If mouse moved we re-enable mouse hovering in case it was disabled by gamepad/keyboard. In theory should use a >0.0f threshold but would need to reset in everywhere we set this to true.
|
|
|
|
- if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)
|
|
|
|
- g.NavDisableMouseHover = false;
|
|
|
|
-
|
|
|
|
- io.MousePosPrev = io.MousePos;
|
|
|
|
- for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
|
|
|
- {
|
|
|
|
- io.MouseClicked[i] = io.MouseDown[i] && io.MouseDownDuration[i] < 0.0f;
|
|
|
|
- io.MouseClickedCount[i] = 0; // Will be filled below
|
|
|
|
- io.MouseReleased[i] = !io.MouseDown[i] && io.MouseDownDuration[i] >= 0.0f;
|
|
|
|
- io.MouseDownDurationPrev[i] = io.MouseDownDuration[i];
|
|
|
|
- io.MouseDownDuration[i] = io.MouseDown[i] ? (io.MouseDownDuration[i] < 0.0f ? 0.0f : io.MouseDownDuration[i] + io.DeltaTime) : -1.0f;
|
|
|
|
- if (io.MouseClicked[i])
|
|
|
|
- {
|
|
|
|
- bool is_repeated_click = false;
|
|
|
|
- if ((float)(g.Time - io.MouseClickedTime[i]) < io.MouseDoubleClickTime)
|
|
|
|
- {
|
|
|
|
- ImVec2 delta_from_click_pos = IsMousePosValid(&io.MousePos) ? (io.MousePos - io.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f);
|
|
|
|
- if (ImLengthSqr(delta_from_click_pos) < io.MouseDoubleClickMaxDist * io.MouseDoubleClickMaxDist)
|
|
|
|
- is_repeated_click = true;
|
|
|
|
- }
|
|
|
|
- if (is_repeated_click)
|
|
|
|
- io.MouseClickedLastCount[i]++;
|
|
|
|
- else
|
|
|
|
- io.MouseClickedLastCount[i] = 1;
|
|
|
|
- io.MouseClickedTime[i] = g.Time;
|
|
|
|
- io.MouseClickedPos[i] = io.MousePos;
|
|
|
|
- io.MouseClickedCount[i] = io.MouseClickedLastCount[i];
|
|
|
|
- io.MouseDragMaxDistanceSqr[i] = 0.0f;
|
|
|
|
- }
|
|
|
|
- else if (io.MouseDown[i])
|
|
|
|
- {
|
|
|
|
- // Maintain the maximum distance we reaching from the initial click position, which is used with dragging threshold
|
|
|
|
- float delta_sqr_click_pos = IsMousePosValid(&io.MousePos) ? ImLengthSqr(io.MousePos - io.MouseClickedPos[i]) : 0.0f;
|
|
|
|
- io.MouseDragMaxDistanceSqr[i] = ImMax(io.MouseDragMaxDistanceSqr[i], delta_sqr_click_pos);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // We provide io.MouseDoubleClicked[] as a legacy service
|
|
|
|
- io.MouseDoubleClicked[i] = (io.MouseClickedCount[i] == 2);
|
|
|
|
-
|
|
|
|
- // Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation
|
|
|
|
- if (io.MouseClicked[i])
|
|
|
|
- g.NavDisableMouseHover = false;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
|
|
// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
|
|
void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
|
void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
|
{
|
|
{
|
|
@@ -7772,6 +7574,11 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
|
|
// - GetMouseCursor()
|
|
// - GetMouseCursor()
|
|
// - SetMouseCursor()
|
|
// - SetMouseCursor()
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
+// - UpdateAliasKey()
|
|
|
|
+// - GetMergedModsFromKeys()
|
|
|
|
+// - UpdateKeyboardInputs()
|
|
|
|
+// - UpdateMouseInputs()
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
// - LockWheelingWindow [Internal]
|
|
// - LockWheelingWindow [Internal]
|
|
// - FindBestWheelingWindow [Internal]
|
|
// - FindBestWheelingWindow [Internal]
|
|
// - UpdateMouseWheel() [Internal]
|
|
// - UpdateMouseWheel() [Internal]
|
|
@@ -8360,6 +8167,204 @@ void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type)
|
|
g.MouseCursor = cursor_type;
|
|
g.MouseCursor = cursor_type;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void UpdateAliasKey(ImGuiKey key, bool v, float analog_value)
|
|
|
|
+{
|
|
|
|
+ IM_ASSERT(ImGui::IsAliasKey(key));
|
|
|
|
+ ImGuiKeyData* key_data = ImGui::GetKeyData(key);
|
|
|
|
+ key_data->Down = v;
|
|
|
|
+ key_data->AnalogValue = analog_value;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// [Internal] Do not use directly
|
|
|
|
+static ImGuiKeyChord GetMergedModsFromKeys()
|
|
|
|
+{
|
|
|
|
+ ImGuiKeyChord mods = 0;
|
|
|
|
+ if (ImGui::IsKeyDown(ImGuiMod_Ctrl)) { mods |= ImGuiMod_Ctrl; }
|
|
|
|
+ if (ImGui::IsKeyDown(ImGuiMod_Shift)) { mods |= ImGuiMod_Shift; }
|
|
|
|
+ if (ImGui::IsKeyDown(ImGuiMod_Alt)) { mods |= ImGuiMod_Alt; }
|
|
|
|
+ if (ImGui::IsKeyDown(ImGuiMod_Super)) { mods |= ImGuiMod_Super; }
|
|
|
|
+ return mods;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void ImGui::UpdateKeyboardInputs()
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiIO& io = g.IO;
|
|
|
|
+
|
|
|
|
+ // Import legacy keys or verify they are not used
|
|
|
|
+#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
|
|
+ if (io.BackendUsingLegacyKeyArrays == 0)
|
|
|
|
+ {
|
|
|
|
+ // Backend used new io.AddKeyEvent() API: Good! Verify that old arrays are never written to externally.
|
|
|
|
+ for (int n = 0; n < ImGuiKey_LegacyNativeKey_END; n++)
|
|
|
|
+ IM_ASSERT((io.KeysDown[n] == false || IsKeyDown((ImGuiKey)n)) && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (g.FrameCount == 0)
|
|
|
|
+ for (int n = ImGuiKey_LegacyNativeKey_BEGIN; n < ImGuiKey_LegacyNativeKey_END; n++)
|
|
|
|
+ IM_ASSERT(g.IO.KeyMap[n] == -1 && "Backend is not allowed to write to io.KeyMap[0..511]!");
|
|
|
|
+
|
|
|
|
+ // Build reverse KeyMap (Named -> Legacy)
|
|
|
|
+ for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++)
|
|
|
|
+ if (io.KeyMap[n] != -1)
|
|
|
|
+ {
|
|
|
|
+ IM_ASSERT(IsLegacyKey((ImGuiKey)io.KeyMap[n]));
|
|
|
|
+ io.KeyMap[io.KeyMap[n]] = n;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Import legacy keys into new ones
|
|
|
|
+ for (int n = ImGuiKey_LegacyNativeKey_BEGIN; n < ImGuiKey_LegacyNativeKey_END; n++)
|
|
|
|
+ if (io.KeysDown[n] || io.BackendUsingLegacyKeyArrays == 1)
|
|
|
|
+ {
|
|
|
|
+ const ImGuiKey key = (ImGuiKey)(io.KeyMap[n] != -1 ? io.KeyMap[n] : n);
|
|
|
|
+ IM_ASSERT(io.KeyMap[n] == -1 || IsNamedKey(key));
|
|
|
|
+ io.KeysData[key].Down = io.KeysDown[n];
|
|
|
|
+ if (key != n)
|
|
|
|
+ io.KeysDown[key] = io.KeysDown[n]; // Allow legacy code using io.KeysDown[GetKeyIndex()] with old backends
|
|
|
|
+ io.BackendUsingLegacyKeyArrays = 1;
|
|
|
|
+ }
|
|
|
|
+ if (io.BackendUsingLegacyKeyArrays == 1)
|
|
|
|
+ {
|
|
|
|
+ GetKeyData(ImGuiMod_Ctrl)->Down = io.KeyCtrl;
|
|
|
|
+ GetKeyData(ImGuiMod_Shift)->Down = io.KeyShift;
|
|
|
|
+ GetKeyData(ImGuiMod_Alt)->Down = io.KeyAlt;
|
|
|
|
+ GetKeyData(ImGuiMod_Super)->Down = io.KeySuper;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
|
|
|
+ const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
|
|
|
|
+ if (io.BackendUsingLegacyNavInputArray && nav_gamepad_active)
|
|
|
|
+ {
|
|
|
|
+ #define MAP_LEGACY_NAV_INPUT_TO_KEY1(_KEY, _NAV1) do { io.KeysData[_KEY].Down = (io.NavInputs[_NAV1] > 0.0f); io.KeysData[_KEY].AnalogValue = io.NavInputs[_NAV1]; } while (0)
|
|
|
|
+ #define MAP_LEGACY_NAV_INPUT_TO_KEY2(_KEY, _NAV1, _NAV2) do { io.KeysData[_KEY].Down = (io.NavInputs[_NAV1] > 0.0f) || (io.NavInputs[_NAV2] > 0.0f); io.KeysData[_KEY].AnalogValue = ImMax(io.NavInputs[_NAV1], io.NavInputs[_NAV2]); } while (0)
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceDown, ImGuiNavInput_Activate);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceRight, ImGuiNavInput_Cancel);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceLeft, ImGuiNavInput_Menu);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceUp, ImGuiNavInput_Input);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadLeft, ImGuiNavInput_DpadLeft);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadRight, ImGuiNavInput_DpadRight);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadUp, ImGuiNavInput_DpadUp);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadDown, ImGuiNavInput_DpadDown);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY2(ImGuiKey_GamepadL1, ImGuiNavInput_FocusPrev, ImGuiNavInput_TweakSlow);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY2(ImGuiKey_GamepadR1, ImGuiNavInput_FocusNext, ImGuiNavInput_TweakFast);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickLeft, ImGuiNavInput_LStickLeft);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickRight, ImGuiNavInput_LStickRight);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickUp, ImGuiNavInput_LStickUp);
|
|
|
|
+ MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickDown, ImGuiNavInput_LStickDown);
|
|
|
|
+ #undef NAV_MAP_KEY
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ // Update aliases
|
|
|
|
+ for (int n = 0; n < ImGuiMouseButton_COUNT; n++)
|
|
|
|
+ UpdateAliasKey(MouseButtonToKey(n), io.MouseDown[n], io.MouseDown[n] ? 1.0f : 0.0f);
|
|
|
|
+ UpdateAliasKey(ImGuiKey_MouseWheelX, io.MouseWheelH != 0.0f, io.MouseWheelH);
|
|
|
|
+ UpdateAliasKey(ImGuiKey_MouseWheelY, io.MouseWheel != 0.0f, io.MouseWheel);
|
|
|
|
+
|
|
|
|
+ // Synchronize io.KeyMods and io.KeyXXX values.
|
|
|
|
+ // - New backends (1.87+): send io.AddKeyEvent(ImGuiMod_XXX) -> -> (here) deriving io.KeyMods + io.KeyXXX from key array.
|
|
|
|
+ // - Legacy backends: set io.KeyXXX bools -> (above) set key array from io.KeyXXX -> (here) deriving io.KeyMods + io.KeyXXX from key array.
|
|
|
|
+ // So with legacy backends the 4 values will do a unnecessary back-and-forth but it makes the code simpler and future facing.
|
|
|
|
+ io.KeyMods = GetMergedModsFromKeys();
|
|
|
|
+ io.KeyCtrl = (io.KeyMods & ImGuiMod_Ctrl) != 0;
|
|
|
|
+ io.KeyShift = (io.KeyMods & ImGuiMod_Shift) != 0;
|
|
|
|
+ io.KeyAlt = (io.KeyMods & ImGuiMod_Alt) != 0;
|
|
|
|
+ io.KeySuper = (io.KeyMods & ImGuiMod_Super) != 0;
|
|
|
|
+
|
|
|
|
+ // Clear gamepad data if disabled
|
|
|
|
+ if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0)
|
|
|
|
+ for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++)
|
|
|
|
+ {
|
|
|
|
+ io.KeysData[i - ImGuiKey_KeysData_OFFSET].Down = false;
|
|
|
|
+ io.KeysData[i - ImGuiKey_KeysData_OFFSET].AnalogValue = 0.0f;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Update keys
|
|
|
|
+ for (int i = 0; i < ImGuiKey_KeysData_SIZE; i++)
|
|
|
|
+ {
|
|
|
|
+ ImGuiKeyData* key_data = &io.KeysData[i];
|
|
|
|
+ key_data->DownDurationPrev = key_data->DownDuration;
|
|
|
|
+ key_data->DownDuration = key_data->Down ? (key_data->DownDuration < 0.0f ? 0.0f : key_data->DownDuration + io.DeltaTime) : -1.0f;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Update keys/input owner (named keys only): one entry per key
|
|
|
|
+ for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1))
|
|
|
|
+ {
|
|
|
|
+ ImGuiKeyData* key_data = &io.KeysData[key - ImGuiKey_KeysData_OFFSET];
|
|
|
|
+ ImGuiKeyOwnerData* owner_data = &g.KeysOwnerData[key - ImGuiKey_NamedKey_BEGIN];
|
|
|
|
+ owner_data->OwnerCurr = owner_data->OwnerNext;
|
|
|
|
+ if (!key_data->Down) // Important: ownership is released on the frame after a release. Ensure a 'MouseDown -> CloseWindow -> MouseUp' chain doesn't lead to someone else seeing the MouseUp.
|
|
|
|
+ owner_data->OwnerNext = ImGuiKeyOwner_None;
|
|
|
|
+ owner_data->LockThisFrame = owner_data->LockUntilRelease = owner_data->LockUntilRelease && key_data->Down; // Clear LockUntilRelease when key is not Down anymore
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ UpdateKeyRoutingTable(&g.KeysRoutingTable);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void ImGui::UpdateMouseInputs()
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiIO& io = g.IO;
|
|
|
|
+
|
|
|
|
+ // Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well)
|
|
|
|
+ if (IsMousePosValid(&io.MousePos))
|
|
|
|
+ io.MousePos = g.MouseLastValidPos = ImFloorSigned(io.MousePos);
|
|
|
|
+
|
|
|
|
+ // If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta
|
|
|
|
+ if (IsMousePosValid(&io.MousePos) && IsMousePosValid(&io.MousePosPrev))
|
|
|
|
+ io.MouseDelta = io.MousePos - io.MousePosPrev;
|
|
|
|
+ else
|
|
|
|
+ io.MouseDelta = ImVec2(0.0f, 0.0f);
|
|
|
|
+
|
|
|
|
+ // If mouse moved we re-enable mouse hovering in case it was disabled by gamepad/keyboard. In theory should use a >0.0f threshold but would need to reset in everywhere we set this to true.
|
|
|
|
+ if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)
|
|
|
|
+ g.NavDisableMouseHover = false;
|
|
|
|
+
|
|
|
|
+ io.MousePosPrev = io.MousePos;
|
|
|
|
+ for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
|
|
|
+ {
|
|
|
|
+ io.MouseClicked[i] = io.MouseDown[i] && io.MouseDownDuration[i] < 0.0f;
|
|
|
|
+ io.MouseClickedCount[i] = 0; // Will be filled below
|
|
|
|
+ io.MouseReleased[i] = !io.MouseDown[i] && io.MouseDownDuration[i] >= 0.0f;
|
|
|
|
+ io.MouseDownDurationPrev[i] = io.MouseDownDuration[i];
|
|
|
|
+ io.MouseDownDuration[i] = io.MouseDown[i] ? (io.MouseDownDuration[i] < 0.0f ? 0.0f : io.MouseDownDuration[i] + io.DeltaTime) : -1.0f;
|
|
|
|
+ if (io.MouseClicked[i])
|
|
|
|
+ {
|
|
|
|
+ bool is_repeated_click = false;
|
|
|
|
+ if ((float)(g.Time - io.MouseClickedTime[i]) < io.MouseDoubleClickTime)
|
|
|
|
+ {
|
|
|
|
+ ImVec2 delta_from_click_pos = IsMousePosValid(&io.MousePos) ? (io.MousePos - io.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f);
|
|
|
|
+ if (ImLengthSqr(delta_from_click_pos) < io.MouseDoubleClickMaxDist * io.MouseDoubleClickMaxDist)
|
|
|
|
+ is_repeated_click = true;
|
|
|
|
+ }
|
|
|
|
+ if (is_repeated_click)
|
|
|
|
+ io.MouseClickedLastCount[i]++;
|
|
|
|
+ else
|
|
|
|
+ io.MouseClickedLastCount[i] = 1;
|
|
|
|
+ io.MouseClickedTime[i] = g.Time;
|
|
|
|
+ io.MouseClickedPos[i] = io.MousePos;
|
|
|
|
+ io.MouseClickedCount[i] = io.MouseClickedLastCount[i];
|
|
|
|
+ io.MouseDragMaxDistanceSqr[i] = 0.0f;
|
|
|
|
+ }
|
|
|
|
+ else if (io.MouseDown[i])
|
|
|
|
+ {
|
|
|
|
+ // Maintain the maximum distance we reaching from the initial click position, which is used with dragging threshold
|
|
|
|
+ float delta_sqr_click_pos = IsMousePosValid(&io.MousePos) ? ImLengthSqr(io.MousePos - io.MouseClickedPos[i]) : 0.0f;
|
|
|
|
+ io.MouseDragMaxDistanceSqr[i] = ImMax(io.MouseDragMaxDistanceSqr[i], delta_sqr_click_pos);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // We provide io.MouseDoubleClicked[] as a legacy service
|
|
|
|
+ io.MouseDoubleClicked[i] = (io.MouseClickedCount[i] == 2);
|
|
|
|
+
|
|
|
|
+ // Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation
|
|
|
|
+ if (io.MouseClicked[i])
|
|
|
|
+ g.NavDisableMouseHover = false;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static void LockWheelingWindow(ImGuiWindow* window, float wheel_amount)
|
|
static void LockWheelingWindow(ImGuiWindow* window, float wheel_amount)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|