mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-30 20:51:06 +01:00 
			
		
		
		
	Nav: small refactor of forwarding, clarified that MoveDir only set when RequestActive, removed one indent level in NavUpdatePageUpPageDown().
This commit is contained in:
		
							
								
								
									
										42
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -8943,12 +8943,12 @@ void ImGui::NavMoveRequestCancel() | |||||||
| void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags) | void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|     IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_None); |     IM_ASSERT(g.NavMoveRequestForwardToNextFrame == false); | ||||||
|     NavMoveRequestCancel(); |     NavMoveRequestCancel(); | ||||||
|  |     g.NavMoveRequestForwardToNextFrame = true; | ||||||
|     g.NavMoveDir = move_dir; |     g.NavMoveDir = move_dir; | ||||||
|     g.NavMoveClipDir = clip_dir; |     g.NavMoveClipDir = clip_dir; | ||||||
|     g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; |     g.NavMoveRequestFlags = move_flags | ImGuiNavMoveFlags_Forwarded; | ||||||
|     g.NavMoveRequestFlags = move_flags; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // Navigation wrap-around logic is delayed to the end of the frame because this operation is only valid after entire | // Navigation wrap-around logic is delayed to the end of the frame because this operation is only valid after entire | ||||||
| @@ -9151,6 +9151,7 @@ static void ImGui::NavUpdate() | |||||||
|     // Process navigation move request |     // Process navigation move request | ||||||
|     if (g.NavMoveRequest) |     if (g.NavMoveRequest) | ||||||
|         NavMoveRequestApplyResult(); |         NavMoveRequestApplyResult(); | ||||||
|  |     g.NavMoveRequest = false; | ||||||
|  |  | ||||||
|     // Apply application mouse position movement, after we had a chance to process move request result. |     // Apply application mouse position movement, after we had a chance to process move request result. | ||||||
|     if (g.NavMousePosDirty && g.NavIdIsAlive) |     if (g.NavMousePosDirty && g.NavIdIsAlive) | ||||||
| @@ -9203,16 +9204,24 @@ static void ImGui::NavUpdate() | |||||||
|         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); | ||||||
|     g.NavMoveRequest = false; |  | ||||||
|  |  | ||||||
|     // Process programmatic activation request |     // Process programmatic activation request | ||||||
|     if (g.NavNextActivateId != 0) |     if (g.NavNextActivateId != 0) | ||||||
|         g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId; |         g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId; | ||||||
|     g.NavNextActivateId = 0; |     g.NavNextActivateId = 0; | ||||||
|  |  | ||||||
|     // Initiate directional inputs request |     if (g.NavMoveRequestForwardToNextFrame) | ||||||
|     if (g.NavMoveRequestForward == ImGuiNavForward_None) |  | ||||||
|     { |     { | ||||||
|  |         // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window) | ||||||
|  |         // (Preserve g.NavMoveRequestFlags, g.NavMoveClipDir which were set by the NavMoveRequestForward() function) | ||||||
|  |         IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None); | ||||||
|  |         IM_ASSERT(g.NavMoveRequestFlags & ImGuiNavMoveFlags_Forwarded); | ||||||
|  |         IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir); | ||||||
|  |         g.NavMoveRequestForwardToNextFrame = false; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         // Initiate directional inputs request | ||||||
|         g.NavMoveDir = ImGuiDir_None; |         g.NavMoveDir = ImGuiDir_None; | ||||||
|         g.NavMoveRequestFlags = ImGuiNavMoveFlags_None; |         g.NavMoveRequestFlags = ImGuiNavMoveFlags_None; | ||||||
|         if (g.NavWindow && !g.NavWindowingTarget && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) |         if (g.NavWindow && !g.NavWindowingTarget && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) | ||||||
| @@ -9225,14 +9234,6 @@ static void ImGui::NavUpdate() | |||||||
|         } |         } | ||||||
|         g.NavMoveClipDir = g.NavMoveDir; |         g.NavMoveClipDir = g.NavMoveDir; | ||||||
|     } |     } | ||||||
|     else if (g.NavMoveRequestForward == ImGuiNavForward_ForwardQueued) |  | ||||||
|     { |  | ||||||
|         // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window) |  | ||||||
|         // (Preserve g.NavMoveRequestFlags, g.NavMoveClipDir which were set by the NavMoveRequestForward() function) |  | ||||||
|         IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None); |  | ||||||
|         IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir); |  | ||||||
|         g.NavMoveRequestForward = ImGuiNavForward_ForwardActive; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Update PageUp/PageDown/Home/End scroll |     // Update PageUp/PageDown/Home/End scroll | ||||||
|     // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag? |     // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag? | ||||||
| @@ -9256,6 +9257,8 @@ static void ImGui::NavUpdate() | |||||||
|         g.NavDisableHighlight = false; |         g.NavDisableHighlight = false; | ||||||
|     } |     } | ||||||
|     NavUpdateAnyRequestFlag(); |     NavUpdateAnyRequestFlag(); | ||||||
|  |     if (g.NavMoveDir != ImGuiDir_None) | ||||||
|  |         IM_ASSERT(g.NavMoveRequest); | ||||||
|  |  | ||||||
|     // Scrolling |     // Scrolling | ||||||
|     if (g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.NavWindowingTarget) |     if (g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.NavWindowingTarget) | ||||||
| @@ -9344,9 +9347,6 @@ void ImGui::NavMoveRequestApplyResult() | |||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|  |  | ||||||
|     if (g.NavMoveRequestForward == ImGuiNavForward_ForwardActive) |  | ||||||
|         g.NavMoveRequestForward = ImGuiNavForward_None; |  | ||||||
|  |  | ||||||
|     if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0) |     if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0) | ||||||
|     { |     { | ||||||
|         // In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result) |         // In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result) | ||||||
| @@ -9471,8 +9471,9 @@ static float ImGui::NavUpdatePageUpPageDown() | |||||||
|     const bool page_down_held = IsKeyDown(io.KeyMap[ImGuiKey_PageDown]) && !IsActiveIdUsingKey(ImGuiKey_PageDown); |     const bool page_down_held = IsKeyDown(io.KeyMap[ImGuiKey_PageDown]) && !IsActiveIdUsingKey(ImGuiKey_PageDown); | ||||||
|     const bool home_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_Home]) && !IsActiveIdUsingKey(ImGuiKey_Home); |     const bool home_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_Home]) && !IsActiveIdUsingKey(ImGuiKey_Home); | ||||||
|     const bool end_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_End]) && !IsActiveIdUsingKey(ImGuiKey_End); |     const bool end_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_End]) && !IsActiveIdUsingKey(ImGuiKey_End); | ||||||
|     if (page_up_held != page_down_held || home_pressed != end_pressed) // If either (not both) are pressed |     if (page_up_held == page_down_held && home_pressed == end_pressed) // Proceed if either (not both) are pressed, otherwise early out | ||||||
|     { |         return 0.0f; | ||||||
|  |  | ||||||
|     if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll) |     if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll) | ||||||
|     { |     { | ||||||
|         // Fallback manual-scroll when window has no navigable item |         // Fallback manual-scroll when window has no navigable item | ||||||
| @@ -9525,7 +9526,6 @@ static float ImGui::NavUpdatePageUpPageDown() | |||||||
|         } |         } | ||||||
|         return nav_scoring_rect_offset_y; |         return nav_scoring_rect_offset_y; | ||||||
|     } |     } | ||||||
|     } |  | ||||||
|     return 0.0f; |     return 0.0f; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -9542,7 +9542,7 @@ static void ImGui::NavEndFrame() | |||||||
|     ImGuiWindow* window = g.NavWindow; |     ImGuiWindow* window = g.NavWindow; | ||||||
|     const ImGuiNavMoveFlags move_flags = g.NavMoveRequestFlags; |     const ImGuiNavMoveFlags move_flags = g.NavMoveRequestFlags; | ||||||
|     const ImGuiNavMoveFlags wanted_flags = ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY; |     const ImGuiNavMoveFlags wanted_flags = ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY; | ||||||
|     if (window && NavMoveRequestButNoResultYet() && (g.NavMoveRequestFlags & wanted_flags) && g.NavMoveRequestForward == ImGuiNavForward_None) |     if (window && NavMoveRequestButNoResultYet() && (g.NavMoveRequestFlags & wanted_flags) && (g.NavMoveRequestFlags & ImGuiNavMoveFlags_Forwarded) == 0) | ||||||
|     { |     { | ||||||
|         bool do_forward = false; |         bool do_forward = false; | ||||||
|         ImRect bb_rel = window->NavRectRel[g.NavLayer]; |         ImRect bb_rel = window->NavRectRel[g.NavLayer]; | ||||||
|   | |||||||
| @@ -1181,14 +1181,8 @@ enum ImGuiNavMoveFlags_ | |||||||
|     ImGuiNavMoveFlags_WrapY                 = 1 << 3,   // This is not super useful but provided for completeness |     ImGuiNavMoveFlags_WrapY                 = 1 << 3,   // This is not super useful but provided for completeness | ||||||
|     ImGuiNavMoveFlags_AllowCurrentNavId     = 1 << 4,   // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place) |     ImGuiNavMoveFlags_AllowCurrentNavId     = 1 << 4,   // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place) | ||||||
|     ImGuiNavMoveFlags_AlsoScoreVisibleSet   = 1 << 5,   // Store alternate result in NavMoveResultLocalVisibleSet that only comprise elements that are already fully visible (used by PageUp/PageDown) |     ImGuiNavMoveFlags_AlsoScoreVisibleSet   = 1 << 5,   // Store alternate result in NavMoveResultLocalVisibleSet that only comprise elements that are already fully visible (used by PageUp/PageDown) | ||||||
|     ImGuiNavMoveFlags_ScrollToEdge          = 1 << 6 |     ImGuiNavMoveFlags_ScrollToEdge          = 1 << 6, | ||||||
| }; |     ImGuiNavMoveFlags_Forwarded             = 1 << 7 | ||||||
|  |  | ||||||
| enum ImGuiNavForward |  | ||||||
| { |  | ||||||
|     ImGuiNavForward_None, |  | ||||||
|     ImGuiNavForward_ForwardQueued, |  | ||||||
|     ImGuiNavForward_ForwardActive |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum ImGuiNavLayer | enum ImGuiNavLayer | ||||||
| @@ -1525,14 +1519,14 @@ struct ImGuiContext | |||||||
|     bool                    NavMousePosDirty;                   // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default) |     bool                    NavMousePosDirty;                   // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default) | ||||||
|     bool                    NavDisableHighlight;                // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) |     bool                    NavDisableHighlight;                // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) | ||||||
|     bool                    NavDisableMouseHover;               // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. |     bool                    NavDisableMouseHover;               // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. | ||||||
|     bool                    NavAnyRequest;                      // ~~ NavMoveRequest || NavInitRequest |     bool                    NavAnyRequest;                      // ~~ NavMoveRequest || NavInitRequest this is to perform early out in ItemAdd() | ||||||
|     bool                    NavInitRequest;                     // Init request for appearing window to select first item |     bool                    NavInitRequest;                     // Init request for appearing window to select first item | ||||||
|     bool                    NavInitRequestFromMove; |     bool                    NavInitRequestFromMove; | ||||||
|     ImGuiID                 NavInitResultId;                    // Init request result (first item of the window, or one for which SetItemDefaultFocus() was called) |     ImGuiID                 NavInitResultId;                    // Init request result (first item of the window, or one for which SetItemDefaultFocus() was called) | ||||||
|     ImRect                  NavInitResultRectRel;               // Init request result rectangle (relative to parent window) |     ImRect                  NavInitResultRectRel;               // Init request result rectangle (relative to parent window) | ||||||
|     bool                    NavMoveRequest;                     // Move request for this frame |     bool                    NavMoveRequest;                     // Move request for this frame | ||||||
|  |     bool                    NavMoveRequestForwardToNextFrame; | ||||||
|     ImGuiNavMoveFlags       NavMoveRequestFlags; |     ImGuiNavMoveFlags       NavMoveRequestFlags; | ||||||
|     ImGuiNavForward         NavMoveRequestForward;              // None / ForwardQueued / ForwardActive (this is used to navigate sibling parent menus from a child menu) |  | ||||||
|     ImGuiKeyModFlags        NavMoveRequestKeyMods; |     ImGuiKeyModFlags        NavMoveRequestKeyMods; | ||||||
|     ImGuiDir                NavMoveDir, NavMoveDirLast;         // Direction of the move request (left/right/up/down), direction of the previous move request |     ImGuiDir                NavMoveDir, NavMoveDirLast;         // Direction of the move request (left/right/up/down), direction of the previous move request | ||||||
|     ImGuiDir                NavMoveClipDir;                     // FIXME-NAV: Describe the purpose of this better. Might want to rename? |     ImGuiDir                NavMoveClipDir;                     // FIXME-NAV: Describe the purpose of this better. Might want to rename? | ||||||
| @@ -1733,8 +1727,8 @@ struct ImGuiContext | |||||||
|         NavInitRequestFromMove = false; |         NavInitRequestFromMove = false; | ||||||
|         NavInitResultId = 0; |         NavInitResultId = 0; | ||||||
|         NavMoveRequest = false; |         NavMoveRequest = false; | ||||||
|  |         NavMoveRequestForwardToNextFrame = false; | ||||||
|         NavMoveRequestFlags = ImGuiNavMoveFlags_None; |         NavMoveRequestFlags = ImGuiNavMoveFlags_None; | ||||||
|         NavMoveRequestForward = ImGuiNavForward_None; |  | ||||||
|         NavMoveRequestKeyMods = ImGuiKeyModFlags_None; |         NavMoveRequestKeyMods = ImGuiKeyModFlags_None; | ||||||
|         NavMoveDir = NavMoveDirLast = NavMoveClipDir = ImGuiDir_None; |         NavMoveDir = NavMoveDirLast = NavMoveClipDir = ImGuiDir_None; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5897,12 +5897,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l | |||||||
|                 toggled = true; |                 toggled = true; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Left && is_open) |         if (g.NavId == id && g.NavMoveDir == ImGuiDir_Left && is_open) | ||||||
|         { |         { | ||||||
|             toggled = true; |             toggled = true; | ||||||
|             NavMoveRequestCancel(); |             NavMoveRequestCancel(); | ||||||
|         } |         } | ||||||
|         if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right && !is_open) // If there's something upcoming on the line we may want to give it the priority? |         if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right && !is_open) // If there's something upcoming on the line we may want to give it the priority? | ||||||
|         { |         { | ||||||
|             toggled = true; |             toggled = true; | ||||||
|             NavMoveRequestCancel(); |             NavMoveRequestCancel(); | ||||||
| @@ -6690,7 +6690,7 @@ void ImGui::EndMenuBar() | |||||||
|         ImGuiWindow* nav_earliest_child = g.NavWindow; |         ImGuiWindow* nav_earliest_child = g.NavWindow; | ||||||
|         while (nav_earliest_child->ParentWindow && (nav_earliest_child->ParentWindow->Flags & ImGuiWindowFlags_ChildMenu)) |         while (nav_earliest_child->ParentWindow && (nav_earliest_child->ParentWindow->Flags & ImGuiWindowFlags_ChildMenu)) | ||||||
|             nav_earliest_child = nav_earliest_child->ParentWindow; |             nav_earliest_child = nav_earliest_child->ParentWindow; | ||||||
|         if (nav_earliest_child->ParentWindow == window && nav_earliest_child->DC.ParentLayoutType == ImGuiLayoutType_Horizontal && g.NavMoveRequestForward == ImGuiNavForward_None) |         if (nav_earliest_child->ParentWindow == window && nav_earliest_child->DC.ParentLayoutType == ImGuiLayoutType_Horizontal && (g.NavMoveRequestFlags & ImGuiNavMoveFlags_Forwarded) == 0) | ||||||
|         { |         { | ||||||
|             // To do so we claim focus back, restore NavId and then process the movement request for yet another frame. |             // To do so we claim focus back, restore NavId and then process the movement request for yet another frame. | ||||||
|             // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth bothering) |             // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth bothering) | ||||||
| @@ -6910,7 +6910,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) | |||||||
|             want_close = menu_is_open; |             want_close = menu_is_open; | ||||||
|             want_open = !menu_is_open; |             want_open = !menu_is_open; | ||||||
|         } |         } | ||||||
|         if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open |         if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open | ||||||
|         { |         { | ||||||
|             want_open = true; |             want_open = true; | ||||||
|             NavMoveRequestCancel(); |             NavMoveRequestCancel(); | ||||||
| @@ -6928,7 +6928,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) | |||||||
|         { |         { | ||||||
|             want_open = true; |             want_open = true; | ||||||
|         } |         } | ||||||
|         else if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open |         else if (g.NavId == id && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open | ||||||
|         { |         { | ||||||
|             want_open = true; |             want_open = true; | ||||||
|             NavMoveRequestCancel(); |             NavMoveRequestCancel(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user