mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-13 16:29:54 +02:00
Merge branch 'master' into docking
# Conflicts: # docs/CHANGELOG.txt # imgui.cpp
This commit is contained in:
149
imgui.cpp
149
imgui.cpp
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.85 WIP
|
||||
// dear imgui, v1.85
|
||||
// (main code and documentation)
|
||||
|
||||
// Help:
|
||||
@ -390,7 +390,7 @@ CODE
|
||||
- 2021/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
|
||||
|
||||
|
||||
- 2021/08/23 (1.85) - removed GetWindowContentRegionWidth() function. keep inline redirection helper. can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead.
|
||||
- 2021/08/23 (1.85) - removed GetWindowContentRegionWidth() function. keep inline redirection helper. can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead for generally 'GetContentRegionAvail().x' is more useful.
|
||||
- 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019):
|
||||
- ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList()
|
||||
- ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder
|
||||
@ -3366,7 +3366,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++;
|
||||
@ -3385,11 +3384,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
|
||||
@ -3977,7 +3971,10 @@ void ImGui::UpdateTabFocus()
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// Pressing TAB activate widget focus
|
||||
g.TabFocusPressed = (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && !IsActiveIdUsingKey(ImGuiKey_Tab));
|
||||
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.
|
||||
@ -3985,7 +3982,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
|
||||
@ -3994,17 +3990,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;
|
||||
@ -6790,7 +6784,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
|
||||
@ -7094,8 +7088,18 @@ void ImGui::FocusWindow(ImGuiWindow* window)
|
||||
void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
const int start_idx = ((under_this_window != NULL) ? FindWindowFocusIndex(under_this_window) : g.WindowsFocusOrder.Size) - 1;
|
||||
int start_idx = g.WindowsFocusOrder.Size - 1;
|
||||
if (under_this_window != NULL)
|
||||
{
|
||||
// Aim at root window behind us, if we are in a child window that's our own root (see #4640)
|
||||
int offset = -1;
|
||||
while (under_this_window->Flags & ImGuiWindowFlags_ChildWindow)
|
||||
{
|
||||
under_this_window = under_this_window->ParentWindow;
|
||||
offset = 0;
|
||||
}
|
||||
start_idx = FindWindowFocusIndex(under_this_window) + offset;
|
||||
}
|
||||
for (int i = start_idx; i >= 0; i--)
|
||||
{
|
||||
// We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user.
|
||||
@ -7677,12 +7681,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()
|
||||
@ -7691,15 +7699,17 @@ void ImGui::SetItemDefaultFocus()
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (!window->Appearing)
|
||||
return;
|
||||
if (g.NavWindow == window->RootWindowForNav && (g.NavInitRequest || g.NavInitResultId != 0) && g.NavLayer == window->DC.NavLayerCurrent)
|
||||
{
|
||||
g.NavInitRequest = false;
|
||||
g.NavInitResultId = g.LastItemData.ID;
|
||||
g.NavInitResultRectRel = ImRect(g.LastItemData.Rect.Min - window->Pos, g.LastItemData.Rect.Max - window->Pos);
|
||||
NavUpdateAnyRequestFlag();
|
||||
if (!IsItemVisible())
|
||||
SetScrollHereY();
|
||||
}
|
||||
if (g.NavWindow != window->RootWindowForNav || (!g.NavInitRequest && g.NavInitResultId == 0) || g.NavLayer != window->DC.NavLayerCurrent)
|
||||
return;
|
||||
|
||||
g.NavInitRequest = false;
|
||||
g.NavInitResultId = g.LastItemData.ID;
|
||||
g.NavInitResultRectRel = ImRect(g.LastItemData.Rect.Min - window->Pos, g.LastItemData.Rect.Max - window->Pos);
|
||||
NavUpdateAnyRequestFlag();
|
||||
|
||||
// Scroll could be done in NavInitRequestApplyResult() via a opt-in flag (we however don't want regular init requests to scroll)
|
||||
if (!IsItemVisible())
|
||||
ScrollToRectEx(window, g.LastItemData.Rect, ImGuiScrollFlags_None);
|
||||
}
|
||||
|
||||
void ImGui::SetStateStorage(ImGuiStorage* tree)
|
||||
@ -9625,6 +9635,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);
|
||||
}
|
||||
|
||||
@ -9659,18 +9670,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9696,6 +9719,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;
|
||||
@ -9704,12 +9731,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;
|
||||
@ -9933,6 +9969,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.
|
||||
@ -9950,7 +9987,7 @@ static void ImGui::NavUpdate()
|
||||
}
|
||||
g.NavIdIsAlive = false;
|
||||
g.NavJustTabbedId = 0;
|
||||
IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1);
|
||||
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
|
||||
if (g.NavWindow)
|
||||
@ -10184,7 +10221,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;
|
||||
@ -10239,9 +10278,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)
|
||||
@ -10406,10 +10463,11 @@ static void ImGui::NavEndFrame()
|
||||
}
|
||||
do_forward = true;
|
||||
}
|
||||
const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
|
||||
if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
|
||||
{
|
||||
bb_rel.Min.y = bb_rel.Max.y =
|
||||
ImMax(window->SizeFull.y, window->ContentSize.y + window->WindowPadding.y * 2.0f) - window->Scroll.y;
|
||||
ImMax(window->SizeFull.y, window->ContentSize.y + window->WindowPadding.y * 2.0f) - window->Scroll.y + decoration_up_height;
|
||||
if (move_flags & ImGuiNavMoveFlags_WrapY)
|
||||
{
|
||||
bb_rel.TranslateX(-bb_rel.GetWidth());
|
||||
@ -10419,7 +10477,7 @@ static void ImGui::NavEndFrame()
|
||||
}
|
||||
if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
|
||||
{
|
||||
bb_rel.Min.y = bb_rel.Max.y = -window->Scroll.y;
|
||||
bb_rel.Min.y = bb_rel.Max.y = -window->Scroll.y + decoration_up_height;
|
||||
if (move_flags & ImGuiNavMoveFlags_WrapY)
|
||||
{
|
||||
bb_rel.TranslateX(+bb_rel.GetWidth());
|
||||
@ -10440,6 +10498,7 @@ static int ImGui::FindWindowFocusIndex(ImGuiWindow* window)
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_UNUSED(g);
|
||||
int order = window->FocusOrder;
|
||||
IM_ASSERT(window->RootWindow == window); // No child window (not testing _ChildWindow because of docking)
|
||||
IM_ASSERT(g.WindowsFocusOrder[order] == window);
|
||||
return order;
|
||||
}
|
||||
@ -16574,7 +16633,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
if (cfg->ShowStackTool)
|
||||
ShowStackToolWindow(&cfg->ShowStackTool);
|
||||
|
||||
if (!Begin("Dear ImGui Metrics/Debugger", p_open))
|
||||
if (!Begin("Dear ImGui Metrics/Debugger", p_open) || GetCurrentWindow()->BeginCount > 1)
|
||||
{
|
||||
End();
|
||||
return;
|
||||
|
Reference in New Issue
Block a user