Fix: InputTextMultiline crashed when drawn (InputTextLineIndexBuild/line offsets 0-based like upstream, inverted buf_display_end), InputText LiveEdit flag check; Shortcut()/IsKeyChordPressed() upstream defaults; FrameCount starts at 0 (IsWindowAppearing on first frame); missing ImGuiIO config fields with upstream defaults (+ ConfigDebugBeginReturnValueOnce/Loop); ColorButton drag source + ColorEdit4 drop target, IMGUI_PAYLOAD_TYPE_COLOR_3F/4F; t_fixes covers them

This commit is contained in:
4DBug
2026-10-15 03:03:10 -05:00
parent 9c8c1b018e
commit 33ab5a1d84
13 changed files with 1068 additions and 790 deletions
+152 -78
View File
@@ -138,7 +138,7 @@ if not utf8 then
end
local ImGui, ImVec2, ImVec4, ImRect, HelpMarker, ImVec2_Copy, IMGUI_DEMO_MARKER, ImGuiTableFlags, ImStd, ImVector, ImGuiKey, ImGuiInputFlags, ImRect_Copy, ImGuiDataType, ImStb, IM_TRUNC, ImGuiStyleVarInfo, ImVec2_CopyV, IM_ASSERT_USER_ERROR, ImGuiHoveredFlags, ImFormatString, ImHashStr, ImS32, IM_ASSERT_USER_ERROR_RET, ImGuiColorEditFlags, ImDrawFlags, ImIsPowerOfTwo, ImVec4_Copy, ExampleAppConsoleMT, IM_ROUND, ImGuiTableColumnFlags, ImGuiTreeNodeFlags, PopStyleCompact, PushStyleCompact, ImU16, ImAbs, ImGuiWindowFlags, ImGuiItemFlags, stbte, ImGuiButtonFlags, ImGuiDebugLogFlags, ImGuiLocKey, ImU32, ImColor, ImCos, ImS16, ImGuiTabBarFlags, ImSin, ImUpperPowerOfTwo, ImVec2_MulVX, IM_F32_TO_INT8_SAT, ImCeil, ImFontAtlasPackGetRect, ImGuiMouseCursor, DockSettingsRenameNodeReferences, IM_ASSERT_PARANOID, ImGuiCol, ImGuiListClipper, ImLengthSqr, ImS8, ImU8, _PathArcToFastExXY, ExampleAppPropertyEditorMT, ImFabs, ImGuiScrollFlags, ImGui_ImplLOVE_GetBackendData, ImLog, ImPow, CustomConstraints, ExampleAppLogMT, IMGUI_DEBUG_LOG_FONT, ImFontAtlasBuildInit, ImFontCalcWordWrapPositionEx, ImGuiComboFlags, ImGuiPopupFlags, ImGuiSliderFlags, ImTextClassifierSetCharClass, ImVec2_AddVA, ImVec2_SubVA, MyDocument, ShowExampleMenuFile, ImFontAtlasBakedAddFontGlyph, ImFontAtlasPackAddRect, ImFontBaked_BuildLoadGlyph, ImGuiInputTextFlags, ImGuiStyle_Copy, ExampleMemberInfo, ExampleTree_CreateNode, ImFontAtlasBuildRenderBitmapFromString, ImFontAtlasFontDestroyOutput, ImFontAtlasFontSourceAddToFont, ImFontAtlasFontSourceInit, ImGuiTableColumn, MyItem_s_current_sort_specs, stb_textedit_key, stbtt_GetGlyphBitmapBoxSubpixel, EditTableSizingFlags, IMGUI_PAYLOAD_TYPE_COLOR_4F, IM_FREE, ImDrawListSplitter, ImGuiDragDropFlags, MyItemColumnID_ID, MyItemColumnID_Name, MyItemColumnID_Quantity, stb_text_locate_coord, stb_text_makeundo_insert, stb_text_makeundo_replace, stb_textedit_find_charpos, stbtt_GetGlyphShape, EditTabBarFittingPolicyFlags, ImGuiTableColumnSortSpecs, ImGuiTableInstanceData, ImGuiTableSettings, stb_text_makeundo_delete, stb_text_redo, stb_text_undo, stb_textedit_click, stb_textedit_drag, stbtt_FindGlyphIndex, stbtt_GetFontOffsetForIndex, stbtt_GetFontVMetrics, stbtt_GetGlyphBitmapBox, stbtt_GetGlyphHMetrics, stbtt_InitFont, stbtt_MakeGlyphBitmapSubpixelPrefilter, stbtt_ScaleForPixelHeight, stbtt__GetGlyphInfoT2, stbtt__GetGlyphShapeT2, stbtt_fontinfo, ImGuiOldColumnData, ImGuiOldColumnFlags, ImGuiOldColumns, ImGuiTable, ImGuiTableColumnSettings, ImGuiTableSortSpecs, ImGuiTableTempData, ImGui_ImplLOVE_CreateTexture, ImGui_ImplLOVE_DestroyTexture, ImGui_ImplLOVE_Init, ImGui_ImplLOVE_NewFrame, ImGui_ImplLOVE_RenderDrawData, ImGui_ImplLOVE_Shutdown, ImGui_ImplLOVE_UpdateTexture, stbrp_init_target, IMGUI_TABLE_MAX_COLUMNS, IMSTB_TEXTEDIT_UNDOSTATECOUNT, IM_COL32_DISABLE, ImGui_ImplLove, STB_TEXTEDIT_K_BACKSPACE, STB_TEXTEDIT_K_DELETE, STB_TEXTEDIT_K_DOWN, STB_TEXTEDIT_K_LEFT, STB_TEXTEDIT_K_LINEEND, STB_TEXTEDIT_K_LINESTART, STB_TEXTEDIT_K_PGDOWN, STB_TEXTEDIT_K_PGUP, STB_TEXTEDIT_K_REDO, STB_TEXTEDIT_K_RIGHT, STB_TEXTEDIT_K_SHIFT, STB_TEXTEDIT_K_TEXTEND
local ImGui, ImVec2, ImVec4, ImRect, HelpMarker, ImVec2_Copy, IMGUI_DEMO_MARKER, ImGuiTableFlags, ImStd, ImVector, ImGuiKey, ImGuiInputFlags, ImRect_Copy, ImGuiDataType, ImStb, IM_TRUNC, ImGuiStyleVarInfo, ImVec2_CopyV, IM_ASSERT_USER_ERROR, ImGuiHoveredFlags, ImFormatString, ImHashStr, ImS32, IM_ASSERT_USER_ERROR_RET, ImGuiColorEditFlags, ImDrawFlags, ImIsPowerOfTwo, ImVec4_Copy, ExampleAppConsoleMT, IM_ROUND, ImGuiTableColumnFlags, ImGuiTreeNodeFlags, PopStyleCompact, PushStyleCompact, ImU16, ImAbs, ImGuiWindowFlags, ImGuiItemFlags, stbte, ImGuiButtonFlags, ImGuiDebugLogFlags, ImGuiLocKey, ImU32, ImColor, ImCos, ImS16, ImGuiTabBarFlags, ImSin, ImUpperPowerOfTwo, ImVec2_MulVX, IM_F32_TO_INT8_SAT, ImFontAtlasPackGetRect, ImGuiMouseCursor, DockSettingsRenameNodeReferences, IM_ASSERT_PARANOID, ImCeil, ImGuiCol, ImGuiListClipper, ImLengthSqr, ImS8, ImU8, _PathArcToFastExXY, ExampleAppPropertyEditorMT, ImFabs, ImGuiScrollFlags, ImGui_ImplLOVE_GetBackendData, ImLog, ImPow, CustomConstraints, ExampleAppLogMT, IMGUI_DEBUG_LOG_FONT, ImFontAtlasBuildInit, ImFontCalcWordWrapPositionEx, ImGuiComboFlags, ImGuiPopupFlags, ImGuiSliderFlags, ImTextClassifierSetCharClass, ImVec2_AddVA, ImVec2_SubVA, MyDocument, ShowExampleMenuFile, ImFontAtlasBakedAddFontGlyph, ImFontAtlasPackAddRect, ImFontBaked_BuildLoadGlyph, ImGuiInputTextFlags, ImGuiStyle_Copy, ExampleMemberInfo, ExampleTree_CreateNode, ImFontAtlasBuildRenderBitmapFromString, ImFontAtlasFontDestroyOutput, ImFontAtlasFontSourceAddToFont, ImFontAtlasFontSourceInit, ImGuiTableColumn, MyItem_s_current_sort_specs, stb_textedit_key, stbtt_GetGlyphBitmapBoxSubpixel, EditTableSizingFlags, IM_FREE, ImDrawListSplitter, ImGuiDragDropFlags, MyItemColumnID_ID, MyItemColumnID_Name, MyItemColumnID_Quantity, stb_text_locate_coord, stb_text_makeundo_insert, stb_text_makeundo_replace, stb_textedit_find_charpos, stbtt_GetGlyphShape, EditTabBarFittingPolicyFlags, ExampleImageViewerData, ImGuiTableColumnSortSpecs, ImGuiTableInstanceData, ImGuiTableSettings, stb_text_makeundo_delete, stb_text_redo, stb_text_undo, stb_textedit_click, stb_textedit_drag, stbtt_FindGlyphIndex, stbtt_GetFontOffsetForIndex, stbtt_GetFontVMetrics, stbtt_GetGlyphBitmapBox, stbtt_GetGlyphHMetrics, stbtt_InitFont, stbtt_MakeGlyphBitmapSubpixelPrefilter, stbtt_ScaleForPixelHeight, stbtt__GetGlyphInfoT2, stbtt__GetGlyphShapeT2, stbtt_fontinfo, ImGuiOldColumnData, ImGuiOldColumnFlags, ImGuiOldColumns, ImGuiTable, ImGuiTableColumnSettings, ImGuiTableSortSpecs, ImGuiTableTempData, ImGui_ImplLOVE_CreateTexture, ImGui_ImplLOVE_DestroyTexture, ImGui_ImplLOVE_Init, ImGui_ImplLOVE_NewFrame, ImGui_ImplLOVE_RenderDrawData, ImGui_ImplLOVE_Shutdown, ImGui_ImplLOVE_UpdateTexture, stbrp_init_target, IMGUI_TABLE_MAX_COLUMNS, IMSTB_TEXTEDIT_UNDOSTATECOUNT, IM_COL32_DISABLE, ImGui_ImplLove, STB_TEXTEDIT_K_BACKSPACE, STB_TEXTEDIT_K_DELETE, STB_TEXTEDIT_K_DOWN, STB_TEXTEDIT_K_LEFT, STB_TEXTEDIT_K_LINEEND, STB_TEXTEDIT_K_LINESTART, STB_TEXTEDIT_K_PGDOWN, STB_TEXTEDIT_K_PGUP, STB_TEXTEDIT_K_REDO, STB_TEXTEDIT_K_RIGHT, STB_TEXTEDIT_K_SHIFT, STB_TEXTEDIT_K_TEXTEND
local type, mathMin, mathMax, mathFloor, mathCeil, bitOr, bitLShift = type, math.min, math.max, math.floor, math.ceil, bit32.bor, bit32.lshift
local function IM_COL32(R, G, B, A) return (bitOr(bitLShift(A, 24 --[[IM_COL32_A_SHIFT]]), bitLShift(B, 16 --[[IM_COL32_B_SHIFT]]), bitLShift(G, 8 --[[IM_COL32_G_SHIFT]]), bitLShift(R, 0 --[[IM_COL32_R_SHIFT]]))) end
@@ -9664,10 +9664,13 @@ function ImGui.SetItemKeyOwner(key, flags)
end
-- This is equivalent to comparing KeyMods + doing a IsKeyPressed()
-- [Port] public overload IsKeyChordPressed(key_chord) == IsKeyChordPressed(key_chord, ImGuiInputFlags_None, ImGuiKeyOwner_Any)
--- @param key_chord ImGuiKeyChord
--- @param flags ImGuiInputFlags
--- @param owner_id ImGuiID
--- @param flags? ImGuiInputFlags
--- @param owner_id? ImGuiID
function ImGui.IsKeyChordPressed(key_chord, flags, owner_id)
if flags == nil then flags = 0 --[[ImGuiInputFlags.None]] end
if owner_id == nil then owner_id = 0 --[[ImGuiKeyOwner_Any]] end
local g = GImGui
key_chord = ImGui.FixupKeyChord(key_chord)
local mods = bit32.band(key_chord, 61440 --[[ImGuiMod_Mask_]])
@@ -9697,10 +9700,13 @@ function ImGui.SetNextItemShortcut(key_chord, flags)
g.NextItemData.ShortcutFlags = flags
end
-- [Port] public overload Shortcut(key_chord, flags = 0) == Shortcut(key_chord, flags, ImGuiKeyOwner_Any)
--- @param key_chord ImGuiKeyChord
--- @param flags ImGuiInputFlags
--- @param owner_id ImGuiID
--- @param flags? ImGuiInputFlags
--- @param owner_id? ImGuiID
function ImGui.Shortcut(key_chord, flags, owner_id)
if flags == nil then flags = 0 end
if owner_id == nil then owner_id = 0 --[[ImGuiKeyOwner_Any]] end
local g = GImGui
-- IMGUI_DEBUG_LOG("Shortcut(%s, flags=%X, owner_id=0x%08X)\n", ImGui.GetKeyChordName(key_chord, g.TempBuffer.Data, g.TempBuffer.Size), flags, owner_id)
@@ -12927,6 +12933,17 @@ function ImGui.Begin(name, open, flags)
end
if open == nil then open = true end
-- [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 not window.IsFallbackWindow then
if (g.IO.ConfigDebugBeginReturnValueOnce and window_just_created) or (g.IO.ConfigDebugBeginReturnValueLoop and g.DebugBeginReturnValueCullDepth == g.CurrentWindowStack.Size) then
if window.AutoFitFramesX > 0 then window.AutoFitFramesX = window.AutoFitFramesX + 1 end
if window.AutoFitFramesY > 0 then window.AutoFitFramesY = window.AutoFitFramesY + 1 end
return open, false
end
end
return open, not window.SkipItems
end
@@ -14212,6 +14229,14 @@ function ImGui.NewFrame()
g.ErrorCountCurrentFrame = 0
g.StackSizesInNewFrame = g.StackSizesInNewFrame or ImGuiErrorRecoveryState()
ImGui.ErrorRecoveryStoreState(g.StackSizesInNewFrame)
-- [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.
if g.IO.ConfigDebugBeginReturnValueLoop then
g.DebugBeginReturnValueCullDepth = (g.DebugBeginReturnValueCullDepth == -1) and 0 or ((g.DebugBeginReturnValueCullDepth + (((g.FrameCount % 4) == 0) and 1 or 0)) % 10)
else
g.DebugBeginReturnValueCullDepth = -1
end
end
-- This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal.
@@ -14632,9 +14657,10 @@ end
--- @param pos ImVec2
--- @param items_height float
function ImGui.CalcClipRectVisibleItemsY(clip_rect, pos, items_height)
local visible_start = ImMax(ImTrunc((clip_rect.Min.y - pos.y) / items_height), 0)
local visible_end = ImMax(ImTrunc(ImCeil((clip_rect.Max.y - pos.y) / items_height)), visible_start)
return visible_start + 1, visible_end + 1
-- [Port] returns (out_visible_start, out_visible_end), 0-based like upstream
local out_visible_start = ImMax(ImTrunc((clip_rect.Min.y - pos.y) / items_height), 0)
local out_visible_end = ImMax(ImTrunc(ImCeil((clip_rect.Max.y - pos.y) / items_height)), out_visible_start)
return out_visible_start, out_visible_end
end
-------------------------------------------------------------------------------
@@ -19924,14 +19950,6 @@ function MT.ImGuiListClipper:Step()
return ret
end
-- Generic helper, equivalent to old ImGui.CalcListClipping() but stateless
-- Returns (out_visible_start, out_visible_end)
function ImGui.CalcClipRectVisibleItemsY(clip_rect, pos, items_height)
local out_visible_start = ImMax(ImTrunc((clip_rect.Min.y - pos.y) / items_height), 0)
local out_visible_end = ImMax(ImTrunc(ImCeil((clip_rect.Max.y - pos.y) / items_height)), out_visible_start)
return out_visible_start, out_visible_end
end
-------------------------------------------------------------------------------
-- [SECTION] ERROR CHECKING, STATE RECOVERY
-------------------------------------------------------------------------------
@@ -21246,7 +21264,7 @@ function ImGui.ShowMetricsWindow(p_open)
_, g.DebugShowGroupRects = ImGui.Checkbox("Show groups rectangles", g.DebugShowGroupRects == true) -- Storing in context as this is used by group code and prefers to be in hot-data
ImGui.SeparatorText("Validate")
_, io.ConfigDebugBeginReturnValueLoop = ImGui.Checkbox("Debug Begin/BeginChild return value", io.ConfigDebugBeginReturnValueLoop == true)
_, io.ConfigDebugBeginReturnValueLoop = ImGui.Checkbox("Debug Begin/BeginChild return value", io.ConfigDebugBeginReturnValueLoop)
ImGui.SameLine(); MetricsHelpMarker("Some calls to Begin()/BeginChild() will return false.\n\nWill cycle through window depths then repeat. Windows should be flickering while running.")
_, cfg.ShowTextEncodingViewer = ImGui.Checkbox("UTF-8 Encoding viewer", cfg.ShowTextEncodingViewer == true)
ImGui.SameLine(); MetricsHelpMarker("You can also call ImGui::DebugTextEncoding() from your code with a given string to test that your UTF-8 encoding settings are correct.")
@@ -22719,10 +22737,6 @@ end
-- [SECTION] DemoWindowWidgetsColorAndPickers()
-------------------------------------------------------------------------------
-- [Port] the library does not define the standard color payload types (ColorButton drag source is not ported yet)
IMGUI_PAYLOAD_TYPE_COLOR_3F = IMGUI_PAYLOAD_TYPE_COLOR_3F or "_COL3F"
IMGUI_PAYLOAD_TYPE_COLOR_4F = IMGUI_PAYLOAD_TYPE_COLOR_4F or "_COL4F"
S.DemoWindowWidgetsColorAndPickers = {
color = ImVec4(114.0 / 255.0, 144.0 / 255.0, 154.0 / 255.0, 200.0 / 255.0),
base_flags = ImGuiColorEditFlags.None,
@@ -22832,7 +22846,7 @@ function DemoWindowWidgetsColorAndPickers()
if ImGui.BeginDragDropTarget() then
local payload = ImGui.AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)
if payload then
local d = payload.Data -- [Port] memcpy -> copy components (Data is a 1-based float array or ImVec4)
local d = payload.Data -- [Port] memcpy -> copy components (Data is a 1-based float array)
saved_palette[n + 1].x, saved_palette[n + 1].y, saved_palette[n + 1].z = d[1], d[2], d[3]
end
payload = ImGui.AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)
@@ -28846,9 +28860,8 @@ function DemoWindowInputs()
local line_height = ImGui.GetTextLineHeightWithSpacing()
local key_chord = bit32.bor(4096 --[[ImGuiMod_Ctrl]], 546 --[[ImGuiKey.A]])
-- [Port] ImGui.Shortcut() has no owner_id default (upstream public overload passes ImGuiKeyOwner_Any): pass it explicitly.
ImGui.Text("Ctrl+A")
ImGui.Text("IsWindowFocused: %d, Shortcut: %s", ImGui.IsWindowFocused() and 1 or 0, ImGui.Shortcut(key_chord, flags, 0 --[[ImGuiKeyOwner_Any]]) and "PRESSED" or "...")
ImGui.Text("IsWindowFocused: %d, Shortcut: %s", ImGui.IsWindowFocused() and 1 or 0, ImGui.Shortcut(key_chord, flags) and "PRESSED" or "...")
ImGui.PushStyleColor(3 --[[ImGuiCol.ChildBg]], ImVec4(1.0, 0.0, 1.0, 0.1))
@@ -28858,7 +28871,7 @@ function DemoWindowInputs()
-- 1: Window polling for Ctrl+A
ImGui.Text("(in WindowA)")
ImGui.Text("IsWindowFocused: %d, Shortcut: %s", ImGui.IsWindowFocused() and 1 or 0, ImGui.Shortcut(key_chord, flags, 0 --[[ImGuiKeyOwner_Any]]) and "PRESSED" or "...")
ImGui.Text("IsWindowFocused: %d, Shortcut: %s", ImGui.IsWindowFocused() and 1 or 0, ImGui.Shortcut(key_chord, flags) and "PRESSED" or "...")
-- 2: InputText also polling for Ctrl+A: it always uses _RouteFocused internally (gets priority when active)
-- (Commented because the owner-aware version of Shortcut() is still in imgui_internal.h)
@@ -28878,7 +28891,7 @@ function DemoWindowInputs()
-- 4: Child window polling for Ctrl+A. It is deeper than WindowA and gets priority when focused.
ImGui.BeginChild("ChildE", ImVec2(-1.1754943508223e-38 --[[FLT_MIN]], line_height * 4), true)
ImGui.Text("(in ChildE: using same Shortcut)")
ImGui.Text("IsWindowFocused: %d, Shortcut: %s", ImGui.IsWindowFocused() and 1 or 0, ImGui.Shortcut(key_chord, flags, 0 --[[ImGuiKeyOwner_Any]]) and "PRESSED" or "...")
ImGui.Text("IsWindowFocused: %d, Shortcut: %s", ImGui.IsWindowFocused() and 1 or 0, ImGui.Shortcut(key_chord, flags) and "PRESSED" or "...")
ImGui.EndChild()
-- 5: In a popup
@@ -28887,7 +28900,7 @@ function DemoWindowInputs()
end
if ImGui.BeginPopup("PopupF") then
ImGui.Text("(in PopupF)")
ImGui.Text("IsWindowFocused: %d, Shortcut: %s", ImGui.IsWindowFocused() and 1 or 0, ImGui.Shortcut(key_chord, flags, 0 --[[ImGuiKeyOwner_Any]]) and "PRESSED" or "...")
ImGui.Text("IsWindowFocused: %d, Shortcut: %s", ImGui.IsWindowFocused() and 1 or 0, ImGui.Shortcut(key_chord, flags) and "PRESSED" or "...")
-- (Commented because the owner-aware version of Shortcut() is still in imgui_internal.h)
--ImGui.InputText("InputTextG", str, IM_COUNTOF(str), ImGuiInputTextFlags.ReadOnly);
--ImGui.Text("IsWindowFocused: %d, Shortcut: %s", ImGui.IsWindowFocused(), ImGui.Shortcut(key_chord, flags, ImGui.GetItemID()) ? "PRESSED" : "...");
@@ -29266,7 +29279,7 @@ function ImGui.ShowStyleEditor(ref)
end
ImGui.SameLine(0.0, 0.0); ImGui.Text(" (out %.2f)", ImGui.GetFontSize())
style.FontScaleMain = ImGui.DragFloat("FontScaleMain", style.FontScaleMain, 0.02, 0.5, 4.0)
ImGui.BeginDisabled(ImGui.GetIO().ConfigDpiScaleFonts == true) -- [Port] field is nil in the port's ImGuiIO (nil would mean "disabled")
ImGui.BeginDisabled(ImGui.GetIO().ConfigDpiScaleFonts)
style.FontScaleDpi = ImGui.DragFloat("FontScaleDpi", style.FontScaleDpi, 0.02, 0.5, 4.0)
ImGui.SetItemTooltip("When io.ConfigDpiScaleFonts is set, this value is automatically overwritten.")
ImGui.EndDisabled()
@@ -29518,7 +29531,7 @@ function ImGui.ShowStyleEditor(ref)
_, style.AntiAliasedFill = ImGui.Checkbox("Anti-aliased fill", style.AntiAliasedFill)
local io = ImGui.GetIO()
_, io.ConfigDebugDrawListDefaultsToStrokeLegacy = ImGui.Checkbox("Debug: DrawList Defaults to _StrokeLegacy", io.ConfigDebugDrawListDefaultsToStrokeLegacy == true) -- [Port] field not declared in the port's ImGuiIO
_, io.ConfigDebugDrawListDefaultsToStrokeLegacy = ImGui.Checkbox("Debug: DrawList Defaults to _StrokeLegacy", io.ConfigDebugDrawListDefaultsToStrokeLegacy)
ImGui.PushItemWidth(ImGui.GetFontSize() * 8)
-- [Port] the library still stores the older style.CurveTessellationTol (== MaxError * MaxError) instead of style.CurveTessellationMaxError
@@ -39105,6 +39118,9 @@ function ImGuiIO()
DisplayFramebufferScale = ImVec2(1.0, 1.0), -- = (1, 1) -- Main display density. For retina display where window coordinates are different from framebuffer coordinates. This will affect font density + will end up in ImDrawData::FramebufferScale.
-- Font system
FontAllowUserScaling = false, -- = false -- Allow user scaling text of individual window with Ctrl+Wheel.
-- Main Input State
-- (this block used to be written by backend, since 1.87 it is best to NOT write to those directly, call the AddXXX functions above instead)
-- (reading from those variables is fair game, as they are extremely unlikely to be moving anywhere)
@@ -39136,6 +39152,25 @@ function ImGuiIO()
ConfigDebugIniSettings = false, -- = false -- Save .ini data with extra comments (particularly helpful for Docking, but makes saving slower)
ConfigWindowsCopyContentsWithCtrlC = false, -- = false -- [EXPERIMENTAL] Ctrl+C copy the contents of focused window into the clipboard. Experimental because: (1) has known issues with nested Begin/End pairs (2) text output quality varies (3) text output is in submission order rather than spatial order.
ConfigWindowsMoveFromTitleBarOnly = false, -- = false -- Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar.
ConfigScrollbarScrollByPage = true, -- = true -- Enable scrolling page by page when clicking outside the scrollbar grab. When disabled, always scroll to clicked location. When enabled, Shift+Click scrolls to clicked location.
ConfigInputTextCursorBlink = true, -- = true -- Enable blinking cursor (optional as some users consider it to be distracting).
ConfigInputTextEnterKeepActive = false, -- = false -- [BETA] Pressing Enter will reactivate item and select all text (single-line only). Ctrl+Enter or Shift+Enter will deactivate normally.
ConfigDragClickToInputText = false, -- = false -- [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.
-- Keyboard/Gamepad Navigation options
ConfigNavSwapGamepadButtons = false, -- = false -- Swap Activate<>Cancel (A<>B) buttons, matching typical "Nintendo/Japanese style" gamepad layout.
ConfigNavMoveSetMousePos = false, -- = false -- Directional/tabbing navigation teleports the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is difficult. Will update io.MousePos and set io.WantSetMousePos=true.
ConfigNavCaptureKeyboard = true, -- = true -- Sets io.WantCaptureKeyboard when io.NavActive is set.
ConfigNavEscapeClearFocusItem = true, -- = true -- Pressing Escape can clear focused item + navigation id/highlight. Set to false if you want to always keep highlight on.
ConfigNavEscapeClearFocusWindow = false, -- = false -- Pressing Escape can clear focused window as well (super set of io.ConfigNavEscapeClearFocusItem).
-- DPI/Scaling options
ConfigDpiScaleFonts = false, -- = false -- [EXPERIMENTAL] Automatically overwrite style.FontScaleDpi when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
ConfigDpiScaleViewports = false, -- = false -- [EXPERIMENTAL] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
-- Ini Settings options
ConfigIniSettingsSaveLastUsedDate = true, -- = true -- Enable loading/saving last used day (YYYYMMDD) in some .ini struct, making things easier to audit and allowing custom tools to cleanup old data.
ConfigIniSettingsAutoDiscardMonths = 0, -- = 0 -- [BETA] Set number of months after which unused .ini entries are discarded on load. Require platform_io.Platform_SessionDate to be set. For systems supporting the feature, .ini entries without a LastUsed field will always be discarded! Please report if you are using this.
-- Options to configure Error Handling and how we handle recoverable errors [EXPERIMENTAL]
-- - Error recovery is provided as a way to facilitate:
-- - Recovery after a programming error (native code or scripting language - the latter tends to facilitate iterating on code while running).
@@ -39160,6 +39195,14 @@ function ImGuiIO()
-- - See FAQ https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-about-the-id-stack-system
ConfigDebugHighlightIdConflicts = false, -- Highlight and show an error message popup when multiple items have conflicting identifiers.
ConfigDebugHighlightIdConflictsShowItemPicker = true, -- =true -- Show "Item Picker" button in aforementioned popup.
ConfigDebugIsDebuggerPresent = false, -- = false -- Enable various tools calling IM_DEBUG_BREAK().
-- Tools to test correct Begin/End and BeginChild/EndChild behaviors.
ConfigDebugBeginReturnValueOnce = false, -- = false -- First-time calls to Begin()/BeginChild() will return false. NEEDS TO BE SET AT APPLICATION BOOT TIME if you don't want to miss windows.
ConfigDebugBeginReturnValueLoop = false, -- = false -- Some calls to Begin()/BeginChild() will return false. Will cycle through window depths then repeat. Suggested use: add "io.ConfigDebugBeginReturnValue = io.KeyShift" in your main loop then occasionally press SHIFT. Windows should be flickering while running.
-- Option to deactivate io.AddFocusEvent(false) handling.
ConfigDebugIgnoreFocusLoss = false, -- = false -- Ignore io.AddFocusEvent(false), consequently not calling io.ClearInputKeys()/io.ClearInputMouse() in input processing.
-- Option to default all ImDrawList to ImDrawListFlags_StrokeLegacy mode.
ConfigDebugDrawListDefaultsToStrokeLegacy = false, -- false -- Default all ImDrawList to ImDrawList_StrokeLegacy mode, mimicking pre-1.93.0 rendering. [Port] the 1.93 stroke rendering is not ported yet: no effect.
IniFilename = "imgui.ini", -- Roblox: no disk access, only used as a flag (nil disables .ini handling)
IniSavingRate = 5.0, -- = 5.0f -- Minimum time between saving positions/sizes to .ini file, in seconds.
@@ -40026,6 +40069,10 @@ ImGuiDragDropFlags = {
ImGuiDragDropFlags.AcceptPeekOnly = bitOr(ImGuiDragDropFlags.AcceptBeforeDelivery, ImGuiDragDropFlags.AcceptNoDrawDefaultRect) -- For peeking ahead and inspecting the payload before delivery.
-- Standard Drag and Drop payload types. You can define you own payload types using short strings. Types starting with '_' are defined by Dear ImGui.
IMGUI_PAYLOAD_TYPE_COLOR_3F = "_COL3F" -- float[3]: Standard type for colors, without alpha. User code may use this type. [Port] payload.Data = { r, g, b } (1-based)
IMGUI_PAYLOAD_TYPE_COLOR_4F = "_COL4F" -- float[4]: Standard type for colors. User code may use this type. [Port] payload.Data = { r, g, b, a } (1-based)
-- Helpers macros to generate 32-bit encoded colors
IM_COL32_R_SHIFT = 0
IM_COL32_G_SHIFT = 8
@@ -42897,12 +42944,14 @@ IMGUI_TEXT_INDEX.__index = IMGUI_TEXT_INDEX
function IMGUI_TEXT_INDEX:clear() self.Offsets:clear(); self.EndOffset = 0; end
function IMGUI_TEXT_INDEX:size() return self.Offsets.Size end
-- [Port] 'n' is a 0-based line number like upstream (Offsets.Data is 1-based), 'base' the 1-based position of the buffer start; returns 1-based positions
function IMGUI_TEXT_INDEX:get_line_begin(base, n)
return base + (self.Offsets.Size ~= 0 and self.Offsets[n] or 0)
return base + (self.Offsets.Size ~= 0 and self.Offsets.Data[n + 1] or 0)
end
function IMGUI_TEXT_INDEX:get_line_end(base, n)
return base + ((n + 1 < self.Offsets.Size) and (self.Offsets[n + 1] - 1) or self.EndOffset)
return base + ((n + 1 < self.Offsets.Size) and (self.Offsets.Data[n + 2] - 1) or self.EndOffset)
end
--- @return ImGuiTextIndex
@@ -43306,7 +43355,7 @@ function ImGuiContext(shared_font_atlas) -- TODO: tidy up / complete this struct
NavActivateId = 0, NavActivateDownId = 0, NavActivatePressedId = 0, -- ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey.Space) || IsKeyDown(ImGuiKey.Enter) || IsKeyPressed(ImGuiKey.NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItemByID()
NavActivateFlags = 0 --[[ImGuiActivateFlags.None]],
FrameCount = -1,
FrameCount = 0,
FrameCountEnded = -1,
FrameCountPlatformEnded = -1,
@@ -43479,6 +43528,7 @@ function ImGuiContext(shared_font_atlas) -- TODO: tidy up / complete this struct
DebugLogFlags = bitOr(1 --[[ImGuiDebugLogFlags.EventError]], 1048576 --[[ImGuiDebugLogFlags.OutputToTTY]]),
DebugFlashStyleColorIdx = nil,
DebugBeginReturnValueCullDepth = -1, -- Cycle between 0..9 then wrap around.
DebugMetricsConfig = ImGuiMetricsConfig(),
DebugHookIdInfoId = 0, -- Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool
@@ -54777,34 +54827,37 @@ end
--- @param flags ImGuiInputTextFlags
--- @param line_index ImGuiTextIndex
--- @param buf char[]
--- @param buf_end int
--- @param buf_end? int # nil: inactive multi-line path, end found with strchr()
--- @param wrap_width float
--- @param max_output_buffer_size int
--- @param want_out_buf_end boolean
--- @return int size
--- @return int? out_buf_end
local function InputTextLineIndexBuild(flags, line_index, buf, buf_end, wrap_width, max_output_buffer_size)
--- @return int? out_buf_end # [Port] 'const char** out_buf_end' output parameter becomes a 2nd return value (nil when not requested)
local function InputTextLineIndexBuild(flags, line_index, buf, buf_end, wrap_width, max_output_buffer_size, want_out_buf_end)
local g = GImGui
local size = 0
local s = 1
local s
local trailing_line_already_counted = false
-- [Port] 's' is a 1-based position in 'buf' (C++ s == buf + (s - 1)), Offsets store 0-based offsets like upstream.
if bit32.band(flags, 16777216 --[[ImGuiInputTextFlags.WordWrap]]) ~= 0 then
s = 1
while s < buf_end do
if size <= max_output_buffer_size then
line_index.Offsets:push_back(s - 1)
end
size = size + 1
s = ImFontCalcWordWrapPositionEx(g.Font, g.FontSize, buf, s, buf_end, wrap_width, 2 --[[ImDrawTextFlags.WrapKeepBlanks]])
if buf[s] == 10 then s = s + 1 end
end
elseif buf_end ~= nil then
s = 1
while s < buf_end do
if size <= max_output_buffer_size then
line_index.Offsets:push_back(s - 1)
end
size = size + 1
s = ImMemchr(buf, 10, s) --[[@as int]] -- FIXME:
s = ImMemchr(buf, 10, s)
if s ~= nil and s >= buf_end then s = nil end -- [Port] ImMemchr() stops at the zero-terminator, not at buf_end
if s then s = s + 1 else s = buf_end end
end
else
@@ -54816,20 +54869,17 @@ local function InputTextLineIndexBuild(flags, line_index, buf, buf_end, wrap_wid
line_index.Offsets:push_back(s - 1)
end
size = size + 1
s_eol = ImMemchr(buf, 10, s)
if s_eol == nil then
s = s + ImStd.ImStrlen(buf) - s -- FIXME:
s = s + ImStd.ImStrlen(buf, s)
trailing_line_already_counted = true
break
end
s = s_eol + 1
end
end
local out_buf_end
if out_buf_end ~= nil then
local out_buf_end = nil
if want_out_buf_end then
out_buf_end = s
buf_end = s
end
@@ -54837,11 +54887,11 @@ local function InputTextLineIndexBuild(flags, line_index, buf, buf_end, wrap_wid
line_index.Offsets:push_back(0)
size = size + 1
end
if s > 1 and buf[s - 1] == 10 and not trailing_line_already_counted then
if buf_end > 1 and buf[buf_end - 1] == 10 and not trailing_line_already_counted then
local old_size = size
size = size + 1
if old_size <= max_output_buffer_size then
line_index.Offsets:push_back(s - 1)
line_index.Offsets:push_back(buf_end - 1)
end
end
return size, out_buf_end
@@ -54880,24 +54930,24 @@ end
--- @param cursor_n int
--- @return ImVec2
local function InputTextLineIndexGetPosOffset(g, state, line_index, buf, buf_end, cursor_n)
-- [Port] 'cursor_n' is a 1-based position (Stb.cursor) == C++ cursor_ptr; Offsets hold 0-based offsets, compare with cursor_n - 1.
local cursor_ptr = cursor_n
local it = ImLowerBound(line_index.Offsets, 1, line_index.Offsets.Size + 1, cursor_ptr)
if it > 1 then
if it > line_index.Offsets.Size or line_index.Offsets[it] ~= cursor_ptr or (state ~= nil and state.WrapWidth > 0.0 and state.LastMoveDirectionLR == 1 --[[ImGuiDir.Right]] and
buf[cursor_ptr - 1] ~= 10 and buf[cursor_ptr - 1] ~= 0) then
local cursor_off = cursor_n - 1
local offsets = line_index.Offsets
local it_begin = 1
local it_end = offsets.Size + 1
local it = ImLowerBound(offsets.Data, it_begin, it_end, cursor_off)
if it > it_begin then
if it == it_end or offsets.Data[it] ~= cursor_off or (state ~= nil and state.WrapWidth > 0.0 and state.LastMoveDirectionLR == 1 --[[ImGuiDir.Right]] and buf[cursor_ptr - 1] ~= 10 and buf[cursor_ptr - 1] ~= 0) then
it = it - 1
end
end
local line_no = it
local line_start = (line_no == 1) and 1 or line_index.Offsets[line_no] + 1
local line_no = (it == it_begin) and 0 or (it - 1) -- 0-based (index_from_ptr)
local line_start = line_index:get_line_begin(1, line_no)
local offset = ImVec2()
offset.x = InputTextCalcTextSize(g, buf, line_start, cursor_ptr, buf_end, nil, 2 --[[ImDrawTextFlags.WrapKeepBlanks]]).x
offset.y = line_no * g.FontSize
offset.y = (line_no + 1) * g.FontSize
return offset
end
@@ -55628,7 +55678,7 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
-- Write back result string if modified.
-- FIXME-OPT: Could mark dirty state from the stb_textedit callbacks
if not is_readonly then
if bit32.band(g.LastItemData.ItemFlags, 256 --[[ImGuiItemFlags.LiveEditOnInputScalar]]) ~= 0 then
if bit32.band(g.LastItemData.ItemFlags, 128 --[[ImGuiItemFlags.LiveEditOnInputText]]) ~= 0 then
-- Apply when modified
if (ImStd.strcmp(state.TextSrc, buf) ~= 0) then
apply_new_text = state.TextSrc
@@ -55747,7 +55797,7 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
end
-- Calculate visibility
local line_visible_n0, line_visible_n1 = 1, 2
local line_visible_n0, line_visible_n1 = 0, 1 -- 0-based like upstream
if is_multiline then
line_visible_n0, line_visible_n1 = ImGui.CalcClipRectVisibleItemsY(clip_rect, draw_pos, g.FontSize)
end
@@ -55760,15 +55810,15 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
-- If scrolling is expected to change build full index.
-- FIXME-OPT: Could append to index when new value of line_visible_n1 becomes bigger, see second call to CalcClipRectVisibleItemsY() below.
local will_scroll_y = state and ((state.CursorFollow and render_cursor) or (state.CursorCenterY and (render_cursor or render_selection)))
--- @cast buf_display_end int
local out_buf_end
line_count, out_buf_end = InputTextLineIndexBuild(flags, line_index, buf_display, buf_display_end, wrap_width, will_scroll_y and 2147483647 --[[INT_MAX]] or (line_visible_n1 + 1))
if buf_display_end then
line_count, out_buf_end = InputTextLineIndexBuild(flags, line_index, buf_display, buf_display_end, wrap_width, will_scroll_y and 2147483647 --[[INT_MAX]] or (line_visible_n1 + 1), buf_display_end == nil)
if buf_display_end == nil then
buf_display_end = out_buf_end
end
end
--- @cast buf_display_end int
line_index.EndOffset = buf_display_end - 1
line_visible_n1 = ImMin(line_visible_n1, line_count + 1)
line_visible_n1 = ImMin(line_visible_n1, line_count)
-- Store text height (we don't need width)
local text_size_y = line_count * g.FontSize
@@ -55869,7 +55919,7 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
local rect = ImRect()
rect.Min.x = draw_pos.x - draw_scroll.x + ImGui.CalcTextSizeEx(buf_display, p, line_selected_begin).x
rect.Min.y = draw_pos.y - draw_scroll.y + (line_n - 1) * g.FontSize
rect.Min.y = draw_pos.y - draw_scroll.y + line_n * g.FontSize
rect.Max.x = rect.Min.x + rect_width
rect.Max.y = rect.Min.y + bg_offy_dn + g.FontSize
rect.Min.y = rect.Min.y + bg_offy_up
@@ -55890,7 +55940,7 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
-- Render text
if (is_multiline or (buf_display_end - 1) < buf_display_max_length) and bit32.band(text_col, 4278190080 --[[IM_COL32_A_MASK]]) ~= 0 and line_visible_n0 < line_visible_n1 then
g.Font:RenderText(draw_window.DrawList, g.FontSize,
draw_pos - draw_scroll + ImVec2(0.0, (line_visible_n0 - 1) * g.FontSize),
draw_pos - draw_scroll + ImVec2(0.0, line_visible_n0 * g.FontSize),
text_col, clip_rect:AsVec4(),
buf_display,
line_index:get_line_begin(1, line_visible_n0),
@@ -56308,7 +56358,28 @@ function ImGui.ColorEdit4(label, col, flags)
ImGui.EndGroup()
-- Drag and Drop Target
-- TODO:
-- NB: The flag test is merely an optional micro-optimization, BeginDragDropTarget() does the same test.
if bit32.band(g.LastItemData.StatusFlags, 1 --[[ImGuiItemStatusFlags.HoveredRect]]) ~= 0 and bit32.band(g.LastItemData.ItemFlags, 2048 --[[ImGuiItemFlags.ReadOnly]]) == 0 and bit32.band(flags, 512 --[[ImGuiColorEditFlags.NoDragDrop]]) == 0 and ImGui.BeginDragDropTarget() then
local accepted_drag_drop = false
local payload = ImGui.AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)
if payload then
local d = payload.Data
col[1], col[2], col[3] = d[1], d[2], d[3] -- Preserve alpha if any
value_changed = true; accepted_drag_drop = true
end
payload = ImGui.AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)
if payload then
local d = payload.Data
for i = 1, components do col[i] = d[i] end
value_changed = true; accepted_drag_drop = true
end
-- Drag-drop payloads are always RGB
if accepted_drag_drop and bit32.band(flags, 536870912 --[[ImGuiColorEditFlags.InputHSV]]) ~= 0 then
col[1], col[2], col[3] = ImGui.ColorConvertRGBtoHSV(col[1], col[2], col[3])
end
ImGui.EndDragDropTarget()
end
-- When picker is being actively used, use its active id so IsItemActive() will function on ColorEdit4().
if picker_active_window and g.ActiveId ~= 0 and g.ActiveIdWindow == picker_active_window then
@@ -56877,17 +56948,20 @@ function ImGui.ColorButton(desc_id, col, flags, size_arg)
-- Drag and Drop Source
-- NB: The ActiveId test is merely an optional micro-optimization, BeginDragDropSource() does the same test.
-- if g.ActiveId == id and bit32.band(flags, ImGuiColorEditFlags.NoDragDrop) == 0 and ImGui.BeginDragDropSource() then
-- if bit32.band(flags, ImGuiColorEditFlags.NoAlpha) ~= 0 then
-- ImGui.SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F, col_rgb, ImGuiCond.Once)
-- else
-- ImGui.SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, col_rgb, ImGuiCond.Once)
-- end
-- ImGui.ColorButton(desc_id, col, flags)
-- ImGui.SameLine()
-- ImGui.TextEx("Color")
-- ImGui.EndDragDropSource()
-- end
-- [Port] payload.Data is a 1-based float array copy { r, g, b [, a] } (C++ memcpy of float[3]/float[4])
if g.ActiveId == id and bit32.band(flags, 512 --[[ImGuiColorEditFlags.NoDragDrop]]) == 0 and ImGui.BeginDragDropSource() then
if bit32.band(flags, 2 --[[ImGuiColorEditFlags.NoAlpha]]) ~= 0 then
ImGui.SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F, { col_rgb.x, col_rgb.y, col_rgb.z }, 3, 2 --[[ImGuiCond.Once]])
else
ImGui.SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, { col_rgb.x, col_rgb.y, col_rgb.z, col_rgb.w }, 4, 2 --[[ImGuiCond.Once]])
end
ImGui.PushItemFlag(4096 --[[ImGuiItemFlags.MixedValue]], false)
ImGui.ColorButton(desc_id, col, flags)
ImGui.PopItemFlag()
ImGui.SameLine()
ImGui.TextEx("Color")
ImGui.EndDragDropSource()
end
-- Tooltip
if bit32.band(flags, 64 --[[ImGuiColorEditFlags.NoTooltip]]) == 0 and hovered and ImGui.IsItemHovered(4096 --[[ImGuiHoveredFlags.ForTooltip]]) then