mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-12 16:01:11 +01:00
Nav: Extract part of NavUpdate() into a saner NavUpdateWindowingTarget() (#787)
This commit is contained in:
parent
b05b31e690
commit
17519c313a
156
imgui.cpp
156
imgui.cpp
@ -2606,6 +2606,85 @@ static ImVec2 GetNavInputAmount2d(int stick_no, ImGuiNavReadMode mode, float slo
|
|||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Window management mode (change focus, move/resize window, jump back and forth to menu layer)
|
||||||
|
static void NavUpdateWindowingTarget()
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (!g.NavWindowingTarget && IsNavInputPressed(ImGuiNavInput_PadMenu, ImGuiNavReadMode_Pressed))
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = g.NavWindow;
|
||||||
|
if (!window)
|
||||||
|
window = FindWindowNavigable(g.Windows.Size - 1, -1, -1);
|
||||||
|
if (window)
|
||||||
|
{
|
||||||
|
g.NavWindowingTarget = window->RootNonPopupWindow;
|
||||||
|
g.NavWindowingDisplayAlpha = 0.0f;
|
||||||
|
g.NavWindowingToggleLayer = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (g.NavWindowingTarget)
|
||||||
|
{
|
||||||
|
// Visuals only appears after a brief time holding the button, so that a fast tap (to toggle NavLayer) doesn't add visual noise
|
||||||
|
const float pressed_duration = g.IO.NavInputsDownDuration[ImGuiNavInput_PadMenu];
|
||||||
|
g.NavWindowingDisplayAlpha = ImMax(g.NavWindowingDisplayAlpha, ImSaturate((pressed_duration - 0.20f) / 0.05f));
|
||||||
|
g.NavWindowingToggleLayer &= (g.NavWindowingDisplayAlpha < 1.0f); // Once button is held long enough we don't consider it a tag-to-toggle-layer press anymore.
|
||||||
|
|
||||||
|
// Select window to focus
|
||||||
|
const int focus_change_dir = (int)IsNavInputPressed(ImGuiNavInput_PadFocusPrev, ImGuiNavReadMode_RepeatSlow) - (int)IsNavInputPressed(ImGuiNavInput_PadFocusNext, ImGuiNavReadMode_RepeatSlow);
|
||||||
|
if (focus_change_dir != 0 && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_Modal))
|
||||||
|
{
|
||||||
|
const int i_current = FindWindowIndex(g.NavWindowingTarget);
|
||||||
|
ImGuiWindow* window_target = FindWindowNavigable(i_current + focus_change_dir, -1, focus_change_dir);
|
||||||
|
if (!window_target)
|
||||||
|
window_target = FindWindowNavigable((focus_change_dir < 0) ? (g.Windows.Size - 1) : 0, i_current, focus_change_dir);
|
||||||
|
g.NavWindowingTarget = window_target;
|
||||||
|
g.NavWindowingToggleLayer = false;
|
||||||
|
g.NavWindowingDisplayAlpha = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move window
|
||||||
|
if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove))
|
||||||
|
{
|
||||||
|
const ImVec2 move_delta = GetNavInputAmount2d(1, ImGuiNavReadMode_Down);
|
||||||
|
if (move_delta.x != 0.0f || move_delta.y != 0.0f)
|
||||||
|
{
|
||||||
|
const float move_speed = ImFloor(600 * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
|
||||||
|
g.NavWindowingTarget->PosFloat += move_delta * move_speed;
|
||||||
|
g.NavDisableMouseHover = true;
|
||||||
|
MarkIniSettingsDirty(g.NavWindowingTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsNavInputDown(ImGuiNavInput_PadMenu))
|
||||||
|
{
|
||||||
|
// Apply actual focus only when releasing the NavMenu button (until then the window was merely rendered front-most)
|
||||||
|
if (g.NavWindowingTarget && !g.NavWindowingToggleLayer && (!g.NavWindow || g.NavWindowingTarget != g.NavWindow->RootNonPopupWindow))
|
||||||
|
{
|
||||||
|
ImGui::FocusWindow(g.NavWindowingTarget);
|
||||||
|
g.NavDisableHighlight = false;
|
||||||
|
g.NavDisableMouseHover = true;
|
||||||
|
if (g.NavWindowingTarget->NavLastIds[0] == 0)
|
||||||
|
NavInitWindow(g.NavWindowingTarget, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single press toggles NavLayer
|
||||||
|
if (g.NavWindowingToggleLayer && g.NavWindow)
|
||||||
|
{
|
||||||
|
if ((g.NavWindow->DC.NavLayerActiveMask & (1 << 1)) == 0 && (g.NavWindow->RootWindow->DC.NavLayerActiveMask & (1 << 1)) != 0)
|
||||||
|
ImGui::FocusWindow(g.NavWindow->RootWindow);
|
||||||
|
g.NavLayer = (g.NavWindow->DC.NavLayerActiveMask & (1 << 1)) ? (g.NavLayer ^ 1) : 0;
|
||||||
|
g.NavDisableHighlight = false;
|
||||||
|
g.NavDisableMouseHover = true;
|
||||||
|
if (g.NavLayer == 0 && g.NavWindow->NavLastIds[0] != 0)
|
||||||
|
SetNavIdAndMoveMouse(g.NavWindow->NavLastIds[0], g.NavLayer, ImRect());
|
||||||
|
else
|
||||||
|
NavInitWindow(g.NavWindow, true);
|
||||||
|
}
|
||||||
|
g.NavWindowingTarget = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NB: We modify rect_rel by the amount we scrolled for, so it is immediately updated.
|
// NB: We modify rect_rel by the amount we scrolled for, so it is immediately updated.
|
||||||
static void NavScrollToBringItemIntoView(ImGuiWindow* window, ImRect& item_rect_rel)
|
static void NavScrollToBringItemIntoView(ImGuiWindow* window, ImRect& item_rect_rel)
|
||||||
{
|
{
|
||||||
@ -2699,83 +2778,10 @@ static void NavUpdate()
|
|||||||
}
|
}
|
||||||
g.NavIdIsAlive = false;
|
g.NavIdIsAlive = false;
|
||||||
g.NavJustTabbedId = 0;
|
g.NavJustTabbedId = 0;
|
||||||
|
|
||||||
// Navigation windowing mode (change focus, move/resize window)
|
|
||||||
if (!g.NavWindowingTarget && IsNavInputPressed(ImGuiNavInput_PadMenu, ImGuiNavReadMode_Pressed))
|
|
||||||
{
|
|
||||||
ImGuiWindow* window = g.NavWindow;
|
|
||||||
if (!window)
|
|
||||||
window = FindWindowNavigable(g.Windows.Size-1, -1, -1);
|
|
||||||
if (window)
|
|
||||||
{
|
|
||||||
g.NavWindowingTarget = window->RootNonPopupWindow;
|
|
||||||
g.NavWindowingDisplayAlpha = 0.0f;
|
|
||||||
g.NavWindowingToggleLayer = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (g.NavWindowingTarget)
|
|
||||||
{
|
|
||||||
// Visuals only appears after a brief time holding the button, so that a fast tap (to toggle NavLayer) doesn't add visual noise
|
|
||||||
const float pressed_duration = g.IO.NavInputsDownDuration[ImGuiNavInput_PadMenu];
|
|
||||||
g.NavWindowingDisplayAlpha = ImMax(g.NavWindowingDisplayAlpha, ImSaturate((pressed_duration - 0.20f) / 0.05f));
|
|
||||||
g.NavWindowingToggleLayer &= (g.NavWindowingDisplayAlpha < 1.0f); // Once button is held long enough we don't consider it a tag-to-toggle-layer press anymore.
|
|
||||||
|
|
||||||
// Select window to focus
|
|
||||||
const int focus_change_dir = (int)IsNavInputPressed(ImGuiNavInput_PadFocusPrev, ImGuiNavReadMode_RepeatSlow) - (int)IsNavInputPressed(ImGuiNavInput_PadFocusNext, ImGuiNavReadMode_RepeatSlow);
|
|
||||||
if (focus_change_dir != 0 && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_Modal))
|
|
||||||
{
|
|
||||||
const int i_current = FindWindowIndex(g.NavWindowingTarget);
|
|
||||||
ImGuiWindow* window_target = FindWindowNavigable(i_current + focus_change_dir, -1, focus_change_dir);
|
|
||||||
if (!window_target)
|
|
||||||
window_target = FindWindowNavigable((focus_change_dir < 0) ? (g.Windows.Size-1) : 0, i_current, focus_change_dir);
|
|
||||||
g.NavWindowingTarget = window_target;
|
|
||||||
g.NavWindowingToggleLayer = false;
|
|
||||||
g.NavWindowingDisplayAlpha = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move window
|
|
||||||
if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove))
|
|
||||||
{
|
|
||||||
const ImVec2 move_delta = GetNavInputAmount2d(1, ImGuiNavReadMode_Down);
|
|
||||||
if (move_delta.x != 0.0f || move_delta.y != 0.0f)
|
|
||||||
{
|
|
||||||
const float move_speed = ImFloor(600 * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
|
|
||||||
g.NavWindowingTarget->PosFloat += move_delta * move_speed;
|
|
||||||
g.NavDisableMouseHover = true;
|
|
||||||
MarkIniSettingsDirty(g.NavWindowingTarget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsNavInputDown(ImGuiNavInput_PadMenu))
|
|
||||||
{
|
|
||||||
// Apply actual focus only when releasing the NavMenu button (until then the window was merely rendered front-most)
|
|
||||||
if (g.NavWindowingTarget && !g.NavWindowingToggleLayer && (!g.NavWindow || g.NavWindowingTarget != g.NavWindow->RootNonPopupWindow))
|
|
||||||
{
|
|
||||||
ImGui::FocusWindow(g.NavWindowingTarget);
|
|
||||||
g.NavDisableHighlight = false;
|
|
||||||
g.NavDisableMouseHover = true;
|
|
||||||
if (g.NavWindowingTarget->NavLastIds[0] == 0)
|
|
||||||
NavInitWindow(g.NavWindowingTarget, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Single press toggles NavLayer
|
|
||||||
if (g.NavWindowingToggleLayer && g.NavWindow)
|
|
||||||
{
|
|
||||||
if ((g.NavWindow->DC.NavLayerActiveMask & (1<<1)) == 0 && (g.NavWindow->RootWindow->DC.NavLayerActiveMask & (1<<1)) != 0)
|
|
||||||
ImGui::FocusWindow(g.NavWindow->RootWindow);
|
|
||||||
g.NavLayer = (g.NavWindow->DC.NavLayerActiveMask & (1<<1)) ? (g.NavLayer ^ 1) : 0;
|
|
||||||
g.NavDisableHighlight = false;
|
|
||||||
g.NavDisableMouseHover = true;
|
|
||||||
if (g.NavLayer == 0 && g.NavWindow->NavLastIds[0] != 0)
|
|
||||||
SetNavIdAndMoveMouse(g.NavWindow->NavLastIds[0], g.NavLayer, ImRect());
|
|
||||||
else
|
|
||||||
NavInitWindow(g.NavWindow, true);
|
|
||||||
}
|
|
||||||
g.NavWindowingTarget = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1);
|
IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1);
|
||||||
|
|
||||||
|
NavUpdateWindowingTarget();
|
||||||
|
|
||||||
// Set output flags for user application
|
// Set output flags for user application
|
||||||
g.IO.NavUsable = g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs);
|
g.IO.NavUsable = g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs);
|
||||||
g.IO.NavActive = (g.IO.NavUsable && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL) || g.NavInitRequest;
|
g.IO.NavActive = (g.IO.NavUsable && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL) || g.NavInitRequest;
|
||||||
|
Loading…
Reference in New Issue
Block a user