mirror of
https://github.com/ocornut/imgui.git
synced 2025-10-16 15:06:04 +00:00
Shortcuts: reorganize route scoring so values are easier to read. (#9004)
Score now require 16-bits but ImGuiKeyRoutingData doesn't grow size.
This commit is contained in:
49
imgui.cpp
49
imgui.cpp
@@ -9378,7 +9378,7 @@ static void ImGui::UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt)
|
|||||||
routing_entry->RoutingCurrScore = routing_entry->RoutingNextScore;
|
routing_entry->RoutingCurrScore = routing_entry->RoutingNextScore;
|
||||||
routing_entry->RoutingCurr = routing_entry->RoutingNext; // Update entry
|
routing_entry->RoutingCurr = routing_entry->RoutingNext; // Update entry
|
||||||
routing_entry->RoutingNext = ImGuiKeyOwner_NoOwner;
|
routing_entry->RoutingNext = ImGuiKeyOwner_NoOwner;
|
||||||
routing_entry->RoutingNextScore = 255;
|
routing_entry->RoutingNextScore = 0;
|
||||||
if (routing_entry->RoutingCurr == ImGuiKeyOwner_NoOwner)
|
if (routing_entry->RoutingCurr == ImGuiKeyOwner_NoOwner)
|
||||||
continue;
|
continue;
|
||||||
rt->EntriesNext.push_back(*routing_entry); // Write alive ones into new buffer
|
rt->EntriesNext.push_back(*routing_entry); // Write alive ones into new buffer
|
||||||
@@ -9447,23 +9447,24 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord)
|
|||||||
return routing_data;
|
return routing_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Current score encoding (lower is highest priority):
|
// Current score encoding
|
||||||
// - 0: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverActive
|
// - 0: Never route
|
||||||
// - 1: ImGuiInputFlags_ActiveItem or ImGuiInputFlags_RouteFocused (if item active)
|
// - 1: ImGuiInputFlags_RouteGlobal (lower priority)
|
||||||
// - 2: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused
|
// - 100..199: ImGuiInputFlags_RouteFocused (if window in focus-stack)
|
||||||
// - 3+: ImGuiInputFlags_RouteFocused (if window in focus-stack)
|
// 200: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused
|
||||||
// - 254: ImGuiInputFlags_RouteGlobal
|
// 300: ImGuiInputFlags_RouteActive or ImGuiInputFlags_RouteFocused (if item active)
|
||||||
// - 255: never route
|
// 400: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverActive
|
||||||
|
// - 500..599: ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteOverActive (if window in focus-stack) (higher priority)
|
||||||
// 'flags' should include an explicit routing policy
|
// 'flags' should include an explicit routing policy
|
||||||
static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInputFlags flags)
|
static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInputFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (flags & ImGuiInputFlags_RouteFocused)
|
if (flags & ImGuiInputFlags_RouteFocused)
|
||||||
{
|
{
|
||||||
// ActiveID gets top priority
|
// ActiveID gets high priority
|
||||||
// (we don't check g.ActiveIdUsingAllKeys here. Routing is applied but if input ownership is tested later it may discard it)
|
// (we don't check g.ActiveIdUsingAllKeys here. Routing is applied but if input ownership is tested later it may discard it)
|
||||||
if (owner_id != 0 && g.ActiveId == owner_id)
|
if (owner_id != 0 && g.ActiveId == owner_id)
|
||||||
return 1;
|
return 300;
|
||||||
|
|
||||||
// Score based on distance to focused window (lower is better)
|
// Score based on distance to focused window (lower is better)
|
||||||
// Assuming both windows are submitting a routing request,
|
// Assuming both windows are submitting a routing request,
|
||||||
@@ -9473,25 +9474,27 @@ static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInput
|
|||||||
// - When Window/ChildB is focused -> Window scores 4 (best), Window/ChildB doesn't have a score.
|
// - When Window/ChildB is focused -> Window scores 4 (best), Window/ChildB doesn't have a score.
|
||||||
// This essentially follow the window->ParentWindowForFocusRoute chain.
|
// This essentially follow the window->ParentWindowForFocusRoute chain.
|
||||||
if (focus_scope_id == 0)
|
if (focus_scope_id == 0)
|
||||||
return 255;
|
return 0;
|
||||||
for (int index_in_focus_path = 0; index_in_focus_path < g.NavFocusRoute.Size; index_in_focus_path++)
|
for (int index_in_focus_path = 0; index_in_focus_path < g.NavFocusRoute.Size; index_in_focus_path++)
|
||||||
if (g.NavFocusRoute.Data[index_in_focus_path].ID == focus_scope_id)
|
if (g.NavFocusRoute.Data[index_in_focus_path].ID == focus_scope_id)
|
||||||
return 3 + index_in_focus_path;
|
return 199 - index_in_focus_path;
|
||||||
return 255;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (flags & ImGuiInputFlags_RouteActive)
|
else if (flags & ImGuiInputFlags_RouteActive)
|
||||||
{
|
{
|
||||||
if (owner_id != 0 && g.ActiveId == owner_id)
|
if (owner_id != 0 && g.ActiveId == owner_id)
|
||||||
return 1;
|
return 300;
|
||||||
return 255;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (flags & ImGuiInputFlags_RouteGlobal)
|
else if (flags & ImGuiInputFlags_RouteGlobal)
|
||||||
{
|
{
|
||||||
if (flags & ImGuiInputFlags_RouteOverActive)
|
if (flags & ImGuiInputFlags_RouteOverActive)
|
||||||
return 0;
|
return 400;
|
||||||
|
if (owner_id != 0 && g.ActiveId == owner_id)
|
||||||
|
return 300;
|
||||||
if (flags & ImGuiInputFlags_RouteOverFocused)
|
if (flags & ImGuiInputFlags_RouteOverFocused)
|
||||||
return 2;
|
return 200;
|
||||||
return 254;
|
return 1;
|
||||||
}
|
}
|
||||||
IM_ASSERT(0);
|
IM_ASSERT(0);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -9587,17 +9590,17 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, I
|
|||||||
|
|
||||||
const int score = CalcRoutingScore(focus_scope_id, owner_id, flags);
|
const int score = CalcRoutingScore(focus_scope_id, owner_id, flags);
|
||||||
IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, flags=%04X, owner_id=0x%08X) -> score %d\n", GetKeyChordName(key_chord), flags, owner_id, score);
|
IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, flags=%04X, owner_id=0x%08X) -> score %d\n", GetKeyChordName(key_chord), flags, owner_id, score);
|
||||||
if (score == 255)
|
if (score == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Submit routing for NEXT frame (assuming score is sufficient)
|
// Submit routing for NEXT frame (assuming score is sufficient)
|
||||||
// FIXME: Could expose a way to use a "serve last" policy for same score resolution (using <= instead of <).
|
// FIXME: Could expose a way to use a "serve last" policy for same score resolution (using >= instead of >).
|
||||||
ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord);
|
ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord);
|
||||||
//const bool set_route = (flags & ImGuiInputFlags_ServeLast) ? (score <= routing_data->RoutingNextScore) : (score < routing_data->RoutingNextScore);
|
//const bool set_route = (flags & ImGuiInputFlags_ServeLast) ? (score >= routing_data->RoutingNextScore) : (score > routing_data->RoutingNextScore);
|
||||||
if (score < routing_data->RoutingNextScore)
|
if (score > routing_data->RoutingNextScore)
|
||||||
{
|
{
|
||||||
routing_data->RoutingNext = owner_id;
|
routing_data->RoutingNext = owner_id;
|
||||||
routing_data->RoutingNextScore = (ImU8)score;
|
routing_data->RoutingNextScore = (ImU16)score;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return routing state for CURRENT frame
|
// Return routing state for CURRENT frame
|
||||||
|
@@ -1556,12 +1556,12 @@ struct ImGuiKeyRoutingData
|
|||||||
{
|
{
|
||||||
ImGuiKeyRoutingIndex NextEntryIndex;
|
ImGuiKeyRoutingIndex NextEntryIndex;
|
||||||
ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits.
|
ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits.
|
||||||
ImU8 RoutingCurrScore; // [DEBUG] For debug display
|
ImU16 RoutingCurrScore; // [DEBUG] For debug display
|
||||||
ImU8 RoutingNextScore; // Lower is better (0: perfect score)
|
ImU16 RoutingNextScore; // Lower is better (0: perfect score)
|
||||||
ImGuiID RoutingCurr;
|
ImGuiID RoutingCurr;
|
||||||
ImGuiID RoutingNext;
|
ImGuiID RoutingNext;
|
||||||
|
|
||||||
ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_NoOwner; }
|
ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 0; RoutingCurr = RoutingNext = ImGuiKeyOwner_NoOwner; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching.
|
// Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching.
|
||||||
|
Reference in New Issue
Block a user