mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-01 02:37:24 +01:00
Merge branch 'master' into docking
# Conflicts: # imgui_internal.h
This commit is contained in:
commit
cab7edd135
@ -18,6 +18,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-01-17: Explicitly fill all of WGPUDepthStencilState since standard removed defaults.
|
||||
// 2023-07-13: Use WGPUShaderModuleWGSLDescriptor's code instead of source. use WGPUMipmapFilterMode_Linear instead of WGPUFilterMode_Linear. (#6602)
|
||||
// 2023-04-11: Align buffer sizes. Use WGSL shaders instead of precompiled SPIR-V.
|
||||
// 2023-04-11: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
@ -656,7 +657,13 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
depth_stencil_state.depthWriteEnabled = false;
|
||||
depth_stencil_state.depthCompare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilFront.compare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilFront.failOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilFront.depthFailOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilFront.passOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilBack.compare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilBack.failOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilBack.depthFailOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilBack.passOp = WGPUStencilOperation_Keep;
|
||||
|
||||
// Configure disabled depth-stencil state
|
||||
graphics_pipeline_desc.depthStencil = (bd->depthStencilFormat == WGPUTextureFormat_Undefined) ? nullptr : &depth_stencil_state;
|
||||
|
@ -46,12 +46,17 @@ Breaking changes:
|
||||
|
||||
Other changes:
|
||||
|
||||
- Fixed SetKeyboardFocusHere() not working when current nav focus is in different scope,
|
||||
- Nav: keyboard/gamepad activation mark widgets as held to give better visual feedback.
|
||||
- Nav: tweak to logic marking navigated item as hovered when using keyboard, allowing
|
||||
the hover highlight to stay even while another item is activated.
|
||||
- Nav: Fixed SetKeyboardFocusHere() not working when current nav focus is in different scope,
|
||||
regression from 1.90.1 related to code scoping Tab presses to local scope. (#7226) [@bratpilz]
|
||||
- Debug Tools: Metrics: Fixed debug break in SetShortcutRouting() not handling ImGuiMod_Shortcut redirect.
|
||||
- Debug Tools: Debug Log: Added "Input Routing" logging.
|
||||
- Backends: Vulkan: Fixed vkMapMemory() calls unnecessarily using full buffer size. (#3957)
|
||||
- Backends: Vulkan: Fixed handling of ImGui_ImplVulkan_InitInfo::MinAllocationSize field. (#7189, #4238)
|
||||
- Backends: WebGPU: Filling all WGPUDepthStencilState fields explicitly as a recent Dawn
|
||||
update stopped setting default values. (#7232) [@GrigoryGraborenko]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
|
257
imgui.cpp
257
imgui.cpp
@ -75,6 +75,7 @@ CODE
|
||||
// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
|
||||
// [SECTION] INPUTS
|
||||
// [SECTION] ERROR CHECKING
|
||||
// [SECTION] ITEM SUBMISSION
|
||||
// [SECTION] LAYOUT
|
||||
// [SECTION] SCROLLING
|
||||
// [SECTION] TOOLTIPS
|
||||
@ -3672,6 +3673,14 @@ void ImGui::Initialize()
|
||||
g.ViewportCreatedCount++;
|
||||
g.PlatformIO.Viewports.push_back(g.Viewports[0]);
|
||||
|
||||
// Build KeysMayBeCharInput[] lookup table (1 bool per named key)
|
||||
for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1))
|
||||
if ((key >= ImGuiKey_0 && key <= ImGuiKey_9) || (key >= ImGuiKey_A && key <= ImGuiKey_Z) || (key >= ImGuiKey_Keypad0 && key <= ImGuiKey_Keypad9)
|
||||
|| key == ImGuiKey_Tab || key == ImGuiKey_Space || key == ImGuiKey_Apostrophe || key == ImGuiKey_Comma || key == ImGuiKey_Minus || key == ImGuiKey_Period
|
||||
|| key == ImGuiKey_Slash || key == ImGuiKey_Semicolon || key == ImGuiKey_Equal || key == ImGuiKey_LeftBracket || key == ImGuiKey_RightBracket || key == ImGuiKey_GraveAccent
|
||||
|| key == ImGuiKey_KeypadDecimal || key == ImGuiKey_KeypadDivide || key == ImGuiKey_KeypadMultiply || key == ImGuiKey_KeypadSubtract || key == ImGuiKey_KeypadAdd || key == ImGuiKey_KeypadEqual)
|
||||
g.KeysMayBeCharInput.SetBit(key);
|
||||
|
||||
#ifdef IMGUI_HAS_DOCK
|
||||
// Initialize Docking
|
||||
DockContextInitialize(&g);
|
||||
@ -4007,17 +4016,6 @@ ImGuiID ImGui::GetHoveredID()
|
||||
return g.HoveredId ? g.HoveredId : g.HoveredIdPreviousFrame;
|
||||
}
|
||||
|
||||
// This is called by ItemAdd().
|
||||
// Code not using ItemAdd() may need to call this manually otherwise ActiveId will be cleared. In IMGUI_VERSION_NUM < 18717 this was called by GetID().
|
||||
void ImGui::KeepAliveID(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.ActiveId == id)
|
||||
g.ActiveIdIsAlive = id;
|
||||
if (g.ActiveIdPreviousFrame == id)
|
||||
g.ActiveIdPreviousFrameIsAlive = true;
|
||||
}
|
||||
|
||||
void ImGui::MarkItemEdited(ImGuiID id)
|
||||
{
|
||||
// This marking is solely to be able to provide info for IsItemDeactivatedAfterEdit().
|
||||
@ -4238,17 +4236,19 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
if (id != 0)
|
||||
{
|
||||
// [DEBUG] Item Picker tool!
|
||||
// We perform the check here because SetHoveredID() is not frequently called (1~ time a frame), making
|
||||
// the cost of this tool near-zero. We can get slightly better call-stack and support picking non-hovered
|
||||
// items if we performed the test in ItemAdd(), but that would incur a small runtime cost.
|
||||
// We perform the check here because reaching is path is rare (1~ time a frame),
|
||||
// making the cost of this tool near-zero! We could get better call-stack and support picking non-hovered
|
||||
// items if we performed the test in ItemAdd(), but that would incur a bigger runtime cost.
|
||||
if (g.DebugItemPickerActive && g.HoveredIdPreviousFrame == id)
|
||||
GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255));
|
||||
if (g.DebugItemPickerBreakId == id)
|
||||
IM_DEBUG_BREAK();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (g.NavDisableMouseHover)
|
||||
return false;
|
||||
@ -4980,6 +4980,7 @@ void ImGui::NewFrame()
|
||||
DockContextNewFrameUpdateDocking(&g);
|
||||
|
||||
// [DEBUG] Update debug features
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
UpdateDebugToolItemPicker();
|
||||
UpdateDebugToolStackQueries();
|
||||
UpdateDebugToolFlashStyleColor();
|
||||
@ -4994,6 +4995,7 @@ void ImGui::NewFrame()
|
||||
g.DebugLogFlags &= ~g.DebugLogAutoDisableFlags;
|
||||
g.DebugLogAutoDisableFlags = ImGuiDebugLogFlags_None;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create implicit/fallback window - which we will only render it if the user has added something to it.
|
||||
// We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags.
|
||||
@ -5005,10 +5007,12 @@ void ImGui::NewFrame()
|
||||
|
||||
// [DEBUG] When io.ConfigDebugBeginReturnValue is set, we make Begin()/BeginChild() return false at different level of the window-stack,
|
||||
// allowing to validate correct Begin/End behavior in user code.
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
if (g.IO.ConfigDebugBeginReturnValueLoop)
|
||||
g.DebugBeginReturnValueCullDepth = (g.DebugBeginReturnValueCullDepth == -1) ? 0 : ((g.DebugBeginReturnValueCullDepth + ((g.FrameCount % 4) == 0 ? 1 : 0)) % 10);
|
||||
else
|
||||
g.DebugBeginReturnValueCullDepth = -1;
|
||||
#endif
|
||||
|
||||
CallContextHooks(&g, ImGuiContextHookType_NewFramePost);
|
||||
}
|
||||
@ -7588,12 +7592,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
|
||||
// [DEBUG] io.ConfigDebugBeginReturnValue override return value to test Begin/End and BeginChild/EndChild behaviors.
|
||||
// (The implicit fallback window is NOT automatically ended allowing it to always be able to receive commands without crashing)
|
||||
if (!window->IsFallbackWindow && ((g.IO.ConfigDebugBeginReturnValueOnce && window_just_created) || (g.IO.ConfigDebugBeginReturnValueLoop && g.DebugBeginReturnValueCullDepth == g.CurrentWindowStack.Size)))
|
||||
{
|
||||
if (window->AutoFitFramesX > 0) { window->AutoFitFramesX++; }
|
||||
if (window->AutoFitFramesY > 0) { window->AutoFitFramesY++; }
|
||||
return false;
|
||||
}
|
||||
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
if (!window->IsFallbackWindow)
|
||||
if ((g.IO.ConfigDebugBeginReturnValueOnce && window_just_created) || (g.IO.ConfigDebugBeginReturnValueLoop && g.DebugBeginReturnValueCullDepth == g.CurrentWindowStack.Size))
|
||||
{
|
||||
if (window->AutoFitFramesX > 0) { window->AutoFitFramesX++; }
|
||||
if (window->AutoFitFramesY > 0) { window->AutoFitFramesY++; }
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return !window->SkipItems;
|
||||
}
|
||||
@ -8438,7 +8445,7 @@ void ImGui::SetNavFocusScope(ImGuiID focus_scope_id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.NavFocusScopeId = focus_scope_id;
|
||||
g.NavFocusScopePath.resize(0); // Invalidate
|
||||
g.NavFocusRoute.resize(0); // Invalidate
|
||||
if (focus_scope_id == 0)
|
||||
return;
|
||||
IM_ASSERT(g.NavWindow != NULL);
|
||||
@ -8448,17 +8455,17 @@ void ImGui::SetNavFocusScope(ImGuiID focus_scope_id)
|
||||
{
|
||||
// Top of focus stack contains local focus scopes inside current window
|
||||
for (int n = g.FocusScopeStack.Size - 1; n >= 0 && g.FocusScopeStack.Data[n].WindowID == g.CurrentWindow->ID; n--)
|
||||
g.NavFocusScopePath.push_back(g.FocusScopeStack.Data[n]);
|
||||
g.NavFocusRoute.push_back(g.FocusScopeStack.Data[n]);
|
||||
}
|
||||
else if (focus_scope_id == g.NavWindow->NavRootFocusScopeId)
|
||||
g.NavFocusScopePath.push_back({ focus_scope_id, g.NavWindow->ID });
|
||||
g.NavFocusRoute.push_back({ focus_scope_id, g.NavWindow->ID });
|
||||
else
|
||||
return;
|
||||
|
||||
// Then follow on manually set ParentWindowForFocusRoute field (#6798)
|
||||
for (ImGuiWindow* window = g.NavWindow->ParentWindowForFocusRoute; window != NULL; window = window->ParentWindowForFocusRoute)
|
||||
g.NavFocusScopePath.push_back({ window->NavRootFocusScopeId, window->ID });
|
||||
IM_ASSERT(g.NavFocusScopePath.Size < 100); // Maximum depth is technically 251 as per CalcRoutingScore(): 254 - 3
|
||||
g.NavFocusRoute.push_back({ window->NavRootFocusScopeId, window->ID });
|
||||
IM_ASSERT(g.NavFocusRoute.Size < 100); // Maximum depth is technically 251 as per CalcRoutingScore(): 254 - 3
|
||||
}
|
||||
|
||||
// Focus = move navigation cursor, set scrolling, set focus window.
|
||||
@ -8922,13 +8929,11 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord)
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiKeyRoutingTable* rt = &g.KeysRoutingTable;
|
||||
ImGuiKeyRoutingData* routing_data;
|
||||
if (key_chord & ImGuiMod_Shortcut)
|
||||
key_chord = ConvertShortcutMod(key_chord);
|
||||
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
|
||||
ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_);
|
||||
if (key == ImGuiKey_None)
|
||||
key = ConvertSingleModFlagToKey(&g, mods);
|
||||
IM_ASSERT(IsNamedKey(key));
|
||||
IM_ASSERT(IsNamedKey(key) && (key_chord & ImGuiMod_Shortcut) == 0); // Please call ConvertShortcutMod() in calling function.
|
||||
|
||||
// Get (in the majority of case, the linked list will have one element so this should be 2 reads.
|
||||
// Subsequent elements will be contiguous in memory as list is sorted/rebuilt in NewFrame).
|
||||
@ -8977,8 +8982,8 @@ static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInput
|
||||
// This essentially follow the window->ParentWindowForFocusRoute chain.
|
||||
if (focus_scope_id == 0)
|
||||
return 255;
|
||||
for (int index_in_focus_path = 0; index_in_focus_path < g.NavFocusScopePath.Size; index_in_focus_path++)
|
||||
if (g.NavFocusScopePath.Data[index_in_focus_path].ID == focus_scope_id)
|
||||
for (int index_in_focus_path = 0; index_in_focus_path < g.NavFocusRoute.Size; index_in_focus_path++)
|
||||
if (g.NavFocusRoute.Data[index_in_focus_path].ID == focus_scope_id)
|
||||
return 3 + index_in_focus_path;
|
||||
|
||||
return 255;
|
||||
@ -8992,6 +8997,24 @@ static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInput
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We need this to filter some Shortcut() routes when an item e.g. an InputText() is active
|
||||
// e.g. ImGuiKey_G won't be considered a shortcut when item is active, but ImGuiMod|ImGuiKey_G can be.
|
||||
static bool IsKeyChordPotentiallyCharInput(ImGuiKeyChord key_chord)
|
||||
{
|
||||
// Mimic 'ignore_char_inputs' logic in InputText()
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// When the right mods are pressed it cannot be a char input so we won't filter the shortcut out.
|
||||
ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_);
|
||||
const bool ignore_char_inputs = ((mods & ImGuiMod_Ctrl) && !(mods & ImGuiMod_Alt)) || (g.IO.ConfigMacOSXBehaviors && (mods & ImGuiMod_Super));
|
||||
if (ignore_char_inputs)
|
||||
return false;
|
||||
|
||||
// Return true for A-Z, 0-9 and other keys associated to char inputs. Other keys such as F1-F12 won't be filtered.
|
||||
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
|
||||
return g.KeysMayBeCharInput.TestBit(key);
|
||||
}
|
||||
|
||||
// Request a desired route for an input chord (key + mods).
|
||||
// Return true if the route is available this frame.
|
||||
// - Routes and key ownership are attributed at the beginning of next frame based on best score and mod state.
|
||||
@ -9006,14 +9029,17 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI
|
||||
flags |= ImGuiInputFlags_RouteGlobalHigh; // IMPORTANT: This is the default for SetShortcutRouting() but NOT Shortcut()
|
||||
else
|
||||
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteMask_)); // Check that only 1 routing flag is used
|
||||
if (key_chord & ImGuiMod_Shortcut)
|
||||
key_chord = ConvertShortcutMod(key_chord);
|
||||
|
||||
// [DEBUG] Debug break requested by user
|
||||
if (g.DebugBreakInShortcutRouting != 0 && g.DebugBreakInShortcutRouting == ConvertShortcutMod(key_chord))
|
||||
if (g.DebugBreakInShortcutRouting == key_chord)
|
||||
IM_DEBUG_BREAK();
|
||||
|
||||
if (flags & ImGuiInputFlags_RouteUnlessBgFocused)
|
||||
if (g.NavWindow == NULL)
|
||||
return false;
|
||||
|
||||
// Note how ImGuiInputFlags_RouteAlways won't set routing and thus won't set owner. May want to rework this?
|
||||
if (flags & ImGuiInputFlags_RouteAlways)
|
||||
{
|
||||
@ -9021,6 +9047,18 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI
|
||||
return true;
|
||||
}
|
||||
|
||||
// Specific culling for shortcuts with no modifiers when there's an active id.
|
||||
// e.g. Shortcut(ImGuiKey_G) also generates 'g' character, should not trigger when InputText() is active.
|
||||
// but Shortcut(Ctrl+G) should generally trigger when InputText() is active.
|
||||
// TL;DR: lettered shortcut with no mods or with only Alt mod will not trigger while an item reading text input is active.
|
||||
// (We cannot filter based on io.InputQueueCharacters[] contents because of trickling and key<>chars submission order are undefined)
|
||||
if ((flags & ImGuiInputFlags_RouteFocused) && (g.ActiveId != 0 && g.ActiveId != owner_id))
|
||||
if (g.IO.WantTextInput && IsKeyChordPotentiallyCharInput(key_chord))
|
||||
{
|
||||
IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, owner_id=0x%08X, flags=%04X) -> filtered as potential char input\n", GetKeyChordName(key_chord), owner_id, flags);
|
||||
return false;
|
||||
}
|
||||
|
||||
const int score = CalcRoutingScore(g.CurrentFocusScopeId, owner_id, flags);
|
||||
IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, owner_id=0x%08X, flags=%04X) -> score %d\n", GetKeyChordName(key_chord), owner_id, flags, score);
|
||||
if (score == 255)
|
||||
@ -9048,6 +9086,8 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI
|
||||
bool ImGui::TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id)
|
||||
{
|
||||
const ImGuiID routing_id = GetRoutingIdFromOwnerId(owner_id);
|
||||
if (key_chord & ImGuiMod_Shortcut)
|
||||
key_chord = ConvertShortcutMod(key_chord);
|
||||
ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord); // FIXME: Could avoid creating entry.
|
||||
return routing_data->RoutingCurr == routing_id;
|
||||
}
|
||||
@ -10016,7 +10056,7 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags
|
||||
|
||||
// Default repeat behavior for Shortcut()
|
||||
// So e.g. pressing Ctrl+W and releasing Ctrl while holding W will not trigger the W shortcut.
|
||||
if ((flags & ImGuiInputFlags_RepeatUntilMask_) == 0)
|
||||
if ((flags & ImGuiInputFlags_Repeat) != 0 && (flags & ImGuiInputFlags_RepeatUntilMask_) == 0)
|
||||
flags |= ImGuiInputFlags_RepeatUntilKeyModsChange;
|
||||
|
||||
if (!IsKeyChordPressed(key_chord, owner_id, flags))
|
||||
@ -10341,77 +10381,21 @@ void ImGuiStackSizes::CompareWithContextState(ImGuiContext* ctx)
|
||||
IM_ASSERT(SizeOfFocusScopeStack == g.FocusScopeStack.Size && "PushFocusScope/PopFocusScope Mismatch!");
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] LAYOUT
|
||||
// [SECTION] ITEM SUBMISSION
|
||||
//-----------------------------------------------------------------------------
|
||||
// - ItemSize()
|
||||
// - KeepAliveID()
|
||||
// - ItemAdd()
|
||||
// - SameLine()
|
||||
// - GetCursorScreenPos()
|
||||
// - SetCursorScreenPos()
|
||||
// - GetCursorPos(), GetCursorPosX(), GetCursorPosY()
|
||||
// - SetCursorPos(), SetCursorPosX(), SetCursorPosY()
|
||||
// - GetCursorStartPos()
|
||||
// - Indent()
|
||||
// - Unindent()
|
||||
// - SetNextItemWidth()
|
||||
// - PushItemWidth()
|
||||
// - PushMultiItemsWidths()
|
||||
// - PopItemWidth()
|
||||
// - CalcItemWidth()
|
||||
// - CalcItemSize()
|
||||
// - GetTextLineHeight()
|
||||
// - GetTextLineHeightWithSpacing()
|
||||
// - GetFrameHeight()
|
||||
// - GetFrameHeightWithSpacing()
|
||||
// - GetContentRegionMax()
|
||||
// - GetContentRegionMaxAbs() [Internal]
|
||||
// - GetContentRegionAvail(),
|
||||
// - GetWindowContentRegionMin(), GetWindowContentRegionMax()
|
||||
// - BeginGroup()
|
||||
// - EndGroup()
|
||||
// Also see in imgui_widgets: tab bars, and in imgui_tables: tables, columns.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Advance cursor given item size for layout.
|
||||
// Register minimum needed size so it can extend the bounding box used for auto-fit calculation.
|
||||
// See comments in ItemAdd() about how/why the size provided to ItemSize() vs ItemAdd() may often different.
|
||||
// THIS IS IN THE PERFORMANCE CRITICAL PATH.
|
||||
void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
|
||||
// Code not using ItemAdd() may need to call this manually otherwise ActiveId will be cleared. In IMGUI_VERSION_NUM < 18717 this was called by GetID().
|
||||
void ImGui::KeepAliveID(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (window->SkipItems)
|
||||
return;
|
||||
|
||||
// We increase the height in this function to accommodate for baseline offset.
|
||||
// In theory we should be offsetting the starting position (window->DC.CursorPos), that will be the topic of a larger refactor,
|
||||
// but since ItemSize() is not yet an API that moves the cursor (to handle e.g. wrapping) enlarging the height has the same effect.
|
||||
const float offset_to_match_baseline_y = (text_baseline_y >= 0) ? ImMax(0.0f, window->DC.CurrLineTextBaseOffset - text_baseline_y) : 0.0f;
|
||||
|
||||
const float line_y1 = window->DC.IsSameLine ? window->DC.CursorPosPrevLine.y : window->DC.CursorPos.y;
|
||||
const float line_height = ImMax(window->DC.CurrLineSize.y, /*ImMax(*/window->DC.CursorPos.y - line_y1/*, 0.0f)*/ + size.y + offset_to_match_baseline_y);
|
||||
|
||||
// Always align ourselves on pixel boundaries
|
||||
//if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG]
|
||||
window->DC.CursorPosPrevLine.x = window->DC.CursorPos.x + size.x;
|
||||
window->DC.CursorPosPrevLine.y = line_y1;
|
||||
window->DC.CursorPos.x = IM_TRUNC(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); // Next line
|
||||
window->DC.CursorPos.y = IM_TRUNC(line_y1 + line_height + g.Style.ItemSpacing.y); // Next line
|
||||
window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x);
|
||||
window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y);
|
||||
//if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG]
|
||||
|
||||
window->DC.PrevLineSize.y = line_height;
|
||||
window->DC.CurrLineSize.y = 0.0f;
|
||||
window->DC.PrevLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, text_baseline_y);
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
window->DC.IsSameLine = window->DC.IsSetPos = false;
|
||||
|
||||
// Horizontal layout mode
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||
SameLine();
|
||||
if (g.ActiveId == id)
|
||||
g.ActiveIdIsAlive = id;
|
||||
if (g.ActiveIdPreviousFrame == id)
|
||||
g.ActiveIdPreviousFrameIsAlive = true;
|
||||
}
|
||||
|
||||
// Declare item bounding box for clipping and interaction.
|
||||
@ -10502,6 +10486,78 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] LAYOUT
|
||||
//-----------------------------------------------------------------------------
|
||||
// - ItemSize()
|
||||
// - SameLine()
|
||||
// - GetCursorScreenPos()
|
||||
// - SetCursorScreenPos()
|
||||
// - GetCursorPos(), GetCursorPosX(), GetCursorPosY()
|
||||
// - SetCursorPos(), SetCursorPosX(), SetCursorPosY()
|
||||
// - GetCursorStartPos()
|
||||
// - Indent()
|
||||
// - Unindent()
|
||||
// - SetNextItemWidth()
|
||||
// - PushItemWidth()
|
||||
// - PushMultiItemsWidths()
|
||||
// - PopItemWidth()
|
||||
// - CalcItemWidth()
|
||||
// - CalcItemSize()
|
||||
// - GetTextLineHeight()
|
||||
// - GetTextLineHeightWithSpacing()
|
||||
// - GetFrameHeight()
|
||||
// - GetFrameHeightWithSpacing()
|
||||
// - GetContentRegionMax()
|
||||
// - GetContentRegionMaxAbs() [Internal]
|
||||
// - GetContentRegionAvail(),
|
||||
// - GetWindowContentRegionMin(), GetWindowContentRegionMax()
|
||||
// - BeginGroup()
|
||||
// - EndGroup()
|
||||
// Also see in imgui_widgets: tab bars, and in imgui_tables: tables, columns.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Advance cursor given item size for layout.
|
||||
// Register minimum needed size so it can extend the bounding box used for auto-fit calculation.
|
||||
// See comments in ItemAdd() about how/why the size provided to ItemSize() vs ItemAdd() may often different.
|
||||
// THIS IS IN THE PERFORMANCE CRITICAL PATH.
|
||||
void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (window->SkipItems)
|
||||
return;
|
||||
|
||||
// We increase the height in this function to accommodate for baseline offset.
|
||||
// In theory we should be offsetting the starting position (window->DC.CursorPos), that will be the topic of a larger refactor,
|
||||
// but since ItemSize() is not yet an API that moves the cursor (to handle e.g. wrapping) enlarging the height has the same effect.
|
||||
const float offset_to_match_baseline_y = (text_baseline_y >= 0) ? ImMax(0.0f, window->DC.CurrLineTextBaseOffset - text_baseline_y) : 0.0f;
|
||||
|
||||
const float line_y1 = window->DC.IsSameLine ? window->DC.CursorPosPrevLine.y : window->DC.CursorPos.y;
|
||||
const float line_height = ImMax(window->DC.CurrLineSize.y, /*ImMax(*/window->DC.CursorPos.y - line_y1/*, 0.0f)*/ + size.y + offset_to_match_baseline_y);
|
||||
|
||||
// Always align ourselves on pixel boundaries
|
||||
//if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG]
|
||||
window->DC.CursorPosPrevLine.x = window->DC.CursorPos.x + size.x;
|
||||
window->DC.CursorPosPrevLine.y = line_y1;
|
||||
window->DC.CursorPos.x = IM_TRUNC(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); // Next line
|
||||
window->DC.CursorPos.y = IM_TRUNC(line_y1 + line_height + g.Style.ItemSpacing.y); // Next line
|
||||
window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x);
|
||||
window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y);
|
||||
//if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG]
|
||||
|
||||
window->DC.PrevLineSize.y = line_height;
|
||||
window->DC.CurrLineSize.y = 0.0f;
|
||||
window->DC.PrevLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, text_baseline_y);
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
window->DC.IsSameLine = window->DC.IsSetPos = false;
|
||||
|
||||
// Horizontal layout mode
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||
SameLine();
|
||||
}
|
||||
|
||||
// Gets back to previous line and continue with horizontal layout
|
||||
// offset_from_start_x == 0 : follow right after previous item
|
||||
// offset_from_start_x != 0 : align to specified x position (relative to window/group left)
|
||||
@ -20211,10 +20267,10 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
Text("NavActivateFlags: %04X", g.NavActivateFlags);
|
||||
Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover);
|
||||
Text("NavFocusScopeId = 0x%08X", g.NavFocusScopeId);
|
||||
Text("NavFocusScopePath[] = ");
|
||||
for (int path_n = g.NavFocusScopePath.Size - 1; path_n >= 0; path_n--)
|
||||
Text("NavFocusRoute[] = ");
|
||||
for (int path_n = g.NavFocusRoute.Size - 1; path_n >= 0; path_n--)
|
||||
{
|
||||
const ImGuiFocusScopeData& focus_scope = g.NavFocusScopePath[path_n];
|
||||
const ImGuiFocusScopeData& focus_scope = g.NavFocusRoute[path_n];
|
||||
SameLine(0.0f, 0.0f);
|
||||
Text("0x%08X/", focus_scope.ID);
|
||||
SetItemTooltip("In window \"%s\"", FindWindowByID(focus_scope.WindowID)->Name);
|
||||
@ -21323,9 +21379,6 @@ void ImGui::DebugLogV(const char*, va_list) {}
|
||||
void ImGui::ShowDebugLogWindow(bool*) {}
|
||||
void ImGui::ShowIDStackToolWindow(bool*) {}
|
||||
void ImGui::DebugHookIdInfo(ImGuiID, ImGuiDataType, const void*, const void*) {}
|
||||
void ImGui::UpdateDebugToolItemPicker() {}
|
||||
void ImGui::UpdateDebugToolStackQueries() {}
|
||||
void ImGui::UpdateDebugToolFlashStyleColor() {}
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||||
|
||||
|
2
imgui.h
2
imgui.h
@ -24,7 +24,7 @@
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.90.2 WIP"
|
||||
#define IMGUI_VERSION_NUM 19012
|
||||
#define IMGUI_VERSION_NUM 19013
|
||||
#define IMGUI_HAS_TABLE
|
||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||
#define IMGUI_HAS_DOCK // Docking WIP branch
|
||||
|
@ -700,9 +700,6 @@ struct ImPool
|
||||
int GetBufSize() const { return Buf.Size; }
|
||||
int GetMapSize() const { return Map.Data.Size; } // It is the map we need iterate to find valid items, since we don't have "alive" storage anywhere
|
||||
T* TryGetMapData(ImPoolIdx n) { int idx = Map.Data[n].val_i; if (idx == -1) return NULL; return GetByIndex(idx); }
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
int GetSize() { return GetMapSize(); } // For ImPlot: should use GetMapSize() from (IMGUI_VERSION_NUM >= 18304)
|
||||
#endif
|
||||
};
|
||||
|
||||
// Helper: ImChunkStream<>
|
||||
@ -1213,9 +1210,9 @@ typedef ImS64 ImGuiSelectionUserData;
|
||||
|
||||
enum ImGuiNextItemDataFlags_
|
||||
{
|
||||
ImGuiNextItemDataFlags_None = 0,
|
||||
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
|
||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
||||
ImGuiNextItemDataFlags_None = 0,
|
||||
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
|
||||
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
|
||||
};
|
||||
|
||||
struct ImGuiNextItemData
|
||||
@ -1223,10 +1220,10 @@ struct ImGuiNextItemData
|
||||
ImGuiNextItemDataFlags Flags;
|
||||
ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap.
|
||||
// Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem()
|
||||
float Width; // Set by SetNextItemWidth()
|
||||
ImGuiSelectionUserData SelectionUserData; // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values)
|
||||
ImGuiCond OpenCond;
|
||||
float Width; // Set by SetNextItemWidth()
|
||||
bool OpenVal; // Set by SetNextItemOpen()
|
||||
ImGuiCond OpenCond : 8;
|
||||
|
||||
ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; }
|
||||
inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()!
|
||||
@ -1424,17 +1421,19 @@ struct ImGuiKeyOwnerData
|
||||
};
|
||||
|
||||
// Flags for extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner()
|
||||
// Don't mistake with ImGuiInputTextFlags! (for ImGui::InputText() function)
|
||||
// Don't mistake with ImGuiInputTextFlags! (which is for ImGui::InputText() function)
|
||||
enum ImGuiInputFlags_
|
||||
{
|
||||
// Flags for IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked(), Shortcut()
|
||||
ImGuiInputFlags_None = 0,
|
||||
ImGuiInputFlags_Repeat = 1 << 0, // Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1.
|
||||
|
||||
// Repeat mode
|
||||
ImGuiInputFlags_Repeat = 1 << 0, // Enable repeat. Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1.
|
||||
ImGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default)
|
||||
ImGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast
|
||||
ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster
|
||||
|
||||
// Specify when repeating key pressed can be interrupted.
|
||||
// Repeat mode: Specify when repeating key pressed can be interrupted.
|
||||
// In theory ImGuiInputFlags_RepeatUntilOtherKeyPress may be a desirable default, but it would break too many behavior so everything is opt-in.
|
||||
ImGuiInputFlags_RepeatUntilRelease = 1 << 4, // Stop repeating when released (default for all functions except Shortcut). This only exists to allow overriding Shortcut() default behavior.
|
||||
ImGuiInputFlags_RepeatUntilKeyModsChange = 1 << 5, // Stop repeating when released OR if keyboard mods are changed (default for Shortcut)
|
||||
@ -1445,38 +1444,46 @@ enum ImGuiInputFlags_
|
||||
ImGuiInputFlags_CondHovered = 1 << 8, // Only set if item is hovered (default to both)
|
||||
ImGuiInputFlags_CondActive = 1 << 9, // Only set if item is active (default to both)
|
||||
ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
|
||||
// Flags for SetKeyOwner(), SetItemKeyOwner()
|
||||
ImGuiInputFlags_LockThisFrame = 1 << 10, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
|
||||
ImGuiInputFlags_LockUntilRelease = 1 << 11, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
|
||||
// Locking is useful to make input-owner-aware code steal keys from non-input-owner-aware code. If all code is input-owner-aware locking would never be necessary.
|
||||
ImGuiInputFlags_LockThisFrame = 1 << 10, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame.
|
||||
ImGuiInputFlags_LockUntilRelease = 1 << 11, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released.
|
||||
|
||||
// Routing policies for Shortcut() + low-level SetShortcutRouting()
|
||||
// - The general idea is that several callers register interest in a shortcut, and only one owner gets it.
|
||||
// - When a policy (other than _RouteAlways) is set, Shortcut() will register itself with SetShortcutRouting(),
|
||||
// Parent -> call Shortcut(Ctrl+S) // When Parent is focused, Parent gets the shortcut.
|
||||
// Child1 -> call Shortcut(Ctrl+S) // When Child1 is focused, Child1 gets the shortcut (Child1 overrides Parent shortcuts)
|
||||
// Child2 -> no call // When Child2 is focused, Parent gets the shortcut.
|
||||
// The whole system is order independent, so if Child1 does it calls before Parent results will be identical.
|
||||
// This is an important property as it facilitate working with foreign code or larger codebase.
|
||||
// - Visualize registered routes in 'Metrics->Inputs' and submitted routes in 'Debug Log->InputRouting'.
|
||||
// - When a policy (except for _RouteAlways *) is set, Shortcut() will register itself with SetShortcutRouting(),
|
||||
// allowing the system to decide where to route the input among other route-aware calls.
|
||||
// - Shortcut() uses ImGuiInputFlags_RouteFocused by default: meaning that a simple Shortcut() poll
|
||||
// will register a route and only succeed when parent window is in the focus stack and if no-one
|
||||
// with a higher priority is claiming the shortcut.
|
||||
// - Using ImGuiInputFlags_RouteAlways is roughly equivalent to doing e.g. IsKeyPressed(key) + testing mods.
|
||||
// (* Using ImGuiInputFlags_RouteAlways is roughly equivalent to calling IsKeyChordPressed(key)).
|
||||
// - Shortcut() uses ImGuiInputFlags_RouteFocused by default. Meaning that a Shortcut() call will register
|
||||
// a route and only succeed when parent window is in the focus-stack and if no-one with a higher priority
|
||||
// is claiming the same shortcut.
|
||||
// - You can chain two unrelated windows in the focus stack using SetWindowParentWindowForFocusRoute().
|
||||
// - Priorities: GlobalHigh > Focused (when owner is active item) > Global > Focused (when focused window) > GlobalLow.
|
||||
// - Can select only 1 policy among all available.
|
||||
ImGuiInputFlags_RouteFocused = 1 << 12, // (Default) Register focused route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window.
|
||||
ImGuiInputFlags_RouteGlobalLow = 1 << 13, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority.
|
||||
ImGuiInputFlags_RouteGlobal = 1 << 14, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText).
|
||||
ImGuiInputFlags_RouteGlobalHigh = 1 << 15, // Register route globally (highest priority: unlikely you need to use that: will interfere with every active items)
|
||||
ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this!
|
||||
ImGuiInputFlags_RouteFocused = 1 << 12, // (Default) Honor focus route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window.
|
||||
ImGuiInputFlags_RouteGlobalLow = 1 << 13, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority IF you need a Global priority.
|
||||
ImGuiInputFlags_RouteGlobal = 1 << 14, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText will take priority over this).
|
||||
ImGuiInputFlags_RouteGlobalHigh = 1 << 15, // Register route globally (higher priority: unlikely you need to use that: will interfere with every active items, e.g. CTRL+A registered by InputText will be overiden by this)
|
||||
ImGuiInputFlags_RouteAlways = 1 << 16, // Do not register route, poll keys directly.
|
||||
// Routing polices: extra options
|
||||
ImGuiInputFlags_RouteUnlessBgFocused= 1 << 17, // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
|
||||
ImGuiInputFlags_RouteExtraMask_ = ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused,
|
||||
|
||||
// [Internal] Mask of which function support which flags
|
||||
ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak,
|
||||
ImGuiInputFlags_RepeatUntilMask_ = ImGuiInputFlags_RepeatUntilRelease | ImGuiInputFlags_RepeatUntilKeyModsChange | ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone | ImGuiInputFlags_RepeatUntilOtherKeyPress,
|
||||
ImGuiInputFlags_RepeatMask_ = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RepeatUntilMask_,
|
||||
ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
|
||||
ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this!
|
||||
ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_RepeatMask_,
|
||||
ImGuiInputFlags_SupportedByIsMouseClicked = ImGuiInputFlags_Repeat,
|
||||
ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteExtraMask_,
|
||||
ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused,
|
||||
ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease,
|
||||
ImGuiInputFlags_SupportedBySetItemKeyOwner = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_,
|
||||
};
|
||||
@ -2155,6 +2162,7 @@ struct ImGuiContext
|
||||
double LastKeyModsChangeTime; // Record the last time key mods changed (affect repeat delay when using shortcut logic)
|
||||
double LastKeyModsChangeFromNoneTime; // Record the last time key mods changed away from being 0 (affect repeat delay when using shortcut logic)
|
||||
double LastKeyboardKeyPressTime; // Record the last time a keyboard key (ignore mouse/gamepad ones) was pressed.
|
||||
ImBitArrayForNamedKeys KeysMayBeCharInput; // Lookup to tell if a key can emit char input, see IsKeyChordPotentiallyCharInput(). sizeof() = 20 bytes
|
||||
ImGuiKeyOwnerData KeysOwnerData[ImGuiKey_NamedKey_COUNT];
|
||||
ImGuiKeyRoutingTable KeysRoutingTable;
|
||||
ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
|
||||
@ -2203,7 +2211,7 @@ struct ImGuiContext
|
||||
ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow'
|
||||
ImGuiID NavId; // Focused item for navigation
|
||||
ImGuiID NavFocusScopeId; // Focused focus scope (e.g. selection code often wants to "clear other items" when landing on an item of the same scope)
|
||||
ImVector<ImGuiFocusScopeData> NavFocusScopePath; // Reversed copy focus scope stack for NavId (should contains NavFocusScopeId). This essentially follow the window->ParentWindowForFocusRoute chain.
|
||||
ImVector<ImGuiFocusScopeData> NavFocusRoute; // Reversed copy focus scope stack for NavId (should contains NavFocusScopeId). This essentially follow the window->ParentWindowForFocusRoute chain.
|
||||
ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItem()
|
||||
ImGuiID NavActivateDownId; // ~~ IsKeyDown(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyDown(ImGuiKey_NavGamepadActivate) ? NavId : 0
|
||||
ImGuiID NavActivatePressedId; // ~~ IsKeyPressed(ImGuiKey_Space) || IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate) ? NavId : 0 (no repeat)
|
||||
@ -2606,6 +2614,7 @@ struct ImGuiContext
|
||||
FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0;
|
||||
FramerateSecPerFrameAccum = 0.0f;
|
||||
WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1;
|
||||
memset(TempKeychordName, 0, sizeof(TempKeychordName));
|
||||
}
|
||||
};
|
||||
|
||||
@ -3771,13 +3780,12 @@ namespace ImGui
|
||||
inline void SetItemUsingMouseWheel() { SetItemKeyOwner(ImGuiKey_MouseWheelY); } // Changed in 1.89
|
||||
inline bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0) { return TreeNodeUpdateNextOpen(id, flags); } // Renamed in 1.89
|
||||
|
||||
// Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets that used FocusableItemRegister():
|
||||
// Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets which used FocusableItemRegister():
|
||||
// (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.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput))' (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
|
||||
// (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0'
|
||||
// (New) IMGUI_VERSION_NUM >= 18413: using 'ItemAdd(..., ImGuiItemFlags_Inputable)' and 'bool tab_focused = (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput))'
|
||||
//inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd()
|
||||
//inline void FocusableItemUnregister(ImGuiWindow* window) // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem
|
||||
#endif
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // Removed in 1.87: Mapping from named key is always identity!
|
||||
|
@ -599,7 +599,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
|
||||
// Gamepad/Keyboard navigation
|
||||
// We report navigated item as hovered but we don't set g.HoveredId to not interfere with mouse.
|
||||
if (g.NavId == id && !g.NavDisableHighlight && g.NavDisableMouseHover && (g.ActiveId == 0 || g.ActiveId == id || g.ActiveId == window->MoveId))
|
||||
if (g.NavId == id && !g.NavDisableHighlight && g.NavDisableMouseHover)
|
||||
if (!(flags & ImGuiButtonFlags_NoHoveredOnFocus))
|
||||
hovered = true;
|
||||
if (g.NavActivateDownId == id)
|
||||
@ -666,7 +666,9 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
else if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad)
|
||||
{
|
||||
// When activated using Nav, we hold on the ActiveID until activation button is released
|
||||
if (g.NavActivateDownId != id)
|
||||
if (g.NavActivateDownId == id)
|
||||
held = true;
|
||||
else
|
||||
ClearActiveID();
|
||||
}
|
||||
if (pressed)
|
||||
@ -972,7 +974,6 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6
|
||||
|
||||
// Click position in scrollbar normalized space (0.0f->1.0f)
|
||||
const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v);
|
||||
SetHoveredID(id);
|
||||
|
||||
bool seek_absolute = false;
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
|
Loading…
Reference in New Issue
Block a user