mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-11-04 01:34:32 +00:00 
			
		
		
		
	Nav: refactor SetKeyboardFocusHere() into using Nav facility. Fix it for clipped items. (#343, #4079, #2352, #432)
+ Removed references to counter used by previous implementation of SetKeyboardFocus functions (the TabStop ones will be removed after)
This commit is contained in:
		@@ -57,6 +57,13 @@ Other Changes:
 | 
			
		||||
- TextUnformatted: Accept null ranges including (NULL,NULL) without asserting, in order to conform
 | 
			
		||||
  to common idioms (e.g. passing .data(), .data() + .size() from a null string). (#3615)
 | 
			
		||||
- Disabled: Added assert guard for mismatching BeginDisabled()/EndDisabled() blocks. (#211)
 | 
			
		||||
- Nav: Fixed using SetKeyboardFocusHere() on non-visible/clipped items. It now works and will scroll
 | 
			
		||||
  toward the item. When called during a frame where the parent window is appearing, scrolling will
 | 
			
		||||
  aim to center the item in the window. When calling during a frame where the parent window is already
 | 
			
		||||
  visible, scrolling will aim to scroll as little as possible to make the item visible. We will later
 | 
			
		||||
  expose scroll functions and flags in public API to select those behaviors. (#343, #4079, #2352)
 | 
			
		||||
- Nav: Fixed using SetKeyboardFocusHere() from activating a different item on the next frame if
 | 
			
		||||
  submitted items have changed during that frame. (#432)
 | 
			
		||||
- Nav: Fixed toggling menu layer with Alt or exiting menu layer with Esc not moving mouse when
 | 
			
		||||
  the NavEnableSetMousePos config flag is set.
 | 
			
		||||
- Nav: Fixed a few widgets from not setting reference keyboard/gamepad navigation ID when
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										96
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -3303,7 +3303,6 @@ void ImGui::ItemInputable(ImGuiWindow* window, ImGuiID id)
 | 
			
		||||
    // Increment counters
 | 
			
		||||
    // FIXME: ImGuiItemFlags_Disabled should disable more.
 | 
			
		||||
    const bool is_tab_stop = (g.LastItemData.InFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0;
 | 
			
		||||
    window->DC.FocusCounterRegular++;
 | 
			
		||||
    if (is_tab_stop)
 | 
			
		||||
    {
 | 
			
		||||
        window->DC.FocusCounterTabStop++;
 | 
			
		||||
@@ -3322,11 +3321,6 @@ void ImGui::ItemInputable(ImGuiWindow* window, ImGuiID id)
 | 
			
		||||
    // Handle focus requests
 | 
			
		||||
    if (g.TabFocusRequestCurrWindow == window)
 | 
			
		||||
    {
 | 
			
		||||
        if (window->DC.FocusCounterRegular == g.TabFocusRequestCurrCounterRegular)
 | 
			
		||||
        {
 | 
			
		||||
            g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_FocusedByCode;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        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
 | 
			
		||||
@@ -3843,7 +3837,6 @@ void ImGui::UpdateTabFocus()
 | 
			
		||||
        // - 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;
 | 
			
		||||
        g.TabFocusRequestNextCounterRegular = INT_MAX;
 | 
			
		||||
        if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX)
 | 
			
		||||
            g.TabFocusRequestNextCounterTabStop = g.NavIdTabCounter + (g.IO.KeyShift ? -1 : 0);
 | 
			
		||||
        else
 | 
			
		||||
@@ -3852,17 +3845,15 @@ void ImGui::UpdateTabFocus()
 | 
			
		||||
 | 
			
		||||
    // Turn queued focus request into current one
 | 
			
		||||
    g.TabFocusRequestCurrWindow = NULL;
 | 
			
		||||
    g.TabFocusRequestCurrCounterRegular = g.TabFocusRequestCurrCounterTabStop = INT_MAX;
 | 
			
		||||
    g.TabFocusRequestCurrCounterTabStop = INT_MAX;
 | 
			
		||||
    if (g.TabFocusRequestNextWindow != NULL)
 | 
			
		||||
    {
 | 
			
		||||
        ImGuiWindow* window = g.TabFocusRequestNextWindow;
 | 
			
		||||
        g.TabFocusRequestCurrWindow = window;
 | 
			
		||||
        if (g.TabFocusRequestNextCounterRegular != INT_MAX && window->DC.FocusCounterRegular != -1)
 | 
			
		||||
            g.TabFocusRequestCurrCounterRegular = ImModPositive(g.TabFocusRequestNextCounterRegular, window->DC.FocusCounterRegular + 1);
 | 
			
		||||
        if (g.TabFocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1)
 | 
			
		||||
            g.TabFocusRequestCurrCounterTabStop = ImModPositive(g.TabFocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1);
 | 
			
		||||
        g.TabFocusRequestNextWindow = NULL;
 | 
			
		||||
        g.TabFocusRequestNextCounterRegular = g.TabFocusRequestNextCounterTabStop = INT_MAX;
 | 
			
		||||
        g.TabFocusRequestNextCounterTabStop = INT_MAX;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    g.NavIdTabCounter = INT_MAX;
 | 
			
		||||
@@ -6316,7 +6307,7 @@ 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.FocusCounterRegular = window->DC.FocusCounterTabStop = -1;
 | 
			
		||||
        window->DC.FocusCounterTabStop = -1;
 | 
			
		||||
 | 
			
		||||
        window->DC.ItemWidth = window->ItemWidthDefault;
 | 
			
		||||
        window->DC.TextWrapPos = -1.0f; // disabled
 | 
			
		||||
@@ -7082,12 +7073,16 @@ void ImGui::PopFocusScope()
 | 
			
		||||
 | 
			
		||||
void ImGui::SetKeyboardFocusHere(int offset)
 | 
			
		||||
{
 | 
			
		||||
    IM_ASSERT(offset >= -1);    // -1 is allowed but not below
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    ImGuiWindow* window = g.CurrentWindow;
 | 
			
		||||
    g.TabFocusRequestNextWindow = window;
 | 
			
		||||
    g.TabFocusRequestNextCounterRegular = window->DC.FocusCounterRegular + 1 + offset;
 | 
			
		||||
    g.TabFocusRequestNextCounterTabStop = INT_MAX;
 | 
			
		||||
    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.
 | 
			
		||||
    if (offset == -1)
 | 
			
		||||
        NavMoveRequestResolveWithLastItem();
 | 
			
		||||
    else
 | 
			
		||||
        g.NavTabbingInputableRemaining = offset + 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImGui::SetItemDefaultFocus()
 | 
			
		||||
@@ -8980,6 +8975,7 @@ static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result)
 | 
			
		||||
    result->Window = window;
 | 
			
		||||
    result->ID = g.LastItemData.ID;
 | 
			
		||||
    result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
 | 
			
		||||
    result->InFlags = g.LastItemData.InFlags;
 | 
			
		||||
    result->RectRel = ImRect(g.LastItemData.NavRect.Min - window->Pos, g.LastItemData.NavRect.Max - window->Pos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -9014,18 +9010,30 @@ 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)))
 | 
			
		||||
        {
 | 
			
		||||
            ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
 | 
			
		||||
            if (NavScoreItem(result))
 | 
			
		||||
                NavApplyItemToResult(result);
 | 
			
		||||
 | 
			
		||||
            // Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
 | 
			
		||||
            const float VISIBLE_RATIO = 0.70f;
 | 
			
		||||
            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 (NavScoreItem(&g.NavMoveResultLocalVisible))
 | 
			
		||||
                        NavApplyItemToResult(&g.NavMoveResultLocalVisible);
 | 
			
		||||
            if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing)
 | 
			
		||||
            {
 | 
			
		||||
                if (g.NavTabbingInputableRemaining == 0)
 | 
			
		||||
                    NavMoveRequestResolveWithLastItem();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (NavScoreItem(result))
 | 
			
		||||
                    NavApplyItemToResult(result);
 | 
			
		||||
 | 
			
		||||
                // Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
 | 
			
		||||
                const float VISIBLE_RATIO = 0.70f;
 | 
			
		||||
                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 (NavScoreItem(&g.NavMoveResultLocalVisible))
 | 
			
		||||
                            NavApplyItemToResult(&g.NavMoveResultLocalVisible);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -9051,6 +9059,10 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    IM_ASSERT(g.NavWindow != NULL);
 | 
			
		||||
 | 
			
		||||
    if (move_flags & ImGuiNavMoveFlags_Tabbing)
 | 
			
		||||
        move_flags |= ImGuiNavMoveFlags_AllowCurrentNavId;
 | 
			
		||||
 | 
			
		||||
    g.NavMoveSubmitted = g.NavMoveScoringItems = true;
 | 
			
		||||
    g.NavMoveDir = move_dir;
 | 
			
		||||
    g.NavMoveDirForDebug = move_dir;
 | 
			
		||||
@@ -9059,12 +9071,21 @@ 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.NavMoveResultLocal.Clear();
 | 
			
		||||
    g.NavMoveResultLocalVisible.Clear();
 | 
			
		||||
    g.NavMoveResultOther.Clear();
 | 
			
		||||
    NavUpdateAnyRequestFlag();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImGui::NavMoveRequestResolveWithLastItem()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    g.NavMoveScoringItems = false; // Ensure request doesn't need more processing
 | 
			
		||||
    NavApplyItemToResult(&g.NavMoveResultLocal);
 | 
			
		||||
    NavUpdateAnyRequestFlag();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ImGui::NavMoveRequestCancel()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
@@ -9284,6 +9305,7 @@ static void ImGui::NavUpdate()
 | 
			
		||||
    // Process navigation move request
 | 
			
		||||
    if (g.NavMoveSubmitted)
 | 
			
		||||
        NavMoveRequestApplyResult();
 | 
			
		||||
    g.NavTabbingInputableRemaining = 0;
 | 
			
		||||
    g.NavMoveSubmitted = g.NavMoveScoringItems = false;
 | 
			
		||||
 | 
			
		||||
    // Apply application mouse position movement, after we had a chance to process move request result.
 | 
			
		||||
@@ -9535,7 +9557,9 @@ void ImGui::NavMoveRequestApplyResult()
 | 
			
		||||
    // 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)
 | 
			
		||||
    {
 | 
			
		||||
        if (g.NavId != 0)
 | 
			
		||||
        if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing)
 | 
			
		||||
            g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight;
 | 
			
		||||
        if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            g.NavDisableHighlight = false;
 | 
			
		||||
            g.NavDisableMouseHover = true;
 | 
			
		||||
@@ -9590,9 +9614,27 @@ void ImGui::NavMoveRequestApplyResult()
 | 
			
		||||
    IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name);
 | 
			
		||||
    SetNavID(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel);
 | 
			
		||||
 | 
			
		||||
    // Tabbing: Activates Inputable or Focus non-Inputable
 | 
			
		||||
    if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && (result->InFlags & ImGuiItemFlags_Inputable))
 | 
			
		||||
    {
 | 
			
		||||
        g.NavNextActivateId = result->ID;
 | 
			
		||||
        g.NavNextActivateFlags = ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState;
 | 
			
		||||
        g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Activate
 | 
			
		||||
    if (g.NavMoveFlags & ImGuiNavMoveFlags_Activate)
 | 
			
		||||
    {
 | 
			
		||||
        g.NavNextActivateId = result->ID;
 | 
			
		||||
        g.NavNextActivateFlags = ImGuiActivateFlags_None;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Enable nav highlight
 | 
			
		||||
    g.NavDisableHighlight = false;
 | 
			
		||||
    g.NavDisableMouseHover = g.NavMousePosDirty = true;
 | 
			
		||||
    if ((g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0)
 | 
			
		||||
    {
 | 
			
		||||
        g.NavDisableHighlight = false;
 | 
			
		||||
        g.NavDisableMouseHover = g.NavMousePosDirty = true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Process NavCancel input (to close a popup, get back to parent, clear focus)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							@@ -64,7 +64,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.85 WIP"
 | 
			
		||||
#define IMGUI_VERSION_NUM           18419
 | 
			
		||||
#define IMGUI_VERSION_NUM           18420
 | 
			
		||||
#define IMGUI_CHECKVERSION()        ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
 | 
			
		||||
#define IMGUI_HAS_TABLE
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -759,9 +759,7 @@ enum ImGuiItemStatusFlags_
 | 
			
		||||
    ImGuiItemStatusFlags_HasDeactivated     = 1 << 5,   // Set if the widget/group is able to provide data for the ImGuiItemStatusFlags_Deactivated flag.
 | 
			
		||||
    ImGuiItemStatusFlags_Deactivated        = 1 << 6,   // Only valid if ImGuiItemStatusFlags_HasDeactivated is set.
 | 
			
		||||
    ImGuiItemStatusFlags_HoveredWindow      = 1 << 7,   // Override the HoveredWindow test to allow cross-window hover testing.
 | 
			
		||||
    ImGuiItemStatusFlags_FocusedByCode      = 1 << 8,   // Set when the Focusable item just got focused from code.
 | 
			
		||||
    ImGuiItemStatusFlags_FocusedByTabbing   = 1 << 9,   // Set when the Focusable item just got focused by Tabbing.
 | 
			
		||||
    ImGuiItemStatusFlags_Focused            = ImGuiItemStatusFlags_FocusedByCode | ImGuiItemStatusFlags_FocusedByTabbing
 | 
			
		||||
    ImGuiItemStatusFlags_FocusedByTabbing   = 1 << 8    // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon)
 | 
			
		||||
 | 
			
		||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
 | 
			
		||||
    , // [imgui_tests only]
 | 
			
		||||
@@ -1219,7 +1217,10 @@ enum ImGuiNavMoveFlags_
 | 
			
		||||
    ImGuiNavMoveFlags_AlsoScoreVisibleSet   = 1 << 5,   // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown)
 | 
			
		||||
    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
 | 
			
		||||
    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
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum ImGuiNavLayer
 | 
			
		||||
@@ -1235,12 +1236,13 @@ struct ImGuiNavItemData
 | 
			
		||||
    ImGuiID             ID;             // Init,Move    // Best candidate item ID
 | 
			
		||||
    ImGuiID             FocusScopeId;   // Init,Move    // Best candidate focus scope ID
 | 
			
		||||
    ImRect              RectRel;        // Init,Move    // Best candidate bounding box in window relative space
 | 
			
		||||
    ImGuiItemFlags      InFlags;        // ????,Move    // Best candidate item flags
 | 
			
		||||
    float               DistBox;        //      Move    // Best candidate box distance to current NavId
 | 
			
		||||
    float               DistCenter;     //      Move    // Best candidate center distance to current NavId
 | 
			
		||||
    float               DistAxial;      //      Move    // Best candidate axial distance to current NavId
 | 
			
		||||
 | 
			
		||||
    ImGuiNavItemData()  { Clear(); }
 | 
			
		||||
    void Clear()        { Window = NULL; ID = FocusScopeId = 0; RectRel = ImRect(); DistBox = DistCenter = DistAxial = FLT_MAX; }
 | 
			
		||||
    void Clear()        { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; DistBox = DistCenter = DistAxial = FLT_MAX; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
@@ -1582,6 +1584,7 @@ struct ImGuiContext
 | 
			
		||||
    ImGuiDir                NavMoveClipDir;                     // FIXME-NAV: Describe the purpose of this better. Might want to rename?
 | 
			
		||||
    ImRect                  NavScoringRect;                     // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring.
 | 
			
		||||
    int                     NavScoringDebugCount;               // Metrics for debugging
 | 
			
		||||
    int                     NavTabbingInputableRemaining;       // >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)
 | 
			
		||||
@@ -1597,9 +1600,7 @@ struct ImGuiContext
 | 
			
		||||
    // 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                     TabFocusRequestCurrCounterRegular;  // Any item being requested for focus, stored as an index (we on layout to be stable between the frame pressing TAB and the next frame, semi-ouch)
 | 
			
		||||
    int                     TabFocusRequestCurrCounterTabStop;  // Tab item being requested for focus, stored as an index
 | 
			
		||||
    int                     TabFocusRequestNextCounterRegular;  // Stored for next frame
 | 
			
		||||
    int                     TabFocusRequestNextCounterTabStop;  // "
 | 
			
		||||
    bool                    TabFocusPressed;                    // Set in NewFrame() when user pressed Tab
 | 
			
		||||
 | 
			
		||||
@@ -1787,14 +1788,15 @@ struct ImGuiContext
 | 
			
		||||
        NavMoveKeyMods = ImGuiKeyModFlags_None;
 | 
			
		||||
        NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = ImGuiDir_None;
 | 
			
		||||
        NavScoringDebugCount = 0;
 | 
			
		||||
        NavTabbingInputableRemaining = 0;
 | 
			
		||||
 | 
			
		||||
        NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL;
 | 
			
		||||
        NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
 | 
			
		||||
        NavWindowingToggleLayer = false;
 | 
			
		||||
 | 
			
		||||
        TabFocusRequestCurrWindow = TabFocusRequestNextWindow = NULL;
 | 
			
		||||
        TabFocusRequestCurrCounterRegular = TabFocusRequestCurrCounterTabStop = INT_MAX;
 | 
			
		||||
        TabFocusRequestNextCounterRegular = TabFocusRequestNextCounterTabStop = INT_MAX;
 | 
			
		||||
        TabFocusRequestCurrCounterTabStop = INT_MAX;
 | 
			
		||||
        TabFocusRequestNextCounterTabStop = INT_MAX;
 | 
			
		||||
        TabFocusPressed = false;
 | 
			
		||||
 | 
			
		||||
        DimBgRatio = 0.0f;
 | 
			
		||||
@@ -1901,7 +1903,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                     FocusCounterRegular;    // (Legacy Focus/Tabbing system) Sequential counter, start at -1 and increase when ImGuiItemFlags_Inputable (FIXME-NAV: Needs redesign)
 | 
			
		||||
    int                     FocusCounterTabStop;    // (Legacy Focus/Tabbing system) Same, but only count widgets which you can Tab through.
 | 
			
		||||
 | 
			
		||||
    // Local parameters stacks
 | 
			
		||||
@@ -2478,9 +2479,9 @@ namespace ImGui
 | 
			
		||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
 | 
			
		||||
    // Currently refactoring focus/nav/tabbing system
 | 
			
		||||
    // If you have old/custom copy-and-pasted widgets that used FocusableItemRegister():
 | 
			
		||||
    //  (Old) IMGUI_VERSION_NUM  < 18209: using 'ItemAdd(....)'                              and 'bool focused = FocusableItemRegister(...)'
 | 
			
		||||
    //  (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)'  and 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0'
 | 
			
		||||
    //  (New) IMGUI_VERSION_NUM >= 18411: using 'ItemAdd(..., ImGuiItemAddFlags_Inputable)'  and 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0'
 | 
			
		||||
    //  (Old) IMGUI_VERSION_NUM  < 18209: using 'ItemAdd(....)'                              and 'bool tab_focused = FocusableItemRegister(...)'
 | 
			
		||||
    //  (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)'  and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0'
 | 
			
		||||
    //  (New) IMGUI_VERSION_NUM >= 18413: using 'ItemAdd(..., ImGuiItemFlags_Inputable)'     and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_FocusedTabbing) != 0 || g.NavActivateInputId == id' (WIP)
 | 
			
		||||
    // Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText()
 | 
			
		||||
    inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id)  { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd()
 | 
			
		||||
    inline void FocusableItemUnregister(ImGuiWindow* window)            { IM_ASSERT(0); IM_UNUSED(window); }                              // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem
 | 
			
		||||
@@ -2522,6 +2523,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          NavMoveRequestCancel();
 | 
			
		||||
    IMGUI_API void          NavMoveRequestApplyResult();
 | 
			
		||||
    IMGUI_API void          NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
 | 
			
		||||
 
 | 
			
		||||
@@ -2407,17 +2407,17 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
 | 
			
		||||
    bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
 | 
			
		||||
    if (!temp_input_is_active)
 | 
			
		||||
    {
 | 
			
		||||
        const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0;
 | 
			
		||||
        const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
 | 
			
		||||
        const bool clicked = (hovered && g.IO.MouseClicked[0]);
 | 
			
		||||
        const bool double_clicked = (hovered && g.IO.MouseDoubleClicked[0]);
 | 
			
		||||
        if (focus_requested || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id)
 | 
			
		||||
        if (input_requested_by_tabbing || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id)
 | 
			
		||||
        {
 | 
			
		||||
            SetActiveID(id, window);
 | 
			
		||||
            SetFocusID(id, window);
 | 
			
		||||
            FocusWindow(window);
 | 
			
		||||
            g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
 | 
			
		||||
            if (temp_input_allowed)
 | 
			
		||||
                if (focus_requested || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavActivateInputId == id)
 | 
			
		||||
                if (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavActivateInputId == id)
 | 
			
		||||
                    temp_input_is_active = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -3025,15 +3025,15 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
 | 
			
		||||
    bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
 | 
			
		||||
    if (!temp_input_is_active)
 | 
			
		||||
    {
 | 
			
		||||
        const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0;
 | 
			
		||||
        const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
 | 
			
		||||
        const bool clicked = (hovered && g.IO.MouseClicked[0]);
 | 
			
		||||
        if (focus_requested || clicked || g.NavActivateId == id || g.NavActivateInputId == id)
 | 
			
		||||
        if (input_requested_by_tabbing || clicked || g.NavActivateId == id || g.NavActivateInputId == id)
 | 
			
		||||
        {
 | 
			
		||||
            SetActiveID(id, window);
 | 
			
		||||
            SetFocusID(id, window);
 | 
			
		||||
            FocusWindow(window);
 | 
			
		||||
            g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
 | 
			
		||||
            if (temp_input_allowed && (focus_requested || (clicked && g.IO.KeyCtrl) || g.NavActivateInputId == id))
 | 
			
		||||
            if (temp_input_allowed && (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || g.NavActivateInputId == id))
 | 
			
		||||
                temp_input_is_active = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -4024,21 +4024,19 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
 | 
			
		||||
    // We are only allowed to access the state if we are already the active widget.
 | 
			
		||||
    ImGuiInputTextState* state = GetInputTextState(id);
 | 
			
		||||
 | 
			
		||||
    const bool focus_requested_by_code = (item_status_flags & ImGuiItemStatusFlags_FocusedByCode) != 0;
 | 
			
		||||
    const bool focus_requested_by_tabbing = (item_status_flags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
 | 
			
		||||
    const bool input_requested_by_tabbing = (item_status_flags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
 | 
			
		||||
    const bool input_requested_by_nav = (g.ActiveId != id) && ((g.NavActivateInputId == id) || (g.NavActivateId == id && g.NavInputSource == ImGuiInputSource_Keyboard));
 | 
			
		||||
 | 
			
		||||
    const bool user_clicked = hovered && io.MouseClicked[0];
 | 
			
		||||
    const bool user_nav_input_start = (g.ActiveId != id) && (g.NavActivateInputId == id || g.NavActivateId == id);
 | 
			
		||||
    const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
 | 
			
		||||
    const bool user_scroll_active = is_multiline && state != NULL && g.ActiveId == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
 | 
			
		||||
 | 
			
		||||
    bool clear_active_id = false;
 | 
			
		||||
    bool select_all = (g.ActiveId != id) && ((flags & ImGuiInputTextFlags_AutoSelectAll) != 0 || user_nav_input_start) && (!is_multiline);
 | 
			
		||||
    bool select_all = false;
 | 
			
		||||
 | 
			
		||||
    float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
 | 
			
		||||
 | 
			
		||||
    const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline);
 | 
			
		||||
    const bool init_make_active = (user_clicked || user_scroll_finish || user_nav_input_start || focus_requested_by_code || focus_requested_by_tabbing);
 | 
			
		||||
    const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav || input_requested_by_tabbing);
 | 
			
		||||
    const bool init_state = (init_make_active || user_scroll_active);
 | 
			
		||||
    if ((init_state && g.ActiveId != id) || init_changed_specs)
 | 
			
		||||
    {
 | 
			
		||||
@@ -4074,13 +4072,20 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
 | 
			
		||||
            state->ID = id;
 | 
			
		||||
            state->ScrollX = 0.0f;
 | 
			
		||||
            stb_textedit_initialize_state(&state->Stb, !is_multiline);
 | 
			
		||||
            if (!is_multiline && focus_requested_by_code)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!is_multiline)
 | 
			
		||||
        {
 | 
			
		||||
            if (flags & ImGuiInputTextFlags_AutoSelectAll)
 | 
			
		||||
                select_all = true;
 | 
			
		||||
            if (input_requested_by_nav && (!recycle_state || !(g.NavActivateFlags & ImGuiActivateFlags_TryToPreserveState)))
 | 
			
		||||
                select_all = true;
 | 
			
		||||
            if (input_requested_by_tabbing || (user_clicked && io.KeyCtrl))
 | 
			
		||||
                select_all = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (flags & ImGuiInputTextFlags_AlwaysOverwrite)
 | 
			
		||||
            state->Stb.insert_mode = 1; // stb field name is indeed incorrect (see #2863)
 | 
			
		||||
        if (!is_multiline && (focus_requested_by_tabbing || (user_clicked && io.KeyCtrl)))
 | 
			
		||||
            select_all = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (g.ActiveId != id && init_make_active)
 | 
			
		||||
@@ -4214,7 +4219,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
 | 
			
		||||
        // We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters.
 | 
			
		||||
        if (io.InputQueueCharacters.Size > 0)
 | 
			
		||||
        {
 | 
			
		||||
            if (!ignore_char_inputs && !is_readonly && !user_nav_input_start)
 | 
			
		||||
            if (!ignore_char_inputs && !is_readonly && !input_requested_by_nav)
 | 
			
		||||
                for (int n = 0; n < io.InputQueueCharacters.Size; n++)
 | 
			
		||||
                {
 | 
			
		||||
                    // Insert character if they pass filtering
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user