From f9ab2a0e9fd17a25a7de152c298fd702c3299976 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 6 Dec 2022 12:09:14 +0100 Subject: [PATCH] Refactor: moved UpdateKeyRoutingTable() to INPUTS section. renamed GetKeyVector2d() -> GetKeyMagnitude2d() --- imgui.cpp | 100 ++++++++++++++++++++++++----------------------- imgui_internal.h | 2 +- 2 files changed, 53 insertions(+), 49 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 890dfd865..4f710584c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1017,11 +1017,14 @@ static void ErrorCheckEndFrameSanityChecks(); static void UpdateDebugToolItemPicker(); static void UpdateDebugToolStackQueries(); -// Misc -static void UpdateSettings(); +// Inputs static void UpdateKeyboardInputs(); static void UpdateMouseInputs(); static void UpdateMouseWheel(); +static void UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt); + +// Misc +static void UpdateSettings(); static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect); static void RenderWindowOuterBorders(ImGuiWindow* window); static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size); @@ -4253,45 +4256,6 @@ static void UpdateAliasKey(ImGuiKey key, bool v, float analog_value) key_data->AnalogValue = analog_value; } -// Rewrite routing data buffers to strip old entries + sort by key to make queries not touch scattered data. -// Entries D,A,B,B,A,C,B --> A,A,B,B,B,C,D -// Index A:1 B:2 C:5 D:0 --> A:0 B:2 C:5 D:6 -// See 'Metrics->Key Owners & Shortcut Routing' to visualize the result of that operation. -static void UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt) -{ - ImGuiContext& g = *GImGui; - rt->EntriesNext.resize(0); - for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) - { - const int new_routing_start_idx = rt->EntriesNext.Size; - ImGuiKeyRoutingData* routing_entry; - for (int old_routing_idx = rt->Index[key - ImGuiKey_NamedKey_BEGIN]; old_routing_idx != -1; old_routing_idx = routing_entry->NextEntryIndex) - { - routing_entry = &rt->Entries[old_routing_idx]; - routing_entry->RoutingCurr = routing_entry->RoutingNext; // Update entry - routing_entry->RoutingNext = ImGuiKeyOwner_None; - routing_entry->RoutingNextScore = 255; - if (routing_entry->RoutingCurr == ImGuiKeyOwner_None) - continue; - rt->EntriesNext.push_back(*routing_entry); // Write alive ones into new buffer - - // Apply routing to owner if there's no owner already (RoutingCurr == None at this point) - if (routing_entry->Mods == g.IO.KeyMods) - { - ImGuiKeyOwnerData* owner_data = ImGui::GetKeyOwnerData(key); - if (owner_data->OwnerCurr == ImGuiKeyOwner_None) - owner_data->OwnerCurr = routing_entry->RoutingCurr; - } - } - - // Rewrite linked-list - rt->Index[key - ImGuiKey_NamedKey_BEGIN] = (ImGuiKeyRoutingIndex)(new_routing_start_idx < rt->EntriesNext.Size ? new_routing_start_idx : -1); - for (int n = new_routing_start_idx; n < rt->EntriesNext.Size; n++) - rt->EntriesNext[n].NextEntryIndex = (ImGuiKeyRoutingIndex)((n + 1 < rt->EntriesNext.Size) ? n + 1 : -1); - } - rt->Entries.swap(rt->EntriesNext); // Swap new and old indexes -} - // [Internal] Do not use directly static ImGuiKeyChord GetMergedModsFromKeys() { @@ -6069,9 +6033,9 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s { ImVec2 nav_resize_dir; if (g.NavInputSource == ImGuiInputSource_Keyboard && g.IO.KeyShift) - nav_resize_dir = GetKeyVector2d(ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow); + nav_resize_dir = GetKeyMagnitude2d(ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow); if (g.NavInputSource == ImGuiInputSource_Gamepad) - nav_resize_dir = GetKeyVector2d(ImGuiKey_GamepadDpadLeft, ImGuiKey_GamepadDpadRight, ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadDpadDown); + nav_resize_dir = GetKeyMagnitude2d(ImGuiKey_GamepadDpadLeft, ImGuiKey_GamepadDpadRight, ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadDpadDown); if (nav_resize_dir.x != 0.0f || nav_resize_dir.y != 0.0f) { const float NAV_RESIZE_SPEED = 600.0f; @@ -7928,8 +7892,9 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) // - CalcTypematicRepeatAmount() [Internal] // - GetTypematicRepeatRate() [Internal] // - GetKeyPressedAmount() [Internal] -// - GetKeyVector2d() [Internal] +// - GetKeyMagnitude2d() [Internal] //----------------------------------------------------------------------------- +// - UpdateKeyRoutingTable() [Internal] // - GetRoutingIdFromOwnerId() [Internal] // - GetShortcutRoutingData() [Internal] // - CalcRoutingScore() [Internal] @@ -8108,13 +8073,52 @@ int ImGui::GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float repeat_ra } // Return 2D vector representing the combination of four cardinal direction, with analog value support (for e.g. ImGuiKey_GamepadLStick* values). -ImVec2 ImGui::GetKeyVector2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down) +ImVec2 ImGui::GetKeyMagnitude2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down) { return ImVec2( GetKeyData(key_right)->AnalogValue - GetKeyData(key_left)->AnalogValue, GetKeyData(key_down)->AnalogValue - GetKeyData(key_up)->AnalogValue); } +// Rewrite routing data buffers to strip old entries + sort by key to make queries not touch scattered data. +// Entries D,A,B,B,A,C,B --> A,A,B,B,B,C,D +// Index A:1 B:2 C:5 D:0 --> A:0 B:2 C:5 D:6 +// See 'Metrics->Key Owners & Shortcut Routing' to visualize the result of that operation. +static void ImGui::UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt) +{ + ImGuiContext& g = *GImGui; + rt->EntriesNext.resize(0); + for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) + { + const int new_routing_start_idx = rt->EntriesNext.Size; + ImGuiKeyRoutingData* routing_entry; + for (int old_routing_idx = rt->Index[key - ImGuiKey_NamedKey_BEGIN]; old_routing_idx != -1; old_routing_idx = routing_entry->NextEntryIndex) + { + routing_entry = &rt->Entries[old_routing_idx]; + routing_entry->RoutingCurr = routing_entry->RoutingNext; // Update entry + routing_entry->RoutingNext = ImGuiKeyOwner_None; + routing_entry->RoutingNextScore = 255; + if (routing_entry->RoutingCurr == ImGuiKeyOwner_None) + continue; + rt->EntriesNext.push_back(*routing_entry); // Write alive ones into new buffer + + // Apply routing to owner if there's no owner already (RoutingCurr == None at this point) + if (routing_entry->Mods == g.IO.KeyMods) + { + ImGuiKeyOwnerData* owner_data = ImGui::GetKeyOwnerData(key); + if (owner_data->OwnerCurr == ImGuiKeyOwner_None) + owner_data->OwnerCurr = routing_entry->RoutingCurr; + } + } + + // Rewrite linked-list + rt->Index[key - ImGuiKey_NamedKey_BEGIN] = (ImGuiKeyRoutingIndex)(new_routing_start_idx < rt->EntriesNext.Size ? new_routing_start_idx : -1); + for (int n = new_routing_start_idx; n < rt->EntriesNext.Size; n++) + rt->EntriesNext[n].NextEntryIndex = (ImGuiKeyRoutingIndex)((n + 1 < rt->EntriesNext.Size) ? n + 1 : -1); + } + rt->Entries.swap(rt->EntriesNext); // Swap new and old indexes +} + // owner_id may be None/Any, but routing_id needs to be always be set, so we default to GetCurrentFocusScope(). static inline ImGuiID GetRoutingIdFromOwnerId(ImGuiID owner_id) { @@ -11086,7 +11090,7 @@ static void ImGui::NavUpdate() // Next movement request will clamp the NavId reference rectangle to the visible area, so navigation will resume within those bounds. if (nav_gamepad_active) { - const ImVec2 scroll_dir = GetKeyVector2d(ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown); + const ImVec2 scroll_dir = GetKeyMagnitude2d(ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown); const float tweak_factor = IsKeyDown(ImGuiKey_NavGamepadTweakSlow) ? 1.0f / 10.0f : IsKeyDown(ImGuiKey_NavGamepadTweakFast) ? 10.0f : 1.0f; if (scroll_dir.x != 0.0f && window->ScrollbarX) SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed * tweak_factor)); @@ -11712,9 +11716,9 @@ static void ImGui::NavUpdateWindowing() { ImVec2 nav_move_dir; if (g.NavInputSource == ImGuiInputSource_Keyboard && !io.KeyShift) - nav_move_dir = GetKeyVector2d(ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow); + nav_move_dir = GetKeyMagnitude2d(ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow); if (g.NavInputSource == ImGuiInputSource_Gamepad) - nav_move_dir = GetKeyVector2d(ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown); + nav_move_dir = GetKeyMagnitude2d(ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown); if (nav_move_dir.x != 0.0f || nav_move_dir.y != 0.0f) { const float NAV_MOVE_SPEED = 800.0f; diff --git a/imgui_internal.h b/imgui_internal.h index dbd763779..75c290520 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2893,7 +2893,7 @@ namespace ImGui IMGUI_API void GetKeyChordName(ImGuiKeyChord key_chord, char* out_buf, int out_buf_size); inline ImGuiKey MouseButtonToKey(ImGuiMouseButton button) { IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT); return (ImGuiKey)(ImGuiKey_MouseLeft + button); } IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f); - IMGUI_API ImVec2 GetKeyVector2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down); + IMGUI_API ImVec2 GetKeyMagnitude2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down); IMGUI_API float GetNavTweakPressedAmount(ImGuiAxis axis); IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); IMGUI_API void GetTypematicRepeatRate(ImGuiInputFlags flags, float* repeat_delay, float* repeat_rate);