mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 05:01:05 +01:00 
			
		
		
		
	Merge branch 'master' into docking
# Conflicts: # imgui.cpp
This commit is contained in:
		| @@ -123,6 +123,16 @@ Other Changes: | ||||
| - Added IsMouseTripleClicked() function. Tracking multi-click count in IO structure. (#3229) [@kudaba] | ||||
| - Modals: fixed issue hovering popups inside a child inside a modal. (#4676, #4527) | ||||
| - Fixed IsWindowFocused()/IsWindowHovered() issues with childs inside popups. (#4676) | ||||
| - Nav: tabbing now cycles through clipped items and scroll accordingly. (#4449) | ||||
| - Nav: pressing PageUp/PageDown/Home/End when in Menu layer automatically moves back to Main layer. | ||||
| - Nav: fixed resizing window from borders setting navigation to Menu layer. | ||||
| - Nav: pressing Esc to exit a child window reactivates the Nav highlight if it was disabled by mouse. | ||||
| - Nav: with ImGuiConfigFlags_NavEnableSetMousePos enabled: Fixed absolute mouse position when using | ||||
|   Home/End leads to scrolling. Fixed not setting mouse position when a failed move request (e.g. when | ||||
|   already at edge) reactivates the navigation highlight. | ||||
| - InputText, Nav: fixed repeated calls to SetKeyboardFocusHere() preventing to use InputText(). (#4682) | ||||
| - InputText: made double-click select word, triple-line select line. Word delimitation logic differs | ||||
|   slightly from the one used by CTRL+arrows. (#2244) | ||||
| - Clipper: currently focused item is automatically included in clipper range. | ||||
|   Fixes issue where e.g. drag and dropping an item and scrolling ensure the item source location is | ||||
|   still submitted. (#3841, #1725) [@GamingMinds-DanielC, @ocornut] | ||||
| @@ -130,15 +140,6 @@ Other Changes: | ||||
|   by the clipper to display. (#3841) | ||||
| - Clipper: Fixed content height declaration slightly mismatching the value of when not using a clipper. | ||||
|   (an additional ItemSpacing.y was declared, affecting scrollbar range). | ||||
| - Nav: pressing PageUp/PageDown/Home/End when in Menu layer automatically moves back to Main layer. | ||||
| - Nav: fixed resizing window from borders setting navigation to Menu layer. | ||||
| - Nav: pressing Esc to exit a child window reactivates the Nav highlight if it was disabled by mouse. | ||||
| - Nav: (with ImGuiConfigFlags_NavEnableSetMousePos): fixed absolute mouse position when using Home/End | ||||
|   leads to scrolling. | ||||
| - Nav: (with ImGuiConfigFlags_NavEnableSetMousePos): fixed not setting mouse position when a failed | ||||
|   move request (e.g. already at edge) reactivate the navigation highlight. | ||||
| - InputText: made double-click select word, triple-line select line. Word delimitation logic differs | ||||
|   slightly from the one used by CTRL+arrows. (#2244) | ||||
| - Backends: Vulkan: Call vkCmdSetScissor() at the end of render with a full-viewport to reduce | ||||
|   likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling | ||||
|   vkCmdSetScissor() explicitly every frame. (#4644) | ||||
|   | ||||
| @@ -369,7 +369,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i | ||||
|  - 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: 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/tabbing: refactor old tabbing system and turn into navigation, should pass through all widgets (in submission order?). | ||||
|  - nav/popup: esc/enter default behavior for popups, e.g. be able to mark an "ok" or "cancel" button that would get triggered by those keys, default validation button, etc. | ||||
|  - nav/treenode: left within a tree node block as a fallback (ImGuiTreeNodeFlags_NavLeftJumpsBackHere by default?) | ||||
|  - nav/menus: pressing left-right on a vertically clipped menu bar tends to jump to the collapse/close buttons. | ||||
|   | ||||
							
								
								
									
										237
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										237
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -929,6 +929,7 @@ static void             NavUpdateWindowing(); | ||||
| static void             NavUpdateWindowingOverlay(); | ||||
| static void             NavUpdateCancelRequest(); | ||||
| static void             NavUpdateCreateMoveRequest(); | ||||
| static void             NavUpdateCreateTabbingRequest(); | ||||
| static float            NavUpdatePageUpPageDown(); | ||||
| static inline void      NavUpdateAnyRequestFlag(); | ||||
| static void             NavUpdateCreateWrappingRequest(); | ||||
| @@ -936,6 +937,7 @@ static void             NavEndFrame(); | ||||
| static bool             NavScoreItem(ImGuiNavItemData* result); | ||||
| static void             NavApplyItemToResult(ImGuiNavItemData* result); | ||||
| static void             NavProcessItem(); | ||||
| static void             NavProcessItemForTabbingRequest(ImGuiWindow* window, ImGuiID id); | ||||
| static ImVec2           NavCalcPreferredRefPos(); | ||||
| static void             NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); | ||||
| static ImGuiWindow*     NavRestoreLastChildNavWindow(ImGuiWindow* window); | ||||
| @@ -953,7 +955,6 @@ static void             UpdateDebugToolStackQueries(); | ||||
| static void             UpdateSettings(); | ||||
| static void             UpdateMouseInputs(); | ||||
| static void             UpdateMouseWheel(); | ||||
| static void             UpdateTabFocus(); | ||||
| static bool             UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect); | ||||
| static void             RenderWindowOuterBorders(ImGuiWindow* window); | ||||
| static void             RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size); | ||||
| @@ -2316,9 +2317,11 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items | ||||
|     int end = (int)((rect.Max.y - pos.y) / items_height); | ||||
|  | ||||
|     // When performing a navigation request, ensure we have one item extra in the direction we are moving to | ||||
|     if (g.NavMoveScoringItems && g.NavMoveClipDir == ImGuiDir_Up) | ||||
|     // FIXME: Verify this works with tabbing | ||||
|     const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); | ||||
|     if (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) | ||||
|         start--; | ||||
|     if (g.NavMoveScoringItems && g.NavMoveClipDir == ImGuiDir_Down) | ||||
|     if (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) | ||||
|         end++; | ||||
|  | ||||
|     start = ImClamp(start, 0, items_count); | ||||
| @@ -2519,8 +2522,11 @@ bool ImGuiListClipper::Step() | ||||
|         else | ||||
|         { | ||||
|             // Add range selected to be included for navigation | ||||
|             if (g.NavMoveScoringItems) | ||||
|             const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); | ||||
|             if (is_nav_request) | ||||
|                 data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, 0, 0)); | ||||
|             if (is_nav_request && (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && g.NavTabbingDir == -1) | ||||
|                 data->Ranges.push_back(ImGuiListClipperRange::FromIndices(ItemsCount - 1, ItemsCount)); | ||||
|  | ||||
|             // Add focused/active item | ||||
|             ImRect nav_rect_abs = ImGui::WindowRectRelToAbs(window, window->NavRectRel[0]); | ||||
| @@ -2528,8 +2534,8 @@ bool ImGuiListClipper::Step() | ||||
|                 data->Ranges.push_back(ImGuiListClipperRange::FromPositions(nav_rect_abs.Min.y, nav_rect_abs.Max.y, 0, 0)); | ||||
|  | ||||
|             // Add visible range | ||||
|             const int off_min = (g.NavMoveScoringItems && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0; | ||||
|             const int off_max = (g.NavMoveScoringItems && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0; | ||||
|             const int off_min = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0; | ||||
|             const int off_max = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0; | ||||
|             data->Ranges.push_back(ImGuiListClipperRange::FromPositions(window->ClipRect.Min.y, window->ClipRect.Max.y, off_min, off_max)); | ||||
|         } | ||||
|  | ||||
| @@ -3226,7 +3232,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) | ||||
|     if (id) | ||||
|     { | ||||
|         g.ActiveIdIsAlive = id; | ||||
|         g.ActiveIdSource = (g.NavActivateId == id || g.NavActivateInputId == id || g.NavJustTabbedId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse; | ||||
|         g.ActiveIdSource = (g.NavActivateId == id || g.NavActivateInputId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse; | ||||
|     } | ||||
|  | ||||
|     // Clear declaration of inputs claimed by the widget | ||||
| @@ -3431,48 +3437,6 @@ void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemS | ||||
|     g.LastItemData.Rect = item_rect; | ||||
| } | ||||
|  | ||||
| // Called by ItemAdd() | ||||
| // Process TAB/Shift+TAB. Be mindful that this function may _clear_ the ActiveID when tabbing out. | ||||
| // [WIP] This will eventually be refactored and moved into NavProcessItem() | ||||
| void ImGui::ItemInputable(ImGuiWindow* window, ImGuiID id) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     IM_ASSERT(id != 0 && id == g.LastItemData.ID); | ||||
|  | ||||
|     // Increment counters | ||||
|     // FIXME: ImGuiItemFlags_Disabled should disable more. | ||||
|     const bool is_tab_stop = (g.LastItemData.InFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0; | ||||
|     if (is_tab_stop) | ||||
|     { | ||||
|         window->DC.FocusCounterTabStop++; | ||||
|         if (g.NavId == id) | ||||
|             g.NavIdTabCounter = window->DC.FocusCounterTabStop; | ||||
|     } | ||||
|  | ||||
|     // Process TAB/Shift-TAB to tab *OUT* of the currently focused item. | ||||
|     // (Note that we can always TAB out of a widget that doesn't allow tabbing in) | ||||
|     if (g.ActiveId == id && g.TabFocusPressed && g.TabFocusRequestNextWindow == NULL) | ||||
|     { | ||||
|         g.TabFocusRequestNextWindow = window; | ||||
|         g.TabFocusRequestNextCounterTabStop = window->DC.FocusCounterTabStop + (g.IO.KeyShift ? (is_tab_stop ? -1 : 0) : +1); // Modulo on index will be applied at the end of frame once we've got the total counter of items. | ||||
|     } | ||||
|  | ||||
|     // Handle focus requests | ||||
|     if (g.TabFocusRequestCurrWindow == window) | ||||
|     { | ||||
|         if (is_tab_stop && window->DC.FocusCounterTabStop == g.TabFocusRequestCurrCounterTabStop) | ||||
|         { | ||||
|             g.NavJustTabbedId = id; // FIXME-NAV: aim to eventually set in NavUpdate() once we finish the refactor | ||||
|             g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_FocusedByTabbing; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // If another item is about to be focused, we clear our own active id | ||||
|         if (g.ActiveId == id) | ||||
|             ClearActiveID(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) | ||||
| { | ||||
|     if (wrap_pos_x < 0.0f) | ||||
| @@ -4046,44 +4010,6 @@ void ImGui::UpdateMouseWheel() | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImGui::UpdateTabFocus() | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|  | ||||
|     // Pressing TAB activate widget focus | ||||
|     g.TabFocusPressed = false; | ||||
|     if (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) | ||||
|         if (!g.IO.KeyCtrl && !g.IO.KeyAlt && IsKeyPressedMap(ImGuiKey_Tab) && !IsActiveIdUsingKey(ImGuiKey_Tab)) | ||||
|             g.TabFocusPressed = true; | ||||
|     if (g.ActiveId == 0 && g.TabFocusPressed) | ||||
|     { | ||||
|         // - This path is only taken when no widget are active/tabbed-into yet. | ||||
|         //   Subsequent tabbing will be processed by FocusableItemRegister() | ||||
|         // - Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also | ||||
|         //   manipulate the Next fields here even though they will be turned into Curr fields below. | ||||
|         g.TabFocusRequestNextWindow = g.NavWindow; | ||||
|         if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX) | ||||
|             g.TabFocusRequestNextCounterTabStop = g.NavIdTabCounter + (g.IO.KeyShift ? -1 : 0); | ||||
|         else | ||||
|             g.TabFocusRequestNextCounterTabStop = g.IO.KeyShift ? -1 : 0; | ||||
|     } | ||||
|  | ||||
|     // Turn queued focus request into current one | ||||
|     g.TabFocusRequestCurrWindow = NULL; | ||||
|     g.TabFocusRequestCurrCounterTabStop = INT_MAX; | ||||
|     if (g.TabFocusRequestNextWindow != NULL) | ||||
|     { | ||||
|         ImGuiWindow* window = g.TabFocusRequestNextWindow; | ||||
|         g.TabFocusRequestCurrWindow = window; | ||||
|         if (g.TabFocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1) | ||||
|             g.TabFocusRequestCurrCounterTabStop = ImModPositive(g.TabFocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1); | ||||
|         g.TabFocusRequestNextWindow = NULL; | ||||
|         g.TabFocusRequestNextCounterTabStop = INT_MAX; | ||||
|     } | ||||
|  | ||||
|     g.NavIdTabCounter = INT_MAX; | ||||
| } | ||||
|  | ||||
| // The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app) | ||||
| void ImGui::UpdateHoveredWindowAndCaptureFlags() | ||||
| { | ||||
| @@ -4339,9 +4265,6 @@ void ImGui::NewFrame() | ||||
|     // Mouse wheel scrolling, scale | ||||
|     UpdateMouseWheel(); | ||||
|  | ||||
|     // Update legacy TAB focus | ||||
|     UpdateTabFocus(); | ||||
|  | ||||
|     // Mark all windows as not visible and compact unused memory. | ||||
|     IM_ASSERT(g.WindowsFocusOrder.Size <= g.Windows.Size); | ||||
|     const float memory_compact_start_time = (g.GcCompactAll || g.IO.ConfigMemoryCompactTimer < 0.0f) ? FLT_MAX : (float)g.Time - g.IO.ConfigMemoryCompactTimer; | ||||
| @@ -6874,7 +6797,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) | ||||
|         window->DC.CurrentColumns = NULL; | ||||
|         window->DC.LayoutType = ImGuiLayoutType_Vertical; | ||||
|         window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical; | ||||
|         window->DC.FocusCounterTabStop = -1; | ||||
|  | ||||
|         window->DC.ItemWidth = window->ItemWidthDefault; | ||||
|         window->DC.TextWrapPos = -1.0f; // disabled | ||||
| @@ -7780,11 +7702,16 @@ void ImGui::SetKeyboardFocusHere(int offset) | ||||
|     IM_ASSERT(offset >= -1);    // -1 is allowed but not below | ||||
|     g.NavWindow = window; | ||||
|     ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; | ||||
|     NavMoveRequestSubmit(ImGuiDir_None, ImGuiDir_None, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. | ||||
|     NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. | ||||
|     if (offset == -1) | ||||
|         NavMoveRequestResolveWithLastItem(); | ||||
|     { | ||||
|         NavMoveRequestResolveWithLastItem(&g.NavMoveResultLocal); | ||||
|     } | ||||
|     else | ||||
|         g.NavTabbingInputableRemaining = offset + 1; | ||||
|     { | ||||
|         g.NavTabbingDir = 1; | ||||
|         g.NavTabbingCounter = offset + 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImGui::SetItemDefaultFocus() | ||||
| @@ -8306,11 +8233,6 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu | ||||
|         return false; | ||||
|     //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] | ||||
|  | ||||
|     // [WIP] Tab stop handling (previously was using internal FocusableItemRegister() api) | ||||
|     // FIXME-NAV: We would now want to move this before the clipping test, but this would require being able to scroll and currently this would mean an extra frame. (#4079, #343) | ||||
|     if (extra_flags & ImGuiItemFlags_Inputable) | ||||
|         ItemInputable(window, id); | ||||
|  | ||||
|     // We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them) | ||||
|     if (IsMouseHoveringRect(bb.Min, bb.Max)) | ||||
|         g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect; | ||||
| @@ -9762,19 +9684,17 @@ static void ImGui::NavProcessItem() | ||||
|     // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRect + scoring from a rect wrapped according to current wrapping policy) | ||||
|     if (g.NavMoveScoringItems) | ||||
|     { | ||||
|         if (item_flags & ImGuiItemFlags_Inputable) | ||||
|             g.NavTabbingInputableRemaining--; | ||||
|  | ||||
|         if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNav))) | ||||
|         const bool is_tab_stop = (item_flags & ImGuiItemFlags_Inputable) && (item_flags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0; | ||||
|         const bool is_tabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) != 0; | ||||
|         if (is_tabbing) | ||||
|         { | ||||
|             if (is_tab_stop || (g.NavMoveFlags & ImGuiNavMoveFlags_FocusApi)) | ||||
|                 NavProcessItemForTabbingRequest(window, id); | ||||
|         } | ||||
|         else if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNav))) | ||||
|         { | ||||
|             ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; | ||||
|  | ||||
|             if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) | ||||
|             { | ||||
|                 if (g.NavTabbingInputableRemaining == 0) | ||||
|                     NavMoveRequestResolveWithLastItem(); | ||||
|             } | ||||
|             else | ||||
|             if (!is_tabbing) | ||||
|             { | ||||
|                 if (NavScoreItem(result)) | ||||
|                     NavApplyItemToResult(result); | ||||
| @@ -9800,6 +9720,52 @@ static void ImGui::NavProcessItem() | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Handle "scoring" of an item for a tabbing/focusing request initiated by NavUpdateCreateTabbingRequest(). | ||||
| // Note that SetKeyboardFocusHere() API calls are considered tabbing requests! | ||||
| // - Case 1: no nav/active id:    set result to first eligible item, stop storing. | ||||
| // - Case 2: tab forward:         on ref id set counter, on counter elapse store result | ||||
| // - Case 3: tab forward wrap:    set result to first eligible item (preemptively), on ref id set counter, on next frame if counter hasn't elapsed store result. // FIXME-TABBING: Could be done as a next-frame forwarded request | ||||
| // - Case 4: tab backward:        store all results, on ref id pick prev, stop storing | ||||
| // - Case 5: tab backward wrap:   store all results, on ref id if no result keep storing until last // FIXME-TABBING: Could be done as next-frame forwarded requested | ||||
| void ImGui::NavProcessItemForTabbingRequest(ImGuiWindow* window, ImGuiID id) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|  | ||||
|     ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; | ||||
|     if (g.NavTabbingDir == +1) | ||||
|     { | ||||
|         // Tab Forward or SetKeyboardFocusHere() with >= 0 | ||||
|         if (g.NavTabbingResultFirst.ID == 0) | ||||
|             NavApplyItemToResult(&g.NavTabbingResultFirst); | ||||
|         if (--g.NavTabbingCounter == 0) | ||||
|             NavMoveRequestResolveWithLastItem(result); | ||||
|         else if (g.NavId == id) | ||||
|             g.NavTabbingCounter = 1; | ||||
|     } | ||||
|     else if (g.NavTabbingDir == -1) | ||||
|     { | ||||
|         // Tab Backward | ||||
|         if (g.NavId == id) | ||||
|         { | ||||
|             if (result->ID) | ||||
|             { | ||||
|                 g.NavMoveScoringItems = false; | ||||
|                 NavUpdateAnyRequestFlag(); | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             NavApplyItemToResult(result); | ||||
|         } | ||||
|     } | ||||
|     else if (g.NavTabbingDir == 0) | ||||
|     { | ||||
|         // Tab Init | ||||
|         if (g.NavTabbingResultFirst.ID == 0) | ||||
|             NavMoveRequestResolveWithLastItem(&g.NavTabbingResultFirst); | ||||
|     } | ||||
| } | ||||
|  | ||||
| bool ImGui::NavMoveRequestButNoResultYet() | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
| @@ -9823,18 +9789,18 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM | ||||
|     g.NavMoveScrollFlags = scroll_flags; | ||||
|     g.NavMoveForwardToNextFrame = false; | ||||
|     g.NavMoveKeyMods = g.IO.KeyMods; | ||||
|     g.NavTabbingInputableRemaining = 0; | ||||
|     g.NavTabbingCounter = 0; | ||||
|     g.NavMoveResultLocal.Clear(); | ||||
|     g.NavMoveResultLocalVisible.Clear(); | ||||
|     g.NavMoveResultOther.Clear(); | ||||
|     NavUpdateAnyRequestFlag(); | ||||
| } | ||||
|  | ||||
| void ImGui::NavMoveRequestResolveWithLastItem() | ||||
| void ImGui::NavMoveRequestResolveWithLastItem(ImGuiNavItemData* result) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     g.NavMoveScoringItems = false; // Ensure request doesn't need more processing | ||||
|     NavApplyItemToResult(&g.NavMoveResultLocal); | ||||
|     NavApplyItemToResult(result); | ||||
|     NavUpdateAnyRequestFlag(); | ||||
| } | ||||
|  | ||||
| @@ -10073,7 +10039,7 @@ static void ImGui::NavUpdate() | ||||
|     // Process navigation move request | ||||
|     if (g.NavMoveSubmitted) | ||||
|         NavMoveRequestApplyResult(); | ||||
|     g.NavTabbingInputableRemaining = 0; | ||||
|     g.NavTabbingCounter = 0; | ||||
|     g.NavMoveSubmitted = g.NavMoveScoringItems = false; | ||||
|  | ||||
|     // Schedule mouse position update (will be done at the bottom of this function, after 1) processing all move requests and 2) updating scrolling) | ||||
| @@ -10082,8 +10048,6 @@ static void ImGui::NavUpdate() | ||||
|         if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow) | ||||
|             set_mouse_pos = true; | ||||
|     g.NavMousePosDirty = false; | ||||
|     g.NavIdIsAlive = false; | ||||
|     g.NavJustTabbedId = 0; | ||||
|     IM_ASSERT(g.NavLayer == ImGuiNavLayer_Main || g.NavLayer == ImGuiNavLayer_Menu); | ||||
|  | ||||
|     // Store our return window (for returning from Menu Layer to Main Layer) and clear it as soon as we step back in our own Layer 0 | ||||
| @@ -10145,7 +10109,10 @@ static void ImGui::NavUpdate() | ||||
|  | ||||
|     // Process move requests | ||||
|     NavUpdateCreateMoveRequest(); | ||||
|     if (g.NavMoveDir == ImGuiDir_None) | ||||
|         NavUpdateCreateTabbingRequest(); | ||||
|     NavUpdateAnyRequestFlag(); | ||||
|     g.NavIdIsAlive = false; | ||||
|  | ||||
|     // Scrolling | ||||
|     if (g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.NavWindowingTarget) | ||||
| @@ -10317,6 +10284,31 @@ void ImGui::NavUpdateCreateMoveRequest() | ||||
|     g.NavScoringNoClipRect.Add(scoring_rect); | ||||
| } | ||||
|  | ||||
| void ImGui::NavUpdateCreateTabbingRequest() | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.NavWindow; | ||||
|     IM_ASSERT(g.NavMoveDir == ImGuiDir_None); | ||||
|     if (window == NULL || g.NavWindowingTarget != NULL || (window->Flags & ImGuiWindowFlags_NoNavInputs)) | ||||
|         return; | ||||
|  | ||||
|     const bool tab_pressed = IsKeyPressedMap(ImGuiKey_Tab, true) && !IsActiveIdUsingKey(ImGuiKey_Tab) && !g.IO.KeyCtrl && !g.IO.KeyAlt; | ||||
|     if (!tab_pressed) | ||||
|         return; | ||||
|  | ||||
|     // Initiate tabbing request | ||||
|     // (this is ALWAYS ENABLED, regardless of ImGuiConfigFlags_NavEnableKeyboard flag!) | ||||
|     // Initially this was designed to use counters and modulo arithmetic, but that could not work with unsubmitted items (list clipper). Instead we use a strategy close to other move requests. | ||||
|     // See NavProcessItemForTabbingRequest() for a description of the various forward/backward tabbing cases with and without wrapping. | ||||
|     //// FIXME: We use (g.ActiveId == 0) but (g.NavDisableHighlight == false) might be righter once we can tab through anything | ||||
|     g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.ActiveId == 0) ? 0 : +1; | ||||
|     ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; | ||||
|     ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down; | ||||
|     NavMoveRequestSubmit(ImGuiDir_None, clip_dir, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. | ||||
|     g.NavTabbingResultFirst.Clear(); | ||||
|     g.NavTabbingCounter = -1; | ||||
| } | ||||
|  | ||||
| // Apply result from previous frame navigation directional move request. Always called from NavUpdate() | ||||
| void ImGui::NavMoveRequestApplyResult() | ||||
| { | ||||
| @@ -10329,6 +10321,14 @@ void ImGui::NavMoveRequestApplyResult() | ||||
|     // Select which result to use | ||||
|     ImGuiNavItemData* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : (g.NavMoveResultOther.ID != 0) ? &g.NavMoveResultOther : NULL; | ||||
|  | ||||
|     // Tabbing forward wrap | ||||
|     if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) | ||||
|         if (g.NavTabbingCounter == 1 || g.NavTabbingDir == 0) | ||||
|         { | ||||
|             IM_ASSERT(g.NavTabbingResultFirst.ID != 0); | ||||
|             result = &g.NavTabbingResultFirst; | ||||
|         } | ||||
|  | ||||
|     // 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) | ||||
|     if (result == NULL) | ||||
|     { | ||||
| @@ -10366,8 +10366,9 @@ void ImGui::NavMoveRequestApplyResult() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ClearActiveID(); | ||||
|     g.NavWindow = result->Window; | ||||
|     if (g.ActiveId != result->ID) | ||||
|         ClearActiveID(); | ||||
|     if (g.NavId != result->ID) | ||||
|     { | ||||
|         // Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId) | ||||
| @@ -17746,7 +17747,7 @@ void ImGui::UpdateDebugToolStackQueries() | ||||
|  | ||||
|     // Update queries. The steps are: -1: query Stack, >= 0: query each stack item | ||||
|     // We can only perform 1 ID Info query every frame. This is designed so the GetID() tests are cheap and constant-time | ||||
|     const ImGuiID query_id = g.ActiveId ? g.ActiveId : g.HoveredIdPreviousFrame; | ||||
|     const ImGuiID query_id = g.HoveredIdPreviousFrame ? g.HoveredIdPreviousFrame : g.ActiveId; | ||||
|     if (tool->QueryId != query_id) | ||||
|     { | ||||
|         tool->QueryId = query_id; | ||||
|   | ||||
							
								
								
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -65,7 +65,7 @@ Index of this file: | ||||
| // Version | ||||
| // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) | ||||
| #define IMGUI_VERSION               "1.86 WIP" | ||||
| #define IMGUI_VERSION_NUM           18506 | ||||
| #define IMGUI_VERSION_NUM           18508 | ||||
| #define IMGUI_CHECKVERSION()        ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) | ||||
| #define IMGUI_HAS_TABLE | ||||
| #define IMGUI_HAS_VIEWPORT          // Viewport WIP branch | ||||
|   | ||||
| @@ -1267,9 +1267,10 @@ enum ImGuiNavMoveFlags_ | ||||
|     ImGuiNavMoveFlags_ScrollToEdgeY         = 1 << 6,   // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary | ||||
|     ImGuiNavMoveFlags_Forwarded             = 1 << 7, | ||||
|     ImGuiNavMoveFlags_DebugNoResult         = 1 << 8,   // Dummy scoring for debug purpose, don't apply result | ||||
|     ImGuiNavMoveFlags_Tabbing               = 1 << 9,   // == Focus + Activate if item is Inputable + DontChangeNavHighlight | ||||
|     ImGuiNavMoveFlags_Activate              = 1 << 10, | ||||
|     ImGuiNavMoveFlags_DontSetNavHighlight   = 1 << 11   // Do not alter the visible state of keyboard vs mouse nav highlight | ||||
|     ImGuiNavMoveFlags_FocusApi              = 1 << 9, | ||||
|     ImGuiNavMoveFlags_Tabbing               = 1 << 10,  // == Focus + Activate if item is Inputable + DontChangeNavHighlight | ||||
|     ImGuiNavMoveFlags_Activate              = 1 << 11, | ||||
|     ImGuiNavMoveFlags_DontSetNavHighlight   = 1 << 12   // Do not alter the visible state of keyboard vs mouse nav highlight | ||||
| }; | ||||
|  | ||||
| enum ImGuiNavLayer | ||||
| @@ -1766,7 +1767,6 @@ struct ImGuiContext | ||||
|     ImGuiID                 NavActivatePressedId;               // ~~ IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0 | ||||
|     ImGuiID                 NavActivateInputId;                 // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0; ImGuiActivateFlags_PreferInput will be set and NavActivateId will be 0. | ||||
|     ImGuiActivateFlags      NavActivateFlags; | ||||
|     ImGuiID                 NavJustTabbedId;                    // Just tabbed to this id. | ||||
|     ImGuiID                 NavJustMovedToId;                   // Just navigated to this id (result of a successfully MoveRequest). | ||||
|     ImGuiID                 NavJustMovedToFocusScopeId;         // Just navigated to this focus scope id (result of a successfully MoveRequest). | ||||
|     ImGuiKeyModFlags        NavJustMovedToKeyMods; | ||||
| @@ -1774,7 +1774,6 @@ struct ImGuiContext | ||||
|     ImGuiActivateFlags      NavNextActivateFlags; | ||||
|     ImGuiInputSource        NavInputSource;                     // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard. | ||||
|     ImGuiNavLayer           NavLayer;                           // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. | ||||
|     int                     NavIdTabCounter;                    // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing | ||||
|     bool                    NavIdIsAlive;                       // Nav widget has been seen this frame ~~ NavRectRel is valid | ||||
|     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) | ||||
| @@ -1798,10 +1797,12 @@ struct ImGuiContext | ||||
|     ImRect                  NavScoringRect;                     // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring. | ||||
|     ImRect                  NavScoringNoClipRect;               // Some nav operations (such as PageUp/PageDown) enforce a region which clipper will attempt to always keep submitted | ||||
|     int                     NavScoringDebugCount;               // Metrics for debugging | ||||
|     int                     NavTabbingInputableRemaining;       // >0 when counting items for tabbing | ||||
|     int                     NavTabbingDir;                      // Generally -1 or +1, 0 when tabbing without a nav id | ||||
|     int                     NavTabbingCounter;                  // >0 when counting items for tabbing | ||||
|     ImGuiNavItemData        NavMoveResultLocal;                 // Best move request candidate within NavWindow | ||||
|     ImGuiNavItemData        NavMoveResultLocalVisible;          // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag) | ||||
|     ImGuiNavItemData        NavMoveResultOther;                 // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) | ||||
|     ImGuiNavItemData        NavTabbingResultFirst;              // First tabbing request candidate within NavWindow and flattened hierarchy | ||||
|  | ||||
|     // Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize) | ||||
|     ImGuiWindow*            NavWindowingTarget;                 // Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most! | ||||
| @@ -1811,13 +1812,6 @@ struct ImGuiContext | ||||
|     float                   NavWindowingHighlightAlpha; | ||||
|     bool                    NavWindowingToggleLayer; | ||||
|  | ||||
|     // Legacy Focus/Tabbing system (older than Nav, active even if Nav is disabled, misnamed. FIXME-NAV: This needs a redesign!) | ||||
|     ImGuiWindow*            TabFocusRequestCurrWindow;          // | ||||
|     ImGuiWindow*            TabFocusRequestNextWindow;          // | ||||
|     int                     TabFocusRequestCurrCounterTabStop;  // Tab item being requested for focus, stored as an index | ||||
|     int                     TabFocusRequestNextCounterTabStop;  // " | ||||
|     bool                    TabFocusPressed;                    // Set in NewFrame() when user pressed Tab | ||||
|  | ||||
|     // Render | ||||
|     float                   DimBgRatio;                         // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list) | ||||
|     ImGuiMouseCursor        MouseCursor; | ||||
| @@ -1997,12 +1991,11 @@ struct ImGuiContext | ||||
|  | ||||
|         NavWindow = NULL; | ||||
|         NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavActivateInputId = 0; | ||||
|         NavJustTabbedId = NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0; | ||||
|         NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0; | ||||
|         NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None; | ||||
|         NavJustMovedToKeyMods = ImGuiKeyModFlags_None; | ||||
|         NavInputSource = ImGuiInputSource_None; | ||||
|         NavLayer = ImGuiNavLayer_Main; | ||||
|         NavIdTabCounter = INT_MAX; | ||||
|         NavIdIsAlive = false; | ||||
|         NavMousePosDirty = false; | ||||
|         NavDisableHighlight = true; | ||||
| @@ -2019,17 +2012,13 @@ struct ImGuiContext | ||||
|         NavMoveKeyMods = ImGuiKeyModFlags_None; | ||||
|         NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = ImGuiDir_None; | ||||
|         NavScoringDebugCount = 0; | ||||
|         NavTabbingInputableRemaining = 0; | ||||
|         NavTabbingDir = 0; | ||||
|         NavTabbingCounter = 0; | ||||
|  | ||||
|         NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL; | ||||
|         NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; | ||||
|         NavWindowingToggleLayer = false; | ||||
|  | ||||
|         TabFocusRequestCurrWindow = TabFocusRequestNextWindow = NULL; | ||||
|         TabFocusRequestCurrCounterTabStop = INT_MAX; | ||||
|         TabFocusRequestNextCounterTabStop = INT_MAX; | ||||
|         TabFocusPressed = false; | ||||
|  | ||||
|         DimBgRatio = 0.0f; | ||||
|         MouseCursor = ImGuiMouseCursor_Arrow; | ||||
|  | ||||
| @@ -2137,7 +2126,6 @@ struct IMGUI_API ImGuiWindowTempData | ||||
|     int                     CurrentTableIdx;        // Current table index (into g.Tables) | ||||
|     ImGuiLayoutType         LayoutType; | ||||
|     ImGuiLayoutType         ParentLayoutType;       // Layout type of parent window at the time of Begin() | ||||
|     int                     FocusCounterTabStop;    // (Legacy Focus/Tabbing system) Same, but only count widgets which you can Tab through. | ||||
|  | ||||
|     // Local parameters stacks | ||||
|     // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. | ||||
| @@ -2733,7 +2721,6 @@ namespace ImGui | ||||
|     IMGUI_API void          ItemSize(const ImRect& bb, float text_baseline_y = -1.0f); | ||||
|     IMGUI_API bool          ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemFlags extra_flags = 0); | ||||
|     IMGUI_API bool          ItemHoverable(const ImRect& bb, ImGuiID id); | ||||
|     IMGUI_API void          ItemInputable(ImGuiWindow* window, ImGuiID id); | ||||
|     IMGUI_API bool          IsClippedEx(const ImRect& bb, ImGuiID id); | ||||
|     IMGUI_API void          SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect); | ||||
|     IMGUI_API ImVec2        CalcItemSize(ImVec2 size, float default_w, float default_h); | ||||
| @@ -2794,7 +2781,7 @@ namespace ImGui | ||||
|     IMGUI_API bool          NavMoveRequestButNoResultYet(); | ||||
|     IMGUI_API void          NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags); | ||||
|     IMGUI_API void          NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags); | ||||
|     IMGUI_API void          NavMoveRequestResolveWithLastItem(); | ||||
|     IMGUI_API void          NavMoveRequestResolveWithLastItem(ImGuiNavItemData* result); | ||||
|     IMGUI_API void          NavMoveRequestCancel(); | ||||
|     IMGUI_API void          NavMoveRequestApplyResult(); | ||||
|     IMGUI_API void          NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user