|
@@ -1055,6 +1055,8 @@ CODE
|
|
static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in
|
|
static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in
|
|
static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f; // Time before the window list starts to appear
|
|
static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f; // Time before the window list starts to appear
|
|
|
|
|
|
|
|
+static const float NAV_ACTIVATE_HIGHLIGHT_TIMER = 0.10f; // Time to highlight an item activated by a shortcut.
|
|
|
|
+
|
|
// Window resizing from edges (when io.ConfigWindowsResizeFromEdges = true and ImGuiBackendFlags_HasMouseCursors is set in io.BackendFlags by backend)
|
|
// Window resizing from edges (when io.ConfigWindowsResizeFromEdges = true and ImGuiBackendFlags_HasMouseCursors is set in io.BackendFlags by backend)
|
|
static const float WINDOWS_HOVER_PADDING = 4.0f; // Extend outside window for hovering/resizing (maxxed with TouchPadding) and inside windows for borders. Affect FindHoveredWindow().
|
|
static const float WINDOWS_HOVER_PADDING = 4.0f; // Extend outside window for hovering/resizing (maxxed with TouchPadding) and inside windows for borders. Affect FindHoveredWindow().
|
|
static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduce visual noise by only highlighting the border after a certain time.
|
|
static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduce visual noise by only highlighting the border after a certain time.
|
|
@@ -3980,6 +3982,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
|
|
g.ActiveIdNoClearOnFocusLoss = false;
|
|
g.ActiveIdNoClearOnFocusLoss = false;
|
|
g.ActiveIdWindow = window;
|
|
g.ActiveIdWindow = window;
|
|
g.ActiveIdHasBeenEditedThisFrame = false;
|
|
g.ActiveIdHasBeenEditedThisFrame = false;
|
|
|
|
+ g.ActiveIdFromShortcut = false;
|
|
if (id)
|
|
if (id)
|
|
{
|
|
{
|
|
g.ActiveIdIsAlive = id;
|
|
g.ActiveIdIsAlive = id;
|
|
@@ -4197,7 +4200,8 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag
|
|
if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap)
|
|
if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap)
|
|
return false;
|
|
return false;
|
|
if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap)
|
|
if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap)
|
|
- return false;
|
|
|
|
|
|
+ if (!g.ActiveIdFromShortcut)
|
|
|
|
+ return false;
|
|
|
|
|
|
// Done with rectangle culling so we can perform heavier checks now.
|
|
// Done with rectangle culling so we can perform heavier checks now.
|
|
if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
|
|
if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
|
|
@@ -4257,12 +4261,13 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag
|
|
}
|
|
}
|
|
|
|
|
|
// FIXME: This is inlined/duplicated in ItemAdd()
|
|
// FIXME: This is inlined/duplicated in ItemAdd()
|
|
|
|
+// FIXME: The id != 0 path is not used by our codebase, may get rid of it?
|
|
bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id)
|
|
bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
if (!bb.Overlaps(window->ClipRect))
|
|
if (!bb.Overlaps(window->ClipRect))
|
|
- if (id == 0 || (id != g.ActiveId && id != g.NavId))
|
|
|
|
|
|
+ if (id == 0 || (id != g.ActiveId && id != g.ActiveIdPreviousFrame && id != g.NavId && id != g.NavActivateId))
|
|
if (!g.LogEnabled)
|
|
if (!g.LogEnabled)
|
|
return true;
|
|
return true;
|
|
return false;
|
|
return false;
|
|
@@ -9020,8 +9025,6 @@ static bool IsKeyChordPotentiallyCharInput(ImGuiKeyChord key_chord)
|
|
// - Routes and key ownership are attributed at the beginning of next frame based on best score and mod state.
|
|
// - Routes and key ownership are attributed at the beginning of next frame based on best score and mod state.
|
|
// (Conceptually this does a "Submit for next frame" + "Test for current frame".
|
|
// (Conceptually this does a "Submit for next frame" + "Test for current frame".
|
|
// As such, it could be called TrySetXXX or SubmitXXX, or the Submit and Test operations should be separate.)
|
|
// As such, it could be called TrySetXXX or SubmitXXX, or the Submit and Test operations should be separate.)
|
|
-// - Using 'owner_id == ImGuiKeyOwner_Any/0': auto-assign an owner based on current focus scope (each window has its focus scope by default)
|
|
|
|
-// - Using 'owner_id == ImGuiKeyOwner_None': allows disabling/locking a shortcut.
|
|
|
|
bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
|
|
bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -9029,6 +9032,8 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI
|
|
flags |= ImGuiInputFlags_RouteGlobalHigh; // IMPORTANT: This is the default for SetShortcutRouting() but NOT Shortcut()
|
|
flags |= ImGuiInputFlags_RouteGlobalHigh; // IMPORTANT: This is the default for SetShortcutRouting() but NOT Shortcut()
|
|
else
|
|
else
|
|
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteMask_)); // Check that only 1 routing flag is used
|
|
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteMask_)); // Check that only 1 routing flag is used
|
|
|
|
+ IM_ASSERT(owner_id != ImGuiKeyOwner_Any && owner_id != ImGuiKeyOwner_None);
|
|
|
|
+
|
|
if (key_chord & ImGuiMod_Shortcut)
|
|
if (key_chord & ImGuiMod_Shortcut)
|
|
key_chord = ConvertShortcutMod(key_chord);
|
|
key_chord = ConvertShortcutMod(key_chord);
|
|
|
|
|
|
@@ -9059,6 +9064,7 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // FIXME-SHORTCUT: A way to configure the location/focus-scope to test would render this more flexible.
|
|
const int score = CalcRoutingScore(g.CurrentFocusScopeId, owner_id, flags);
|
|
const int score = CalcRoutingScore(g.CurrentFocusScopeId, owner_id, flags);
|
|
IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, owner_id=0x%08X, flags=%04X) -> score %d\n", GetKeyChordName(key_chord), owner_id, flags, score);
|
|
IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, owner_id=0x%08X, flags=%04X) -> score %d\n", GetKeyChordName(key_chord), owner_id, flags, score);
|
|
if (score == 255)
|
|
if (score == 255)
|
|
@@ -9067,18 +9073,17 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI
|
|
// 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 ImGuiID routing_id = GetRoutingIdFromOwnerId(owner_id);
|
|
|
|
//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 = routing_id;
|
|
|
|
|
|
+ routing_data->RoutingNext = owner_id;
|
|
routing_data->RoutingNextScore = (ImU8)score;
|
|
routing_data->RoutingNextScore = (ImU8)score;
|
|
}
|
|
}
|
|
|
|
|
|
// Return routing state for CURRENT frame
|
|
// Return routing state for CURRENT frame
|
|
- if (routing_data->RoutingCurr == routing_id)
|
|
|
|
|
|
+ if (routing_data->RoutingCurr == owner_id)
|
|
IMGUI_DEBUG_LOG_INPUTROUTING("--> granting current route\n");
|
|
IMGUI_DEBUG_LOG_INPUTROUTING("--> granting current route\n");
|
|
- return routing_data->RoutingCurr == routing_id;
|
|
|
|
|
|
+ return routing_data->RoutingCurr == owner_id;
|
|
}
|
|
}
|
|
|
|
|
|
// Currently unused by core (but used by tests)
|
|
// Currently unused by core (but used by tests)
|
|
@@ -10043,6 +10048,13 @@ bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiIn
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void ImGui::SetNextItemShortcut(ImGuiKeyChord key_chord)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasShortcut;
|
|
|
|
+ g.NextItemData.Shortcut = key_chord;
|
|
|
|
+}
|
|
|
|
+
|
|
bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
|
|
bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
|
|
{
|
|
{
|
|
//ImGuiContext& g = *GImGui;
|
|
//ImGuiContext& g = *GImGui;
|
|
@@ -10051,6 +10063,13 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags
|
|
// When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any.
|
|
// When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any.
|
|
if ((flags & ImGuiInputFlags_RouteMask_) == 0)
|
|
if ((flags & ImGuiInputFlags_RouteMask_) == 0)
|
|
flags |= ImGuiInputFlags_RouteFocused;
|
|
flags |= ImGuiInputFlags_RouteFocused;
|
|
|
|
+
|
|
|
|
+ // Using 'owner_id == ImGuiKeyOwner_Any/0': auto-assign an owner based on current focus scope (each window has its focus scope by default)
|
|
|
|
+ // Effectively makes Shortcut() always input-owner aware.
|
|
|
|
+ if (owner_id == ImGuiKeyOwner_Any || owner_id == ImGuiKeyOwner_None)
|
|
|
|
+ owner_id = GetRoutingIdFromOwnerId(owner_id);
|
|
|
|
+
|
|
|
|
+ // Submit route
|
|
if (!SetShortcutRouting(key_chord, owner_id, flags))
|
|
if (!SetShortcutRouting(key_chord, owner_id, flags))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
@@ -10385,6 +10404,7 @@ void ImGuiStackSizes::CompareWithContextState(ImGuiContext* ctx)
|
|
// [SECTION] ITEM SUBMISSION
|
|
// [SECTION] ITEM SUBMISSION
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
// - KeepAliveID()
|
|
// - KeepAliveID()
|
|
|
|
+// - ItemHandleShortcut() [Internal]
|
|
// - ItemAdd()
|
|
// - ItemAdd()
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
@@ -10398,6 +10418,20 @@ void ImGui::KeepAliveID(ImGuiID id)
|
|
g.ActiveIdPreviousFrameIsAlive = true;
|
|
g.ActiveIdPreviousFrameIsAlive = true;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void ItemHandleShortcut(ImGuiID id)
|
|
|
|
+{
|
|
|
|
+ // FIXME: Generalize Activation queue?
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ if (ImGui::Shortcut(g.NextItemData.Shortcut, id, ImGuiInputFlags_None) && g.NavActivateId == 0)
|
|
|
|
+ {
|
|
|
|
+ g.NavActivateId = id; // Will effectively disable clipping.
|
|
|
|
+ g.NavActivateFlags = ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_FromShortcut;
|
|
|
|
+ if (g.ActiveId == 0 || g.ActiveId == id)
|
|
|
|
+ g.NavActivateDownId = g.NavActivatePressedId = id;
|
|
|
|
+ ImGui::NavHighlightActivated(id);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
// Declare item bounding box for clipping and interaction.
|
|
// Declare item bounding box for clipping and interaction.
|
|
// Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface
|
|
// Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface
|
|
// declare their minimum size requirement to ItemSize() and provide a larger region to ItemAdd() which is used drawing/interaction.
|
|
// declare their minimum size requirement to ItemSize() and provide a larger region to ItemAdd() which is used drawing/interaction.
|
|
@@ -10439,6 +10473,9 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
|
if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened))
|
|
if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened))
|
|
NavProcessItem();
|
|
NavProcessItem();
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasShortcut)
|
|
|
|
+ ItemHandleShortcut(id);
|
|
}
|
|
}
|
|
|
|
|
|
// Lightweight clear of SetNextItemXXX data.
|
|
// Lightweight clear of SetNextItemXXX data.
|
|
@@ -10455,9 +10492,10 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
|
//const bool is_clipped = IsClippedEx(bb, id);
|
|
//const bool is_clipped = IsClippedEx(bb, id);
|
|
//if (is_clipped)
|
|
//if (is_clipped)
|
|
// return false;
|
|
// return false;
|
|
|
|
+ // g.NavActivateId is not necessarily == g.NavId, in the case of remote activation (e.g. shortcuts)
|
|
const bool is_rect_visible = bb.Overlaps(window->ClipRect);
|
|
const bool is_rect_visible = bb.Overlaps(window->ClipRect);
|
|
if (!is_rect_visible)
|
|
if (!is_rect_visible)
|
|
- if (id == 0 || (id != g.ActiveId && id != g.ActiveIdPreviousFrame && id != g.NavId))
|
|
|
|
|
|
+ if (id == 0 || (id != g.ActiveId && id != g.ActiveIdPreviousFrame && id != g.NavId && id != g.NavActivateId))
|
|
if (!g.LogEnabled)
|
|
if (!g.LogEnabled)
|
|
return false;
|
|
return false;
|
|
|
|
|
|
@@ -11836,6 +11874,13 @@ void ImGui::SetNavWindow(ImGuiWindow* window)
|
|
NavUpdateAnyRequestFlag();
|
|
NavUpdateAnyRequestFlag();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void ImGui::NavHighlightActivated(ImGuiID id)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ g.NavHighlightActivatedId = id;
|
|
|
|
+ g.NavHighlightActivatedTimer = NAV_ACTIVATE_HIGHLIGHT_TIMER;
|
|
|
|
+}
|
|
|
|
+
|
|
void ImGui::NavClearPreferredPosForAxis(ImGuiAxis axis)
|
|
void ImGui::NavClearPreferredPosForAxis(ImGuiAxis axis)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
@@ -12503,10 +12548,10 @@ static void ImGui::NavUpdate()
|
|
g.NavActivateFlags = ImGuiActivateFlags_None;
|
|
g.NavActivateFlags = ImGuiActivateFlags_None;
|
|
if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
|
|
if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
|
|
{
|
|
{
|
|
- const bool activate_down = (nav_keyboard_active && IsKeyDown(ImGuiKey_Space)) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadActivate));
|
|
|
|
- const bool activate_pressed = activate_down && ((nav_keyboard_active && IsKeyPressed(ImGuiKey_Space, false)) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadActivate, false)));
|
|
|
|
- const bool input_down = (nav_keyboard_active && (IsKeyDown(ImGuiKey_Enter) || IsKeyDown(ImGuiKey_KeypadEnter))) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadInput));
|
|
|
|
- const bool input_pressed = input_down && ((nav_keyboard_active && (IsKeyPressed(ImGuiKey_Enter, false) || IsKeyPressed(ImGuiKey_KeypadEnter, false))) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadInput, false)));
|
|
|
|
|
|
+ const bool activate_down = (nav_keyboard_active && IsKeyDown(ImGuiKey_Space, ImGuiKeyOwner_None)) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadActivate, ImGuiKeyOwner_None));
|
|
|
|
+ const bool activate_pressed = activate_down && ((nav_keyboard_active && IsKeyPressed(ImGuiKey_Space, ImGuiKeyOwner_None)) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadActivate, ImGuiKeyOwner_None)));
|
|
|
|
+ const bool input_down = (nav_keyboard_active && (IsKeyDown(ImGuiKey_Enter, ImGuiKeyOwner_None) || IsKeyDown(ImGuiKey_KeypadEnter, ImGuiKeyOwner_None))) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadInput, ImGuiKeyOwner_None));
|
|
|
|
+ const bool input_pressed = input_down && ((nav_keyboard_active && (IsKeyPressed(ImGuiKey_Enter, ImGuiKeyOwner_None) || IsKeyPressed(ImGuiKey_KeypadEnter, ImGuiKeyOwner_None))) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadInput, ImGuiKeyOwner_None)));
|
|
if (g.ActiveId == 0 && activate_pressed)
|
|
if (g.ActiveId == 0 && activate_pressed)
|
|
{
|
|
{
|
|
g.NavActivateId = g.NavId;
|
|
g.NavActivateId = g.NavId;
|
|
@@ -12520,13 +12565,22 @@ static void ImGui::NavUpdate()
|
|
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && (activate_down || input_down))
|
|
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && (activate_down || input_down))
|
|
g.NavActivateDownId = g.NavId;
|
|
g.NavActivateDownId = g.NavId;
|
|
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && (activate_pressed || input_pressed))
|
|
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && (activate_pressed || input_pressed))
|
|
|
|
+ {
|
|
g.NavActivatePressedId = g.NavId;
|
|
g.NavActivatePressedId = g.NavId;
|
|
|
|
+ NavHighlightActivated(g.NavId);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
|
|
if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
|
|
g.NavDisableHighlight = true;
|
|
g.NavDisableHighlight = true;
|
|
if (g.NavActivateId != 0)
|
|
if (g.NavActivateId != 0)
|
|
IM_ASSERT(g.NavActivateDownId == g.NavActivateId);
|
|
IM_ASSERT(g.NavActivateDownId == g.NavActivateId);
|
|
|
|
|
|
|
|
+ // Highlight
|
|
|
|
+ if (g.NavHighlightActivatedTimer > 0.0f)
|
|
|
|
+ g.NavHighlightActivatedTimer = ImMax(0.0f, g.NavHighlightActivatedTimer - io.DeltaTime);
|
|
|
|
+ if (g.NavHighlightActivatedTimer == 0.0f)
|
|
|
|
+ g.NavHighlightActivatedId = 0;
|
|
|
|
+
|
|
// Process programmatic activation request
|
|
// Process programmatic activation request
|
|
// FIXME-NAV: Those should eventually be queued (unlike focus they don't cancel each others)
|
|
// FIXME-NAV: Those should eventually be queued (unlike focus they don't cancel each others)
|
|
if (g.NavNextActivateId != 0)
|
|
if (g.NavNextActivateId != 0)
|
|
@@ -12918,15 +12972,14 @@ static void ImGui::NavUpdateCancelRequest()
|
|
NavRestoreLayer(ImGuiNavLayer_Main);
|
|
NavRestoreLayer(ImGuiNavLayer_Main);
|
|
NavRestoreHighlightAfterMove();
|
|
NavRestoreHighlightAfterMove();
|
|
}
|
|
}
|
|
- else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow)
|
|
|
|
|
|
+ else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->RootWindowForNav->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->RootWindowForNav->ParentWindow)
|
|
{
|
|
{
|
|
// Exit child window
|
|
// Exit child window
|
|
- ImGuiWindow* child_window = g.NavWindow;
|
|
|
|
- ImGuiWindow* parent_window = g.NavWindow->ParentWindow;
|
|
|
|
|
|
+ ImGuiWindow* child_window = g.NavWindow->RootWindowForNav;
|
|
|
|
+ ImGuiWindow* parent_window = child_window->ParentWindow;
|
|
IM_ASSERT(child_window->ChildId != 0);
|
|
IM_ASSERT(child_window->ChildId != 0);
|
|
- ImRect child_rect = child_window->Rect();
|
|
|
|
FocusWindow(parent_window);
|
|
FocusWindow(parent_window);
|
|
- SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, WindowRectAbsToRel(parent_window, child_rect));
|
|
|
|
|
|
+ SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, WindowRectAbsToRel(parent_window, child_window->Rect()));
|
|
NavRestoreHighlightAfterMove();
|
|
NavRestoreHighlightAfterMove();
|
|
}
|
|
}
|
|
else if (g.OpenPopupStack.Size > 0 && g.OpenPopupStack.back().Window != NULL && !(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal))
|
|
else if (g.OpenPopupStack.Size > 0 && g.OpenPopupStack.back().Window != NULL && !(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal))
|
|
@@ -21107,6 +21160,7 @@ void ImGui::DebugLocateItem(ImGuiID target_id)
|
|
g.DebugBreakInLocateId = false;
|
|
g.DebugBreakInLocateId = false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// FIXME: Doesn't work over through a modal window, because they clear HoveredWindow.
|
|
void ImGui::DebugLocateItemOnHover(ImGuiID target_id)
|
|
void ImGui::DebugLocateItemOnHover(ImGuiID target_id)
|
|
{
|
|
{
|
|
if (target_id == 0 || !IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
|
if (target_id == 0 || !IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|