mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-30 20:51:06 +01:00 
			
		
		
		
	Nav: move code into NavMoveRequestSubmit(). NavApplyItemToResult() takes absolute rect., comments
This commit is contained in:
		| @@ -334,9 +334,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i | |||||||
|  - nav: patterns to make it possible for arrows key to update selection (see JustMovedTo in range_select branch) |  - nav: patterns to make it possible for arrows key to update selection (see JustMovedTo in range_select branch) | ||||||
|  - nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name) |  - nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name) | ||||||
|  - nav: SetItemDefaultFocus() level of priority, so widget like Selectable when inside a popup could claim a low-priority default focus on the first selected iem |  - nav: SetItemDefaultFocus() level of priority, so widget like Selectable when inside a popup could claim a low-priority default focus on the first selected iem | ||||||
|  |  - nav: NavFlattened: init requests don't work properly on flattened siblings. | ||||||
|  |  - nav: NavFlattened: pageup/pagedown/home/end don't work properly on flattened siblings. | ||||||
|  - nav: NavFlattened: ESC on a flattened child should select something. |  - nav: NavFlattened: ESC on a flattened child should select something. | ||||||
|  - nav: NavFlattened: broken: in typical usage scenario, the items of a fully clipped child are currently not considered to enter into a NavFlattened child. |  - nav: NavFlattened: broken: in typical usage scenario, the items of a fully clipped child are currently not considered to enter into a NavFlattened child. | ||||||
|  - nav: NavFlattened: init request doesn't select items that are part of a NavFlattened child |  | ||||||
|  - nav: NavFlattened: cannot access menu-bar of a flattened child window with Alt/menu key (not a very common use case..). |  - nav: NavFlattened: cannot access menu-bar of a flattened child window with Alt/menu key (not a very common use case..). | ||||||
|  - nav: simulate right-click or context activation? (SHIFT+F10) |  - nav: simulate right-click or context activation? (SHIFT+F10) | ||||||
|  - nav/tabbing: refactor old tabbing system and turn into navigation, should pass through all widgets (in submission order?). |  - nav/tabbing: refactor old tabbing system and turn into navigation, should pass through all widgets (in submission order?). | ||||||
|   | |||||||
							
								
								
									
										58
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -917,8 +917,8 @@ static float            NavUpdatePageUpPageDown(); | |||||||
| static inline void      NavUpdateAnyRequestFlag(); | static inline void      NavUpdateAnyRequestFlag(); | ||||||
| static void             NavEndFrame(); | static void             NavEndFrame(); | ||||||
| static bool             NavScoreItem(ImGuiNavItemData* result, ImRect cand); | static bool             NavScoreItem(ImGuiNavItemData* result, ImRect cand); | ||||||
| static void             NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb_rel); | static void             NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb); | ||||||
| static void             NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id); | static void             NavProcessItem(ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb); | ||||||
| static ImVec2           NavCalcPreferredRefPos(); | static ImVec2           NavCalcPreferredRefPos(); | ||||||
| static void             NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); | static void             NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); | ||||||
| static ImGuiWindow*     NavRestoreLastChildNavWindow(ImGuiWindow* window); | static ImGuiWindow*     NavRestoreLastChildNavWindow(ImGuiWindow* window); | ||||||
| @@ -7495,6 +7495,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu | |||||||
|     ImGuiWindow* window = g.CurrentWindow; |     ImGuiWindow* window = g.CurrentWindow; | ||||||
|  |  | ||||||
|     // Set item data |     // Set item data | ||||||
|  |     // (DisplayRect is left untouched, made valid when ImGuiItemStatusFlags_HasDisplayRect is set) | ||||||
|     g.LastItemData.ID = id; |     g.LastItemData.ID = id; | ||||||
|     g.LastItemData.Rect = bb; |     g.LastItemData.Rect = bb; | ||||||
|     g.LastItemData.InFlags = g.CurrentItemFlags; |     g.LastItemData.InFlags = g.CurrentItemFlags; | ||||||
| @@ -7516,7 +7517,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu | |||||||
|         if (g.NavId == id || g.NavAnyRequest) |         if (g.NavId == id || g.NavAnyRequest) | ||||||
|             if (g.NavWindow->RootWindowForNav == window->RootWindowForNav) |             if (g.NavWindow->RootWindowForNav == window->RootWindowForNav) | ||||||
|                 if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened)) |                 if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened)) | ||||||
|                     NavProcessItem(window, nav_bb_arg ? *nav_bb_arg : bb, id); |                     NavProcessItem(window, id, nav_bb_arg ? *nav_bb_arg : bb); | ||||||
|  |  | ||||||
|         // [DEBUG] Item Picker tool, when enabling the "extended" version we perform the check in ItemAdd() |         // [DEBUG] Item Picker tool, when enabling the "extended" version we perform the check in ItemAdd() | ||||||
| #ifdef IMGUI_DEBUG_TOOL_ITEM_PICKER_EX | #ifdef IMGUI_DEBUG_TOOL_ITEM_PICKER_EX | ||||||
| @@ -8879,20 +8880,22 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result, ImRect cand) | |||||||
|     return new_best; |     return new_best; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb_rel) | static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb) | ||||||
| { | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     IM_ASSERT(g.LastItemData.ID == id); // Otherwise pulling from window->DC wouldn't be right | ||||||
|     result->Window = window; |     result->Window = window; | ||||||
|     result->ID = id; |     result->ID = id; | ||||||
|     result->FocusScopeId = window->DC.NavFocusScopeIdCurrent; |     result->FocusScopeId = window->DC.NavFocusScopeIdCurrent; | ||||||
|     result->RectRel = nav_bb_rel; |     result->RectRel = ImRect(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos); | ||||||
| } | } | ||||||
|  |  | ||||||
| // We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above) | // We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above) | ||||||
| static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id) | // This is called after LastItemData is set. | ||||||
|  | static void ImGui::NavProcessItem(ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb) | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
|     const ImGuiItemFlags item_flags = g.LastItemData.InFlags; |     const ImGuiItemFlags item_flags = g.LastItemData.InFlags; | ||||||
|     const ImRect nav_bb_rel(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos); |  | ||||||
|  |  | ||||||
|     // Process Init Request |     // Process Init Request | ||||||
|     if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent) |     if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent) | ||||||
| @@ -8902,7 +8905,7 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con | |||||||
|         if (candidate_for_nav_default_focus || g.NavInitResultId == 0) |         if (candidate_for_nav_default_focus || g.NavInitResultId == 0) | ||||||
|         { |         { | ||||||
|             g.NavInitResultId = id; |             g.NavInitResultId = id; | ||||||
|             g.NavInitResultRectRel = nav_bb_rel; |             g.NavInitResultRectRel = ImRect(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos); | ||||||
|         } |         } | ||||||
|         if (candidate_for_nav_default_focus) |         if (candidate_for_nav_default_focus) | ||||||
|         { |         { | ||||||
| @@ -8926,14 +8929,14 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con | |||||||
|                 new_best = false; |                 new_best = false; | ||||||
| #endif | #endif | ||||||
|             if (new_best) |             if (new_best) | ||||||
|                 NavApplyItemToResult(result, window, id, nav_bb_rel); |                 NavApplyItemToResult(result, window, id, nav_bb); | ||||||
|  |  | ||||||
|             // Features like PageUp/PageDown need to maintain a separate score for the visible set of items. |             // Features like PageUp/PageDown need to maintain a separate score for the visible set of items. | ||||||
|             const float VISIBLE_RATIO = 0.70f; |             const float VISIBLE_RATIO = 0.70f; | ||||||
|             if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb)) |             if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb)) | ||||||
|                 if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO) |                 if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO) | ||||||
|                     if (NavScoreItem(&g.NavMoveResultLocalVisible, nav_bb)) |                     if (NavScoreItem(&g.NavMoveResultLocalVisible, nav_bb)) | ||||||
|                         NavApplyItemToResult(&g.NavMoveResultLocalVisible, window, id, nav_bb_rel); |                         NavApplyItemToResult(&g.NavMoveResultLocalVisible, window, id, nav_bb); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -8944,7 +8947,7 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con | |||||||
|         g.NavLayer = window->DC.NavLayerCurrent; |         g.NavLayer = window->DC.NavLayerCurrent; | ||||||
|         g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent; |         g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent; | ||||||
|         g.NavIdIsAlive = true; |         g.NavIdIsAlive = true; | ||||||
|         window->NavRectRel[window->DC.NavLayerCurrent] = nav_bb_rel;    // Store item bounding box (relative to window position) |         window->NavRectRel[window->DC.NavLayerCurrent] = ImRect(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos);    // Store item bounding box (relative to window position) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -8954,6 +8957,21 @@ bool ImGui::NavMoveRequestButNoResultYet() | |||||||
|     return g.NavMoveScoringItems && g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0; |     return g.NavMoveScoringItems && g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags) | ||||||
|  | { | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     IM_ASSERT(g.NavWindow != NULL); | ||||||
|  |     g.NavMoveSubmitted = g.NavMoveScoringItems = true; | ||||||
|  |     g.NavMoveDir = move_dir; | ||||||
|  |     g.NavMoveClipDir = clip_dir; | ||||||
|  |     g.NavMoveFlags = move_flags; | ||||||
|  |     g.NavMoveForwardToNextFrame = false; | ||||||
|  |     g.NavMoveKeyMods = g.IO.KeyMods; | ||||||
|  |     g.NavMoveResultLocal.Clear(); | ||||||
|  |     g.NavMoveResultLocalVisible.Clear(); | ||||||
|  |     g.NavMoveResultOther.Clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
| void ImGui::NavMoveRequestCancel() | void ImGui::NavMoveRequestCancel() | ||||||
| { | { | ||||||
|     ImGuiContext& g = *GImGui; |     ImGuiContext& g = *GImGui; | ||||||
| @@ -9304,7 +9322,6 @@ void ImGui::NavUpdateCreateMoveRequest() | |||||||
|         IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None); |         IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None); | ||||||
|         IM_ASSERT(g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded); |         IM_ASSERT(g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded); | ||||||
|         IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir); |         IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir); | ||||||
|         g.NavMoveForwardToNextFrame = false; |  | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
| @@ -9340,20 +9357,12 @@ void ImGui::NavUpdateCreateMoveRequest() | |||||||
|     } |     } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|     // If we initiate a movement request and have no current NavId, we initiate a InitDefaultRequest that will be used as a fallback if the direction fails to find a match |     // Submit | ||||||
|     // FIXME: Would be nice to call a single function to initiate a new request |     g.NavMoveForwardToNextFrame = false; | ||||||
|     if (g.NavMoveDir != ImGuiDir_None) |     if (g.NavMoveDir != ImGuiDir_None) | ||||||
|     { |         NavMoveRequestSubmit(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveFlags); | ||||||
|         IM_ASSERT(window != NULL); |  | ||||||
|         g.NavMoveSubmitted = g.NavMoveScoringItems = true; |  | ||||||
|         g.NavMoveKeyMods = io.KeyMods; |  | ||||||
|         g.NavMoveDirForDebug = g.NavMoveDir; |  | ||||||
|         g.NavMoveResultLocal.Clear(); |  | ||||||
|         g.NavMoveResultLocalVisible.Clear(); |  | ||||||
|         g.NavMoveResultOther.Clear(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Moving with no reference triggers a init request |     // Moving with no reference triggers a init request (will be used as a fallback if the direction fails to find a match) | ||||||
|     if (g.NavMoveSubmitted && g.NavId == 0) |     if (g.NavMoveSubmitted && g.NavId == 0) | ||||||
|     { |     { | ||||||
|         IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer); |         IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer); | ||||||
| @@ -9507,6 +9516,7 @@ static void ImGui::NavUpdateCancelRequest() | |||||||
|  |  | ||||||
| // Handle PageUp/PageDown/Home/End keys | // Handle PageUp/PageDown/Home/End keys | ||||||
| // Called from NavUpdateCreateMoveRequest() which will use our output to create a move request | // Called from NavUpdateCreateMoveRequest() which will use our output to create a move request | ||||||
|  | // FIXME-NAV: This doesn't work properly with NavFlattened siblings as we use NavWindow rectangle for reference | ||||||
| // FIXME-NAV: how to get Home/End to aim at the beginning/end of a 2D grid? | // FIXME-NAV: how to get Home/End to aim at the beginning/end of a 2D grid? | ||||||
| static float ImGui::NavUpdatePageUpPageDown() | static float ImGui::NavUpdatePageUpPageDown() | ||||||
| { | { | ||||||
|   | |||||||
| @@ -758,7 +758,7 @@ enum ImGuiItemStatusFlags_ | |||||||
| { | { | ||||||
|     ImGuiItemStatusFlags_None               = 0, |     ImGuiItemStatusFlags_None               = 0, | ||||||
|     ImGuiItemStatusFlags_HoveredRect        = 1 << 0,   // Mouse position is within item rectangle (does NOT mean that the window is in correct z-order and can be hovered!, this is only one part of the most-common IsItemHovered test) |     ImGuiItemStatusFlags_HoveredRect        = 1 << 0,   // Mouse position is within item rectangle (does NOT mean that the window is in correct z-order and can be hovered!, this is only one part of the most-common IsItemHovered test) | ||||||
|     ImGuiItemStatusFlags_HasDisplayRect     = 1 << 1,   // window->DC.LastItemDisplayRect is valid |     ImGuiItemStatusFlags_HasDisplayRect     = 1 << 1,   // g.LastItemData.DisplayRect is valid | ||||||
|     ImGuiItemStatusFlags_Edited             = 1 << 2,   // Value exposed by item was edited in the current frame (should match the bool return value of most widgets) |     ImGuiItemStatusFlags_Edited             = 1 << 2,   // Value exposed by item was edited in the current frame (should match the bool return value of most widgets) | ||||||
|     ImGuiItemStatusFlags_ToggledSelection   = 1 << 3,   // Set when Selectable(), TreeNode() reports toggling a selection. We can't report "Selected", only state changes, in order to easily handle clipping with less issues. |     ImGuiItemStatusFlags_ToggledSelection   = 1 << 3,   // Set when Selectable(), TreeNode() reports toggling a selection. We can't report "Selected", only state changes, in order to easily handle clipping with less issues. | ||||||
|     ImGuiItemStatusFlags_ToggledOpen        = 1 << 4,   // Set when TreeNode() reports toggling their open state. |     ImGuiItemStatusFlags_ToggledOpen        = 1 << 4,   // Set when TreeNode() reports toggling their open state. | ||||||
| @@ -1123,8 +1123,8 @@ struct ImGuiLastItemData | |||||||
|     ImGuiID                 ID; |     ImGuiID                 ID; | ||||||
|     ImGuiItemFlags          InFlags;            // See ImGuiItemFlags_ |     ImGuiItemFlags          InFlags;            // See ImGuiItemFlags_ | ||||||
|     ImGuiItemStatusFlags    StatusFlags;        // See ImGuiItemStatusFlags_ |     ImGuiItemStatusFlags    StatusFlags;        // See ImGuiItemStatusFlags_ | ||||||
|     ImRect                  Rect; |     ImRect                  Rect;               // Full rectangle | ||||||
|     ImRect                  DisplayRect; |     ImRect                  DisplayRect;        // Display rectangle (only if ImGuiItemStatusFlags_HasDisplayRect is set) | ||||||
|  |  | ||||||
|     ImGuiLastItemData()     { memset(this, 0, sizeof(*this)); } |     ImGuiLastItemData()     { memset(this, 0, sizeof(*this)); } | ||||||
| }; | }; | ||||||
| @@ -2458,6 +2458,7 @@ namespace ImGui | |||||||
|     // Gamepad/Keyboard Navigation |     // Gamepad/Keyboard Navigation | ||||||
|     IMGUI_API void          NavInitWindow(ImGuiWindow* window, bool force_reinit); |     IMGUI_API void          NavInitWindow(ImGuiWindow* window, bool force_reinit); | ||||||
|     IMGUI_API bool          NavMoveRequestButNoResultYet(); |     IMGUI_API bool          NavMoveRequestButNoResultYet(); | ||||||
|  |     IMGUI_API void          NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags); | ||||||
|     IMGUI_API void          NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags); |     IMGUI_API void          NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags); | ||||||
|     IMGUI_API void          NavMoveRequestCancel(); |     IMGUI_API void          NavMoveRequestCancel(); | ||||||
|     IMGUI_API void          NavMoveRequestApplyResult(); |     IMGUI_API void          NavMoveRequestApplyResult(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user