From 17519c313a4f4c01df62a1628f28f0571dec9b1f Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 11 Oct 2017 20:47:41 +0200 Subject: [PATCH] Nav: Extract part of NavUpdate() into a saner NavUpdateWindowingTarget() (#787) --- imgui.cpp | 156 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 81 insertions(+), 75 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index cb5c8bf31..733c04f23 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2606,6 +2606,85 @@ static ImVec2 GetNavInputAmount2d(int stick_no, ImGuiNavReadMode mode, float slo 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. static void NavScrollToBringItemIntoView(ImGuiWindow* window, ImRect& item_rect_rel) { @@ -2699,83 +2778,10 @@ static void NavUpdate() } g.NavIdIsAlive = false; 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); + NavUpdateWindowingTarget(); + // Set output flags for user application 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;