Port debug tools (item picker, flash style color, debug locate, DebugDraw*, keyboard preview, debug break, DrawCmd mesh view), context hooks, SetContextName, AddInputCharactersUTF8, sanity checks, window resize ids, Register/UnregisterUserTexture, SetPixelDensity, TestShortcutRouting, DemoMarker; InputTextState selection API (fixes undo crash, callbacks get 0-based positions), ShortcutsForCancel (Esc/right-click reverts drags/sliders), ImParseFormatSanitizeForPrinting, ImDrawList CloneOutput/PrimQuadUV/AddImageQuad, ImDrawData DeIndexAllBuffers/ScaleClipRects, internal helpers (ImBitVector, ImGuiPackedDate, inline ImGui getters...); t_debugtools, t_helpers
This commit is contained in:
@@ -1 +1 @@
|
|||||||
[[46, "imgui.lua"], [21466, "imgui_demo.lua"], [33318, "imgui_draw.lua"], [41521, "imgui_h.lua"], [44455, "imgui_impl_roblox.lua"], [46103, "imgui_impl_roblox_fonts.lua"], [52506, "imgui_internal.lua"], [56228, "imgui_tables.lua"], [61287, "imgui_widgets.lua"], [73263, "imstb_rectpack.lua"], [73927, "imstb_textedit.lua"], [75469, "imstb_truetype.lua"], [78257, "imstd_minstdio.lua"]]
|
[[46, "imgui.lua"], [22580, "imgui_demo.lua"], [34431, "imgui_draw.lua"], [42736, "imgui_h.lua"], [45681, "imgui_impl_roblox.lua"], [47329, "imgui_impl_roblox_fonts.lua"], [53732, "imgui_internal.lua"], [57611, "imgui_tables.lua"], [62711, "imgui_widgets.lua"], [74825, "imstb_rectpack.lua"], [75489, "imstb_textedit.lua"], [77031, "imstb_truetype.lua"], [79819, "imstd_minstdio.lua"]]
|
||||||
+1765
-173
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@ export type ImVec4 = { x: number, y: number, z: number, w: number, [any]: any }
|
|||||||
export type ImGuiAPI = {
|
export type ImGuiAPI = {
|
||||||
AcceptDragDropPayload: (type: string, flags: number?) -> any,
|
AcceptDragDropPayload: (type: string, flags: number?) -> any,
|
||||||
ActivateItemByID: (...any) -> ...any,
|
ActivateItemByID: (...any) -> ...any,
|
||||||
|
AddContextHook: (...any) -> ...any,
|
||||||
AddDrawListToDrawDataEx: (...any) -> ...any,
|
AddDrawListToDrawDataEx: (...any) -> ...any,
|
||||||
AddSettingsHandler: (...any) -> ...any,
|
AddSettingsHandler: (...any) -> ...any,
|
||||||
AddUpdateViewport: (...any) -> ...any,
|
AddUpdateViewport: (...any) -> ...any,
|
||||||
@@ -72,6 +73,7 @@ export type ImGuiAPI = {
|
|||||||
CalcTypematicRepeatAmount: (...any) -> ...any,
|
CalcTypematicRepeatAmount: (...any) -> ...any,
|
||||||
CalcWindowNextAutoFitSize: (...any) -> ...any,
|
CalcWindowNextAutoFitSize: (...any) -> ...any,
|
||||||
CalcWrapWidthForPos: (...any) -> ...any,
|
CalcWrapWidthForPos: (...any) -> ...any,
|
||||||
|
CallContextHooks: (...any) -> ...any,
|
||||||
Checkbox: (label: string, v: boolean?) -> (boolean, boolean?),
|
Checkbox: (label: string, v: boolean?) -> (boolean, boolean?),
|
||||||
CheckboxFlags: (...any) -> ...any,
|
CheckboxFlags: (...any) -> ...any,
|
||||||
CleanupIniSettings: (...any) -> ...any,
|
CleanupIniSettings: (...any) -> ...any,
|
||||||
@@ -111,15 +113,29 @@ export type ImGuiAPI = {
|
|||||||
DataTypeGetInfo: (...any) -> ...any,
|
DataTypeGetInfo: (...any) -> ...any,
|
||||||
DataTypeIsZero: (...any) -> ...any,
|
DataTypeIsZero: (...any) -> ...any,
|
||||||
DebugAllocHook: (...any) -> ...any,
|
DebugAllocHook: (...any) -> ...any,
|
||||||
|
DebugBreakButton: (...any) -> ...any,
|
||||||
|
DebugBreakButtonTooltip: (...any) -> ...any,
|
||||||
|
DebugBreakClearData: (...any) -> ...any,
|
||||||
|
DebugDrawCursorPos: (...any) -> ...any,
|
||||||
|
DebugDrawItemRect: (...any) -> ...any,
|
||||||
|
DebugDrawLineExtents: (...any) -> ...any,
|
||||||
|
DebugFlashStyleColor: (idx: number) -> (),
|
||||||
DebugHookIdInfo: (...any) -> ...any,
|
DebugHookIdInfo: (...any) -> ...any,
|
||||||
|
DebugLocateItem: (...any) -> ...any,
|
||||||
|
DebugLocateItemOnHover: (...any) -> ...any,
|
||||||
|
DebugLocateItemResolveWithLastItem: (...any) -> ...any,
|
||||||
DebugLog: (fmt: string, ...any) -> (),
|
DebugLog: (fmt: string, ...any) -> (),
|
||||||
|
DebugLogV: (fmt: string, ...any) -> (),
|
||||||
DebugNodeColumns: (...any) -> ...any,
|
DebugNodeColumns: (...any) -> ...any,
|
||||||
DebugNodeDockNode: (...any) -> ...any,
|
DebugNodeDockNode: (...any) -> ...any,
|
||||||
|
DebugNodeDrawCmdShowMeshAndBoundingBox: (...any) -> ...any,
|
||||||
DebugNodeDrawList: (...any) -> ...any,
|
DebugNodeDrawList: (...any) -> ...any,
|
||||||
DebugNodeFont: (...any) -> ...any,
|
DebugNodeFont: (...any) -> ...any,
|
||||||
DebugNodeFontGlyph: (...any) -> ...any,
|
DebugNodeFontGlyph: (...any) -> ...any,
|
||||||
DebugNodeFontGlyphsForSrcMask: (...any) -> ...any,
|
DebugNodeFontGlyphsForSrcMask: (...any) -> ...any,
|
||||||
|
DebugNodeInputTextState: (...any) -> ...any,
|
||||||
DebugNodeMultiSelectState: (...any) -> ...any,
|
DebugNodeMultiSelectState: (...any) -> ...any,
|
||||||
|
DebugNodePlatformMonitor: (...any) -> ...any,
|
||||||
DebugNodeStorage: (...any) -> ...any,
|
DebugNodeStorage: (...any) -> ...any,
|
||||||
DebugNodeTabBar: (...any) -> ...any,
|
DebugNodeTabBar: (...any) -> ...any,
|
||||||
DebugNodeTable: (...any) -> ...any,
|
DebugNodeTable: (...any) -> ...any,
|
||||||
@@ -131,8 +147,13 @@ export type ImGuiAPI = {
|
|||||||
DebugNodeWindowSettings: (...any) -> ...any,
|
DebugNodeWindowSettings: (...any) -> ...any,
|
||||||
DebugNodeWindowsList: (...any) -> ...any,
|
DebugNodeWindowsList: (...any) -> ...any,
|
||||||
DebugNodeWindowsListByBeginStackParent: (...any) -> ...any,
|
DebugNodeWindowsListByBeginStackParent: (...any) -> ...any,
|
||||||
|
DebugRenderKeyboardPreview: (...any) -> ...any,
|
||||||
DebugRenderViewportThumbnail: (...any) -> ...any,
|
DebugRenderViewportThumbnail: (...any) -> ...any,
|
||||||
|
DebugStartItemPicker: () -> (),
|
||||||
DebugTextEncoding: (str: string) -> (),
|
DebugTextEncoding: (str: string) -> (),
|
||||||
|
DebugTextUnformattedWithLocateItem: (...any) -> ...any,
|
||||||
|
DebugTextureIDToU64: (...any) -> ...any,
|
||||||
|
DemoMarker: (...any) -> ...any,
|
||||||
DestroyContext: (ctx: any) -> ...any,
|
DestroyContext: (ctx: any) -> ...any,
|
||||||
DestroyPlatformWindow: (...any) -> ...any,
|
DestroyPlatformWindow: (...any) -> ...any,
|
||||||
DestroyPlatformWindows: () -> (),
|
DestroyPlatformWindows: () -> (),
|
||||||
@@ -247,6 +268,8 @@ export type ImGuiAPI = {
|
|||||||
EndTable: () -> (),
|
EndTable: () -> (),
|
||||||
EndTooltip: () -> (),
|
EndTooltip: () -> (),
|
||||||
ErrorCheckEndFrameFinalizeErrorTooltip: (...any) -> ...any,
|
ErrorCheckEndFrameFinalizeErrorTooltip: (...any) -> ...any,
|
||||||
|
ErrorCheckEndFrameSanityChecks: (...any) -> ...any,
|
||||||
|
ErrorCheckNewFrameSanityChecks: (...any) -> ...any,
|
||||||
ErrorCheckUsingSetCursorPosToExtendParentBoundaries: (...any) -> ...any,
|
ErrorCheckUsingSetCursorPosToExtendParentBoundaries: (...any) -> ...any,
|
||||||
ErrorLog: (...any) -> ...any,
|
ErrorLog: (...any) -> ...any,
|
||||||
ErrorRecoveryStoreState: (...any) -> ...any,
|
ErrorRecoveryStoreState: (...any) -> ...any,
|
||||||
@@ -265,6 +288,7 @@ export type ImGuiAPI = {
|
|||||||
FindRenderedTextEnd: (...any) -> ...any,
|
FindRenderedTextEnd: (...any) -> ...any,
|
||||||
FindSettingsHandler: (...any) -> ...any,
|
FindSettingsHandler: (...any) -> ...any,
|
||||||
FindViewportByID: (viewport_id: number) -> any,
|
FindViewportByID: (viewport_id: number) -> any,
|
||||||
|
FindViewportByPlatformHandle: (platform_handle: any) -> ...any,
|
||||||
FindWindowByID: (...any) -> ...any,
|
FindWindowByID: (...any) -> ...any,
|
||||||
FindWindowByName: (...any) -> ...any,
|
FindWindowByName: (...any) -> ...any,
|
||||||
FindWindowDisplayIndex: (...any) -> ...any,
|
FindWindowDisplayIndex: (...any) -> ...any,
|
||||||
@@ -279,6 +303,7 @@ export type ImGuiAPI = {
|
|||||||
GcAwakeTransientWindowBuffers: (...any) -> ...any,
|
GcAwakeTransientWindowBuffers: (...any) -> ...any,
|
||||||
GcCompactTransientMiscBuffers: (...any) -> ...any,
|
GcCompactTransientMiscBuffers: (...any) -> ...any,
|
||||||
GcCompactTransientWindowBuffers: (...any) -> ...any,
|
GcCompactTransientWindowBuffers: (...any) -> ...any,
|
||||||
|
GetActiveID: (...any) -> ...any,
|
||||||
GetBackgroundDrawList: (viewport: any) -> ...any,
|
GetBackgroundDrawList: (viewport: any) -> ...any,
|
||||||
GetBoxSelectState: (...any) -> ...any,
|
GetBoxSelectState: (...any) -> ...any,
|
||||||
GetClipboardText: () -> any,
|
GetClipboardText: () -> any,
|
||||||
@@ -293,6 +318,9 @@ export type ImGuiAPI = {
|
|||||||
GetContentRegionAvail: () -> ImVec2,
|
GetContentRegionAvail: () -> ImVec2,
|
||||||
GetContentRegionMax: (...any) -> ...any,
|
GetContentRegionMax: (...any) -> ...any,
|
||||||
GetCurrentContext: () -> any,
|
GetCurrentContext: () -> any,
|
||||||
|
GetCurrentFocusScope: (...any) -> ...any,
|
||||||
|
GetCurrentTabBar: (...any) -> ...any,
|
||||||
|
GetCurrentTable: (...any) -> ...any,
|
||||||
GetCurrentWindow: (...any) -> ...any,
|
GetCurrentWindow: (...any) -> ...any,
|
||||||
GetCurrentWindowRead: (...any) -> ...any,
|
GetCurrentWindowRead: (...any) -> ...any,
|
||||||
GetCursorPos: () -> ImVec2,
|
GetCursorPos: () -> ImVec2,
|
||||||
@@ -304,7 +332,9 @@ export type ImGuiAPI = {
|
|||||||
GetDragDropPayload: () -> any,
|
GetDragDropPayload: () -> any,
|
||||||
GetDrawData: () -> any,
|
GetDrawData: () -> any,
|
||||||
GetDrawListSharedData: () -> any,
|
GetDrawListSharedData: () -> any,
|
||||||
|
GetFocusID: (...any) -> ...any,
|
||||||
GetFont: () -> any,
|
GetFont: () -> any,
|
||||||
|
GetFontBaked: () -> any,
|
||||||
GetFontSize: () -> number,
|
GetFontSize: () -> number,
|
||||||
GetFontTexUvWhitePixel: () -> ImVec2,
|
GetFontTexUvWhitePixel: () -> ImVec2,
|
||||||
GetForegroundDrawList: (viewport: any) -> ...any,
|
GetForegroundDrawList: (viewport: any) -> ...any,
|
||||||
@@ -322,6 +352,7 @@ export type ImGuiAPI = {
|
|||||||
GetItemRectMax: () -> ImVec2,
|
GetItemRectMax: () -> ImVec2,
|
||||||
GetItemRectMin: () -> ImVec2,
|
GetItemRectMin: () -> ImVec2,
|
||||||
GetItemRectSize: () -> ImVec2,
|
GetItemRectSize: () -> ImVec2,
|
||||||
|
GetItemStatusFlags: (...any) -> ...any,
|
||||||
GetKeyChordName: (...any) -> ...any,
|
GetKeyChordName: (...any) -> ...any,
|
||||||
GetKeyData: (...any) -> ...any,
|
GetKeyData: (...any) -> ...any,
|
||||||
GetKeyMagnitude2d: (...any) -> ...any,
|
GetKeyMagnitude2d: (...any) -> ...any,
|
||||||
@@ -340,6 +371,7 @@ export type ImGuiAPI = {
|
|||||||
GetMousePosOnOpeningCurrentPopup: () -> ImVec2,
|
GetMousePosOnOpeningCurrentPopup: () -> ImVec2,
|
||||||
GetMultiSelectState: (...any) -> ...any,
|
GetMultiSelectState: (...any) -> ...any,
|
||||||
GetNavTweakPressedAmount: (...any) -> ...any,
|
GetNavTweakPressedAmount: (...any) -> ...any,
|
||||||
|
GetPixelDensity: (...any) -> ...any,
|
||||||
GetPlatformIO: () -> any,
|
GetPlatformIO: () -> any,
|
||||||
GetPopupAllowedExtentRect: (...any) -> ...any,
|
GetPopupAllowedExtentRect: (...any) -> ...any,
|
||||||
GetRoundedFontSize: (...any) -> ...any,
|
GetRoundedFontSize: (...any) -> ...any,
|
||||||
@@ -369,10 +401,13 @@ export type ImGuiAPI = {
|
|||||||
GetWindowContentRegionMax: (...any) -> ...any,
|
GetWindowContentRegionMax: (...any) -> ...any,
|
||||||
GetWindowContentRegionMin: (...any) -> ...any,
|
GetWindowContentRegionMin: (...any) -> ...any,
|
||||||
GetWindowDockID: () -> number,
|
GetWindowDockID: () -> number,
|
||||||
|
GetWindowDockNode: (...any) -> ...any,
|
||||||
GetWindowDpiScale: () -> number,
|
GetWindowDpiScale: () -> number,
|
||||||
GetWindowDrawList: () -> any,
|
GetWindowDrawList: () -> any,
|
||||||
GetWindowHeight: () -> number,
|
GetWindowHeight: () -> number,
|
||||||
GetWindowPos: () -> ImVec2,
|
GetWindowPos: () -> ImVec2,
|
||||||
|
GetWindowResizeBorderID: (...any) -> ...any,
|
||||||
|
GetWindowResizeCornerID: (...any) -> ...any,
|
||||||
GetWindowScrollbarID: (...any) -> ...any,
|
GetWindowScrollbarID: (...any) -> ...any,
|
||||||
GetWindowScrollbarRect: (...any) -> ...any,
|
GetWindowScrollbarRect: (...any) -> ...any,
|
||||||
GetWindowSize: () -> ImVec2,
|
GetWindowSize: () -> ImVec2,
|
||||||
@@ -414,6 +449,7 @@ export type ImGuiAPI = {
|
|||||||
IsInNavFocusRoute: (...any) -> ...any,
|
IsInNavFocusRoute: (...any) -> ...any,
|
||||||
IsItemActivated: () -> boolean,
|
IsItemActivated: () -> boolean,
|
||||||
IsItemActive: () -> boolean,
|
IsItemActive: () -> boolean,
|
||||||
|
IsItemActiveAsInputText: (...any) -> ...any,
|
||||||
IsItemClicked: (mouse_button: number?) -> boolean,
|
IsItemClicked: (mouse_button: number?) -> boolean,
|
||||||
IsItemDeactivated: () -> boolean,
|
IsItemDeactivated: () -> boolean,
|
||||||
IsItemDeactivatedAfterEdit: () -> boolean,
|
IsItemDeactivatedAfterEdit: () -> boolean,
|
||||||
@@ -430,6 +466,7 @@ export type ImGuiAPI = {
|
|||||||
IsKeyReleased: (...any) -> ...any,
|
IsKeyReleased: (...any) -> ...any,
|
||||||
IsKeyboardKey: (...any) -> ...any,
|
IsKeyboardKey: (...any) -> ...any,
|
||||||
IsLRModKey: (...any) -> ...any,
|
IsLRModKey: (...any) -> ...any,
|
||||||
|
IsLegacyKey: (...any) -> ...any,
|
||||||
IsMouseClicked: (button: number, is_repeat: boolean?) -> boolean,
|
IsMouseClicked: (button: number, is_repeat: boolean?) -> boolean,
|
||||||
IsMouseClickedEx: (...any) -> ...any,
|
IsMouseClickedEx: (...any) -> ...any,
|
||||||
IsMouseDoubleClicked: (...any) -> ...any,
|
IsMouseDoubleClicked: (...any) -> ...any,
|
||||||
@@ -569,6 +606,8 @@ export type ImGuiAPI = {
|
|||||||
RadioButton: (...any) -> ...any,
|
RadioButton: (...any) -> ...any,
|
||||||
RadioButtonEx: (...any) -> ...any,
|
RadioButtonEx: (...any) -> ...any,
|
||||||
RegisterFontAtlas: (...any) -> ...any,
|
RegisterFontAtlas: (...any) -> ...any,
|
||||||
|
RegisterUserTexture: (...any) -> ...any,
|
||||||
|
RemoveContextHook: (...any) -> ...any,
|
||||||
RemoveSettingsHandler: (...any) -> ...any,
|
RemoveSettingsHandler: (...any) -> ...any,
|
||||||
Render: () -> (),
|
Render: () -> (),
|
||||||
RenderArrow: (...any) -> ...any,
|
RenderArrow: (...any) -> ...any,
|
||||||
@@ -604,6 +643,7 @@ export type ImGuiAPI = {
|
|||||||
ScaleRatioFromValueT: (...any) -> ...any,
|
ScaleRatioFromValueT: (...any) -> ...any,
|
||||||
ScaleValueFromRatioT: (...any) -> ...any,
|
ScaleValueFromRatioT: (...any) -> ...any,
|
||||||
ScaleWindowsInViewport: (...any) -> ...any,
|
ScaleWindowsInViewport: (...any) -> ...any,
|
||||||
|
ScrollToBringRectIntoView: (...any) -> ...any,
|
||||||
ScrollToItem: (...any) -> ...any,
|
ScrollToItem: (...any) -> ...any,
|
||||||
ScrollToRect: (...any) -> ...any,
|
ScrollToRect: (...any) -> ...any,
|
||||||
ScrollToRectEx: (...any) -> ...any,
|
ScrollToRectEx: (...any) -> ...any,
|
||||||
@@ -621,6 +661,7 @@ export type ImGuiAPI = {
|
|||||||
SetColorEditOptions: (...any) -> ...any,
|
SetColorEditOptions: (...any) -> ...any,
|
||||||
SetColumnOffset: (column_index: number, offset: number) -> (),
|
SetColumnOffset: (column_index: number, offset: number) -> (),
|
||||||
SetColumnWidth: (column_index: number, width: number) -> (),
|
SetColumnWidth: (column_index: number, width: number) -> (),
|
||||||
|
SetContextName: (...any) -> ...any,
|
||||||
SetCurrentContext: (ctx: any) -> ...any,
|
SetCurrentContext: (ctx: any) -> ...any,
|
||||||
SetCurrentFont: (...any) -> ...any,
|
SetCurrentFont: (...any) -> ...any,
|
||||||
SetCurrentViewport: (...any) -> ...any,
|
SetCurrentViewport: (...any) -> ...any,
|
||||||
@@ -634,6 +675,7 @@ export type ImGuiAPI = {
|
|||||||
SetItemDefaultFocus: () -> (),
|
SetItemDefaultFocus: () -> (),
|
||||||
SetItemKeyOwner: (...any) -> ...any,
|
SetItemKeyOwner: (...any) -> ...any,
|
||||||
SetItemTooltip: (fmt: string, ...any) -> (),
|
SetItemTooltip: (fmt: string, ...any) -> (),
|
||||||
|
SetItemTooltipV: (fmt: string, ...any) -> (),
|
||||||
SetKeyOwner: (...any) -> ...any,
|
SetKeyOwner: (...any) -> ...any,
|
||||||
SetKeyOwnersForKeyChord: (...any) -> ...any,
|
SetKeyOwnersForKeyChord: (...any) -> ...any,
|
||||||
SetKeyboardFocusHere: (offset: number?) -> (),
|
SetKeyboardFocusHere: (offset: number?) -> (),
|
||||||
@@ -671,6 +713,7 @@ export type ImGuiAPI = {
|
|||||||
SetNextWindowSize: (size: ImVec2, cond: number?) -> (),
|
SetNextWindowSize: (size: ImVec2, cond: number?) -> (),
|
||||||
SetNextWindowSizeConstraints: (size_min: ImVec2, size_max: ImVec2, custom_callback: any, custom_callback_user_data: any) -> ...any,
|
SetNextWindowSizeConstraints: (size_min: ImVec2, size_max: ImVec2, custom_callback: any, custom_callback_user_data: any) -> ...any,
|
||||||
SetNextWindowViewport: (id: number) -> (),
|
SetNextWindowViewport: (id: number) -> (),
|
||||||
|
SetPixelDensity: (...any) -> ...any,
|
||||||
SetScrollFromPosX: (...any) -> ...any,
|
SetScrollFromPosX: (...any) -> ...any,
|
||||||
SetScrollFromPosY: (...any) -> ...any,
|
SetScrollFromPosY: (...any) -> ...any,
|
||||||
SetScrollHereX: (center_x_ratio: number?) -> (),
|
SetScrollHereX: (center_x_ratio: number?) -> (),
|
||||||
@@ -681,6 +724,7 @@ export type ImGuiAPI = {
|
|||||||
SetStateStorage: (tree: any) -> ...any,
|
SetStateStorage: (tree: any) -> ...any,
|
||||||
SetTabItemClosed: (label: string) -> (),
|
SetTabItemClosed: (label: string) -> (),
|
||||||
SetTooltip: (fmt: string, ...any) -> (),
|
SetTooltip: (fmt: string, ...any) -> (),
|
||||||
|
SetTooltipV: (fmt: string, ...any) -> (),
|
||||||
SetWindowClipRectBeforeSetChannel: (...any) -> ...any,
|
SetWindowClipRectBeforeSetChannel: (...any) -> ...any,
|
||||||
SetWindowCollapsed: (...any) -> ...any,
|
SetWindowCollapsed: (...any) -> ...any,
|
||||||
SetWindowDock: (...any) -> ...any,
|
SetWindowDock: (...any) -> ...any,
|
||||||
@@ -688,6 +732,7 @@ export type ImGuiAPI = {
|
|||||||
SetWindowFontScale: (...any) -> ...any,
|
SetWindowFontScale: (...any) -> ...any,
|
||||||
SetWindowHiddenAndSkipItemsForCurrentFrame: (...any) -> ...any,
|
SetWindowHiddenAndSkipItemsForCurrentFrame: (...any) -> ...any,
|
||||||
SetWindowHitTestHole: (...any) -> ...any,
|
SetWindowHitTestHole: (...any) -> ...any,
|
||||||
|
SetWindowParentWindowForFocusRoute: (...any) -> ...any,
|
||||||
SetWindowPos: (...any) -> ...any,
|
SetWindowPos: (...any) -> ...any,
|
||||||
SetWindowSize: (...any) -> ...any,
|
SetWindowSize: (...any) -> ...any,
|
||||||
SetWindowViewport: (...any) -> ...any,
|
SetWindowViewport: (...any) -> ...any,
|
||||||
@@ -836,6 +881,7 @@ export type ImGuiAPI = {
|
|||||||
TempInputScalar: (...any) -> ...any,
|
TempInputScalar: (...any) -> ...any,
|
||||||
TempInputText: (...any) -> ...any,
|
TempInputText: (...any) -> ...any,
|
||||||
TestKeyOwner: (...any) -> ...any,
|
TestKeyOwner: (...any) -> ...any,
|
||||||
|
TestShortcutRouting: (...any) -> ...any,
|
||||||
Text: (fmt: string, ...any) -> (),
|
Text: (fmt: string, ...any) -> (),
|
||||||
TextAligned: (...any) -> ...any,
|
TextAligned: (...any) -> ...any,
|
||||||
TextBufferToString: (buf: {number}) -> string,
|
TextBufferToString: (buf: {number}) -> string,
|
||||||
@@ -867,9 +913,12 @@ export type ImGuiAPI = {
|
|||||||
TypingSelectFindNextSingleCharMatch: (...any) -> ...any,
|
TypingSelectFindNextSingleCharMatch: (...any) -> ...any,
|
||||||
Unindent: (indent_w: number?) -> (),
|
Unindent: (indent_w: number?) -> (),
|
||||||
UnregisterFontAtlas: (...any) -> ...any,
|
UnregisterFontAtlas: (...any) -> ...any,
|
||||||
|
UnregisterUserTexture: (...any) -> ...any,
|
||||||
UpdateAliasKey: (...any) -> ...any,
|
UpdateAliasKey: (...any) -> ...any,
|
||||||
UpdateCurrentFontSize: (...any) -> ...any,
|
UpdateCurrentFontSize: (...any) -> ...any,
|
||||||
|
UpdateDebugToolFlashStyleColor: (...any) -> ...any,
|
||||||
UpdateDebugToolItemPathQuery: (...any) -> ...any,
|
UpdateDebugToolItemPathQuery: (...any) -> ...any,
|
||||||
|
UpdateDebugToolItemPicker: (...any) -> ...any,
|
||||||
UpdateFontsEndFrame: (...any) -> ...any,
|
UpdateFontsEndFrame: (...any) -> ...any,
|
||||||
UpdateFontsNewFrame: (...any) -> ...any,
|
UpdateFontsNewFrame: (...any) -> ...any,
|
||||||
UpdateHoveredWindowAndCaptureFlags: (...any) -> ...any,
|
UpdateHoveredWindowAndCaptureFlags: (...any) -> ...any,
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
[[183, "imgui.lua"], [21603, "imgui_demo.lua"], [33455, "imgui_draw.lua"], [41658, "imgui_h.lua"], [44592, "imgui_impl_love.lua"], [45132, "imgui_internal.lua"], [48854, "imgui_tables.lua"], [53913, "imgui_widgets.lua"], [65889, "imstb_rectpack.lua"], [66553, "imstb_textedit.lua"], [68095, "imstb_truetype.lua"], [70883, "imstd_minstdio.lua"]]
|
[[183, "imgui.lua"], [22717, "imgui_demo.lua"], [34568, "imgui_draw.lua"], [42873, "imgui_h.lua"], [45818, "imgui_impl_love.lua"], [46358, "imgui_internal.lua"], [50237, "imgui_tables.lua"], [55337, "imgui_widgets.lua"], [67451, "imstb_rectpack.lua"], [68115, "imstb_textedit.lua"], [69657, "imstb_truetype.lua"], [72445, "imstd_minstdio.lua"]]
|
||||||
+1765
-173
File diff suppressed because it is too large
Load Diff
+1520
-1553
File diff suppressed because it is too large
Load Diff
+3
-4
@@ -214,7 +214,7 @@ function ShowDockingDisabledMessage()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Helper to wire demo markers located in code to an interactive browser (e.g. https://pthom.github.io/imgui_explorer)
|
-- Helper to wire demo markers located in code to an interactive browser (e.g. https://pthom.github.io/imgui_explorer)
|
||||||
function IMGUI_DEMO_MARKER(section) end -- [Port] no ImGui.DemoMarker() hook in this port: no-op
|
function IMGUI_DEMO_MARKER(section) ImGui.DemoMarker("imgui_demo.lua", 0, section) end -- [Port] no __LINE__ in Lua: line is 0
|
||||||
|
|
||||||
-- Sneakily forward declare functions which aren't worth putting in public API yet
|
-- Sneakily forward declare functions which aren't worth putting in public API yet
|
||||||
-- [Port] ImGui.ShowFontAtlas(atlas) and ImGui.TreeNodeSetOpen(storage_id, is_open) are already public here.
|
-- [Port] ImGui.ShowFontAtlas(atlas) and ImGui.TreeNodeSetOpen(storage_id, is_open) are already public here.
|
||||||
@@ -698,8 +698,7 @@ function DemoWindowMenuBar(demo_data)
|
|||||||
_, demo_data.ShowDebugLog = ImGui.MenuItem("Debug Log", nil, demo_data.ShowDebugLog, has_debug_tools)
|
_, demo_data.ShowDebugLog = ImGui.MenuItem("Debug Log", nil, demo_data.ShowDebugLog, has_debug_tools)
|
||||||
_, demo_data.ShowIDStackTool = ImGui.MenuItem("ID Stack Tool", nil, demo_data.ShowIDStackTool, has_debug_tools)
|
_, demo_data.ShowIDStackTool = ImGui.MenuItem("ID Stack Tool", nil, demo_data.ShowIDStackTool, has_debug_tools)
|
||||||
local is_debugger_present = io.ConfigDebugIsDebuggerPresent
|
local is_debugger_present = io.ConfigDebugIsDebuggerPresent
|
||||||
local has_item_picker = ImGui.DebugStartItemPicker ~= nil -- [Port] ImGui.DebugStartItemPicker() is not ported yet: menu item disabled until it is
|
if ImGui.MenuItem("Item Picker", nil, false, has_debug_tools) then -- and is_debugger_present
|
||||||
if ImGui.MenuItem("Item Picker", nil, false, has_debug_tools and has_item_picker) then -- and is_debugger_present
|
|
||||||
ImGui.DebugStartItemPicker()
|
ImGui.DebugStartItemPicker()
|
||||||
end
|
end
|
||||||
if not is_debugger_present then
|
if not is_debugger_present then
|
||||||
@@ -8904,7 +8903,7 @@ function ImGui.ShowStyleEditor(ref)
|
|||||||
end
|
end
|
||||||
ImGui.PushID(i)
|
ImGui.PushID(i)
|
||||||
if ImGui.Button("?") then
|
if ImGui.Button("?") then
|
||||||
if ImGui.DebugFlashStyleColor then ImGui.DebugFlashStyleColor(i) end -- [Port] DebugFlashStyleColor() is not in the library yet
|
ImGui.DebugFlashStyleColor(i)
|
||||||
end
|
end
|
||||||
ImGui.SetItemTooltip("Flash given color to identify places where it is used.")
|
ImGui.SetItemTooltip("Flash given color to identify places where it is used.")
|
||||||
ImGui.SameLine()
|
ImGui.SameLine()
|
||||||
|
|||||||
+102
@@ -4155,6 +4155,42 @@ function MT.ImDrawData:AddDrawList(draw_list)
|
|||||||
ImGui.AddDrawListToDrawDataEx(self, self.CmdLists, draw_list)
|
ImGui.AddDrawListToDrawDataEx(self, self.CmdLists, draw_list)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
|
||||||
|
-- [Luau] IdxBuffer values are 1-based vertex indices
|
||||||
|
function MT.ImDrawData:DeIndexAllBuffers()
|
||||||
|
local new_vtx_buffer = ImDrawVtxBuffer()
|
||||||
|
self.TotalVtxCount = 0; self.TotalIdxCount = 0
|
||||||
|
for i = 1, self.CmdLists.Size do
|
||||||
|
repeat
|
||||||
|
local draw_list = self.CmdLists.Data[i]
|
||||||
|
if draw_list.IdxBuffer.Size == 0 then
|
||||||
|
break -- continue
|
||||||
|
end
|
||||||
|
new_vtx_buffer:resize(draw_list.IdxBuffer.Size)
|
||||||
|
local src, dst, idx = draw_list.VtxBuffer.Buf, new_vtx_buffer.Buf, draw_list.IdxBuffer.Data
|
||||||
|
for j = 1, draw_list.IdxBuffer.Size do
|
||||||
|
buffer.copy(dst, (j - 1) * VTX_STRIDE, src, (idx[j] - 1) * VTX_STRIDE, VTX_STRIDE)
|
||||||
|
end
|
||||||
|
draw_list.VtxBuffer, new_vtx_buffer = new_vtx_buffer, draw_list.VtxBuffer -- swap()
|
||||||
|
draw_list.IdxBuffer:resize(0)
|
||||||
|
self.TotalVtxCount = self.TotalVtxCount + draw_list.VtxBuffer.Size
|
||||||
|
until true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Helper to scale the ClipRect field of each ImDrawCmd.
|
||||||
|
-- Use if your final output buffer is at a different scale than draw_data->DisplaySize,
|
||||||
|
-- or if there is a difference between your window resolution and framebuffer resolution.
|
||||||
|
function MT.ImDrawData:ScaleClipRects(fb_scale)
|
||||||
|
for i = 1, self.CmdLists.Size do
|
||||||
|
local draw_list = self.CmdLists.Data[i]
|
||||||
|
for j = 1, draw_list.CmdBuffer.Size do
|
||||||
|
local cmd = draw_list.CmdBuffer.Data[j]
|
||||||
|
cmd.ClipRect = ImVec4(cmd.ClipRect.x * fb_scale.x, cmd.ClipRect.y * fb_scale.y, cmd.ClipRect.z * fb_scale.x, cmd.ClipRect.w * fb_scale.y)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN = 4
|
local IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN = 4
|
||||||
local IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX = 512
|
local IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX = 512
|
||||||
|
|
||||||
@@ -4262,6 +4298,29 @@ function MT.ImDrawList:_ClearFreeMemory()
|
|||||||
self._Splitter:ClearFreeMemory()
|
self._Splitter:ClearFreeMemory()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Note: For multi-threaded rendering, consider using `imgui_threaded_rendering` from https://github.com/ocornut/imgui_club
|
||||||
|
-- [Luau] C++ copies the vectors by value: copy the ImDrawCmd structs and the vertex buffer bytes
|
||||||
|
--- @return ImDrawList
|
||||||
|
function MT.ImDrawList:CloneOutput()
|
||||||
|
local dst = ImDrawList(nil)
|
||||||
|
for i = 1, self.CmdBuffer.Size do
|
||||||
|
local src_cmd = self.CmdBuffer.Data[i]
|
||||||
|
local cmd = ImDrawCmd()
|
||||||
|
for k, v in pairs(src_cmd) do cmd[k] = v end
|
||||||
|
cmd.ClipRect = ImVec4(src_cmd.ClipRect.x, src_cmd.ClipRect.y, src_cmd.ClipRect.z, src_cmd.ClipRect.w)
|
||||||
|
if src_cmd.TexRef then cmd.TexRef = ImTextureRef(src_cmd.TexRef._TexID); cmd.TexRef._TexData = src_cmd.TexRef._TexData end
|
||||||
|
dst.CmdBuffer:push_back(cmd)
|
||||||
|
end
|
||||||
|
if self.IdxBuffer.Size > 0 then
|
||||||
|
dst.IdxBuffer:resize(self.IdxBuffer.Size)
|
||||||
|
table.move(self.IdxBuffer.Data, 1, self.IdxBuffer.Size, 1, dst.IdxBuffer.Data)
|
||||||
|
end
|
||||||
|
dst.VtxBuffer:resize(self.VtxBuffer.Size)
|
||||||
|
buffer.copy(dst.VtxBuffer.Buf, 0, self.VtxBuffer.Buf, 0, self.VtxBuffer.Size * VTX_STRIDE)
|
||||||
|
dst.Flags = self.Flags
|
||||||
|
return dst
|
||||||
|
end
|
||||||
|
|
||||||
function MT.ImDrawList:AddDrawCmd()
|
function MT.ImDrawList:AddDrawCmd()
|
||||||
local draw_cmd = ImDrawCmd()
|
local draw_cmd = ImDrawCmd()
|
||||||
|
|
||||||
@@ -4819,6 +4878,22 @@ function MT.ImDrawList:PrimRectUV(a, c, uv_a, uv_c, col)
|
|||||||
self._IdxWritePtr = idx_write_ptr + 6
|
self._IdxWritePtr = idx_write_ptr + 6
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function MT.ImDrawList:PrimQuadUV(a, b, c, d, uv_a, uv_b, uv_c, uv_d, col)
|
||||||
|
local idx = self._VtxCurrentIdx
|
||||||
|
local idx_data = self.IdxBuffer.Data; local vtx_data = self.VtxBuffer.Buf
|
||||||
|
local idx_write_ptr = self._IdxWritePtr
|
||||||
|
idx_data[idx_write_ptr + 0] = idx; idx_data[idx_write_ptr + 1] = idx + 1; idx_data[idx_write_ptr + 2] = idx + 2
|
||||||
|
idx_data[idx_write_ptr + 3] = idx; idx_data[idx_write_ptr + 4] = idx + 2; idx_data[idx_write_ptr + 5] = idx + 3
|
||||||
|
local vtx_write_ptr = self._VtxWritePtr
|
||||||
|
WV(vtx_data, vtx_write_ptr + 0, a.x, a.y, uv_a.x, uv_a.y, col)
|
||||||
|
WV(vtx_data, vtx_write_ptr + 1, b.x, b.y, uv_b.x, uv_b.y, col)
|
||||||
|
WV(vtx_data, vtx_write_ptr + 2, c.x, c.y, uv_c.x, uv_c.y, col)
|
||||||
|
WV(vtx_data, vtx_write_ptr + 3, d.x, d.y, uv_d.x, uv_d.y, col)
|
||||||
|
self._VtxWritePtr = vtx_write_ptr + 4
|
||||||
|
self._VtxCurrentIdx = idx + 4
|
||||||
|
self._IdxWritePtr = idx_write_ptr + 6
|
||||||
|
end
|
||||||
|
|
||||||
--- @param thickness float
|
--- @param thickness float
|
||||||
--- @return float
|
--- @return float
|
||||||
-- [Luau] local function (also MT.ImDrawList._CalculateCenterBiasedOffset)
|
-- [Luau] local function (also MT.ImDrawList._CalculateCenterBiasedOffset)
|
||||||
@@ -6808,6 +6883,30 @@ function MT.ImDrawList:AddImage(tex_ref, p_min, p_max, uv_min, uv_max, col)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function MT.ImDrawList:AddImageQuad(tex_ref, p1, p2, p3, p4, uv1, uv2, uv3, uv4, col)
|
||||||
|
if uv1 == nil then uv1 = ImVec2(0, 0) end
|
||||||
|
if uv2 == nil then uv2 = ImVec2(1, 0) end
|
||||||
|
if uv3 == nil then uv3 = ImVec2(1, 1) end
|
||||||
|
if uv4 == nil then uv4 = ImVec2(0, 1) end
|
||||||
|
if col == nil then col = IM_COL32_WHITE end
|
||||||
|
|
||||||
|
if bit32.band(col, IM_COL32_A_MASK) == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local push_texture_id = tex_ref ~= self._CmdHeader.TexRef
|
||||||
|
if push_texture_id then
|
||||||
|
self:PushTexture(tex_ref)
|
||||||
|
end
|
||||||
|
|
||||||
|
self:PrimReserve(6, 4)
|
||||||
|
self:PrimQuadUV(p1, p2, p3, p4, uv1, uv2, uv3, uv4, col)
|
||||||
|
|
||||||
|
if push_texture_id then
|
||||||
|
self:PopTexture()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- @param tex_ref ImTextureRef
|
--- @param tex_ref ImTextureRef
|
||||||
--- @param p_min ImVec2
|
--- @param p_min ImVec2
|
||||||
--- @param p_max ImVec2
|
--- @param p_max ImVec2
|
||||||
@@ -6901,6 +7000,9 @@ function MT.ImDrawList:PopClipRect()
|
|||||||
self:_OnChangedClipRect()
|
self:_OnChangedClipRect()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function MT.ImDrawList:GetClipRectMin() local cr = self._ClipRectStack:back(); return ImVec2(cr.x, cr.y) end
|
||||||
|
function MT.ImDrawList:GetClipRectMax() local cr = self._ClipRectStack:back(); return ImVec2(cr.z, cr.w) end
|
||||||
|
|
||||||
--- @param center ImVec2
|
--- @param center ImVec2
|
||||||
--- @param radius float
|
--- @param radius float
|
||||||
--- @param a_min_sample int
|
--- @param a_min_sample int
|
||||||
|
|||||||
+19
-8
@@ -499,8 +499,8 @@ end
|
|||||||
--- @field UserCallbackData any
|
--- @field UserCallbackData any
|
||||||
--- @field UserCallbackDataSize int
|
--- @field UserCallbackDataSize int
|
||||||
--- @field UserCallbackDataOffset int
|
--- @field UserCallbackDataOffset int
|
||||||
local IM_DRAWCMD = {}
|
MT.ImDrawCmd = {}
|
||||||
IM_DRAWCMD.__index = IM_DRAWCMD
|
MT.ImDrawCmd.__index = MT.ImDrawCmd
|
||||||
|
|
||||||
--- @return ImDrawCmd
|
--- @return ImDrawCmd
|
||||||
--- @nodiscard
|
--- @nodiscard
|
||||||
@@ -515,11 +515,11 @@ function ImDrawCmd()
|
|||||||
UserCallbackData = nil, -- 4-8 -- Callback user data (when UserCallback != nil). If called AddCallback() with size == 0, this is a copy of the AddCallback() argument. If called AddCallback() with size > 0, this is pointing to a buffer where data is stored.
|
UserCallbackData = nil, -- 4-8 -- Callback user data (when UserCallback != nil). If called AddCallback() with size == 0, this is a copy of the AddCallback() argument. If called AddCallback() with size > 0, this is pointing to a buffer where data is stored.
|
||||||
UserCallbackDataSize = 0, -- 4 -- Size of callback user data when using storage, otherwise 0.
|
UserCallbackDataSize = 0, -- 4 -- Size of callback user data when using storage, otherwise 0.
|
||||||
UserCallbackDataOffset = 0 -- 4 -- [Internal] Offset of callback user data when using storage, otherwise -1.
|
UserCallbackDataOffset = 0 -- 4 -- [Internal] Offset of callback user data when using storage, otherwise -1.
|
||||||
}, IM_DRAWCMD)
|
}, MT.ImDrawCmd)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @return ImTextureID
|
--- @return ImTextureID
|
||||||
function IM_DRAWCMD:GetTexID()
|
function MT.ImDrawCmd:GetTexID()
|
||||||
local tex_id = (self.TexRef._TexData) and self.TexRef._TexData.TexID or self.TexRef._TexID
|
local tex_id = (self.TexRef._TexData) and self.TexRef._TexData.TexID or self.TexRef._TexID
|
||||||
if self.TexRef._TexData ~= nil then
|
if self.TexRef._TexData ~= nil then
|
||||||
IM_ASSERT(tex_id ~= ImTextureID_Invalid, "ImDrawCmd is referring to ImTextureData that wasn't uploaded to graphics system. Backend must call ImTextureData::SetTexID() after handling ImTextureStatus_WantCreate request!")
|
IM_ASSERT(tex_id ~= ImTextureID_Invalid, "ImDrawCmd is referring to ImTextureData that wasn't uploaded to graphics system. Backend must call ImTextureData::SetTexID() after handling ImTextureStatus_WantCreate request!")
|
||||||
@@ -775,11 +775,14 @@ end
|
|||||||
|
|
||||||
--- @param x int
|
--- @param x int
|
||||||
--- @param y int
|
--- @param y int
|
||||||
|
function MT.ImTextureData:GetPixels() IM_ASSERT(self.Pixels ~= nil); return self.Pixels end
|
||||||
function MT.ImTextureData:GetPixelsAt(x, y)
|
function MT.ImTextureData:GetPixelsAt(x, y)
|
||||||
return self.Pixels, (x + y * self.Width) * self.BytesPerPixel + 1
|
return self.Pixels, (x + y * self.Width) * self.BytesPerPixel + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function MT.ImTextureData:GetSizeInBytes() return self.Width * self.Height * self.BytesPerPixel end
|
||||||
function MT.ImTextureData:GetPitch() return self.Width * self.BytesPerPixel end
|
function MT.ImTextureData:GetPitch() return self.Width * self.BytesPerPixel end
|
||||||
|
function MT.ImTextureData:GetTexRef() local tex_ref = ImTextureRef(); tex_ref._TexData = self; tex_ref._TexID = ImTextureID_Invalid; return tex_ref end
|
||||||
function MT.ImTextureData:GetTexID() return self.TexID end
|
function MT.ImTextureData:GetTexID() return self.TexID end
|
||||||
|
|
||||||
--- @param tex_id ImTextureID
|
--- @param tex_id ImTextureID
|
||||||
@@ -799,8 +802,8 @@ function MT.ImTextureData:SetStatus(status) self.Status = status if (status == I
|
|||||||
--- @class ImTextureRef
|
--- @class ImTextureRef
|
||||||
--- @field _TexData? ImTextureData
|
--- @field _TexData? ImTextureData
|
||||||
--- @field _TexID ImTextureID
|
--- @field _TexID ImTextureID
|
||||||
local IM_TEXTURE_REF = {}
|
MT.ImTextureRef = {}
|
||||||
IM_TEXTURE_REF.__index = IM_TEXTURE_REF
|
MT.ImTextureRef.__index = MT.ImTextureRef
|
||||||
|
|
||||||
--- @return ImTextureRef
|
--- @return ImTextureRef
|
||||||
--- @nodiscard
|
--- @nodiscard
|
||||||
@@ -809,7 +812,14 @@ function ImTextureRef(tex_id)
|
|||||||
-- Members (either are set, never both!)
|
-- Members (either are set, never both!)
|
||||||
_TexData = nil, -- A texture, generally owned by a ImFontAtlas. Will convert to ImTextureID during render loop, after texture has been uploaded.
|
_TexData = nil, -- A texture, generally owned by a ImFontAtlas. Will convert to ImTextureID during render loop, after texture has been uploaded.
|
||||||
_TexID = tex_id or ImTextureID_Invalid -- _OR_ Low-level backend texture identifier, if already uploaded or created by user/app. Generally provided to e.g. ImGui.Image() calls.
|
_TexID = tex_id or ImTextureID_Invalid -- _OR_ Low-level backend texture identifier, if already uploaded or created by user/app. Generally provided to e.g. ImGui.Image() calls.
|
||||||
}, IM_TEXTURE_REF)
|
}, MT.ImTextureRef)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This is provided for consistency (but we don't actually use this)
|
||||||
|
--- @return ImTextureID
|
||||||
|
function MT.ImTextureRef:GetTexID()
|
||||||
|
IM_ASSERT(not (self._TexData ~= nil and self._TexID ~= ImTextureID_Invalid))
|
||||||
|
if self._TexData then return self._TexData.TexID else return self._TexID end
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -2543,7 +2553,8 @@ function MT.ImGuiInputTextCallbackData:InsertChars(pos, new_text)
|
|||||||
self.SelectionStart = self.CursorPos; self.SelectionEnd = self.CursorPos
|
self.SelectionStart = self.CursorPos; self.SelectionEnd = self.CursorPos
|
||||||
end
|
end
|
||||||
|
|
||||||
function MT.ImGuiInputTextCallbackData:SelectAll() self.SelectionStart = 0; self.SelectionEnd = self.BufTextLen end
|
function MT.ImGuiInputTextCallbackData:SelectAll() self.SelectionStart = 0; self.CursorPos = self.BufTextLen; self.SelectionEnd = self.BufTextLen end
|
||||||
|
function MT.ImGuiInputTextCallbackData:SetSelection(s, e) IM_ASSERT(s >= 0 and s <= self.BufTextLen); IM_ASSERT(e >= 0 and e <= self.BufTextLen); self.SelectionStart = s; self.CursorPos = e; self.SelectionEnd = e end
|
||||||
function MT.ImGuiInputTextCallbackData:ClearSelection() self.SelectionStart = self.BufTextLen; self.SelectionEnd = self.BufTextLen end
|
function MT.ImGuiInputTextCallbackData:ClearSelection() self.SelectionStart = self.BufTextLen; self.SelectionEnd = self.BufTextLen end
|
||||||
function MT.ImGuiInputTextCallbackData:HasSelection() return self.SelectionStart ~= self.SelectionEnd end
|
function MT.ImGuiInputTextCallbackData:HasSelection() return self.SelectionStart ~= self.SelectionEnd end
|
||||||
|
|
||||||
|
|||||||
+183
-26
@@ -706,6 +706,27 @@ function ImCharIsBlankA(c) return c == 32 or c == 9 end
|
|||||||
--- @param c char
|
--- @param c char
|
||||||
function ImCharIsBlankW(c) return c == 32 or c == 9 or c == 0x3000 end
|
function ImCharIsBlankW(c) return c == 32 or c == 9 or c == 0x3000 end
|
||||||
|
|
||||||
|
--- @param c char
|
||||||
|
function ImCharIsXdigitA(c) return (c >= 48 and c <= 57) or (c >= 65 and c <= 70) or (c >= 97 and c <= 102) end
|
||||||
|
|
||||||
|
--- @param lhs ImVec2
|
||||||
|
--- @param fail_value float
|
||||||
|
function ImInvLength(lhs, fail_value) local d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if d > 0.0 then return ImRsqrt(d) end; return fail_value end
|
||||||
|
function ImRoundPositive64(f) return _Trunc(f + 0.5) end -- Positive values only.
|
||||||
|
function ImRoundSigned64(f) if f >= 0.0 then return _Trunc(f + 0.5) else return _Trunc(f - 0.5) end end
|
||||||
|
-- [Luau] C '%' truncates toward zero; math.fmod matches it
|
||||||
|
function ImModPositive(a, b) return math.fmod(a + b, b) end
|
||||||
|
function ImIsFloatAboveGuaranteedIntegerPrecision(f) return f <= -16777216 or f >= 16777216 end
|
||||||
|
|
||||||
|
-- Helper: ImVec2i (2D vector, integer) / ImVec2ih (2D vector, half-size integer, for long-term packed storage)
|
||||||
|
-- [Luau] both are plain ImVec2 holding whole numbers
|
||||||
|
function ImVec2i(x, y) return ImVec2(x or 0, y or 0) end
|
||||||
|
--- @overload fun(rhs: ImVec2): ImVec2
|
||||||
|
function ImVec2ih(x, y)
|
||||||
|
if type(x) == "table" then return ImVec2(_Trunc(x.x), _Trunc(x.y)) end
|
||||||
|
return ImVec2(x or 0, y or 0)
|
||||||
|
end
|
||||||
|
|
||||||
--- @enum ImGuiNavMoveFlags
|
--- @enum ImGuiNavMoveFlags
|
||||||
ImGuiNavMoveFlags =
|
ImGuiNavMoveFlags =
|
||||||
{
|
{
|
||||||
@@ -1004,6 +1025,28 @@ function ImBitArraySetBit(arr, n)
|
|||||||
arr[idx] = bitOr(arr[idx], mask)
|
arr[idx] = bitOr(arr[idx], mask)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- [Luau] bit arrays are ImU32[] tables with 1-based word indices; bit indices 'n' are 1-based like the functions above
|
||||||
|
--- @param bitcount int
|
||||||
|
function ImBitArrayGetStorageSizeInBytes(bitcount) return bitLShift(bitRShift(bitcount + 31, 5), 2) end
|
||||||
|
--- @param arr ImU32[]
|
||||||
|
--- @param bitcount int
|
||||||
|
function ImBitArrayClearAllBits(arr, bitcount) for i = 1, bitRShift(bitcount + 31, 5) do arr[i] = 0 end end
|
||||||
|
function ImBitArrayTestBit(arr, n) local mask = bitLShift(1, bitAnd(n - 1, 31)); return bitAnd(arr[bitRShift(n - 1, 5) + 1], mask) ~= 0 end
|
||||||
|
function ImBitArrayClearBit(arr, n) local mask = bitLShift(1, bitAnd(n - 1, 31)); local idx = bitRShift(n - 1, 5) + 1; arr[idx] = bitAnd(arr[idx], bitNot(mask)) end
|
||||||
|
-- Works on range [n..n2)
|
||||||
|
function ImBitArraySetBitRange(arr, n, n2)
|
||||||
|
n = n - 1; n2 = n2 - 1 -- [Luau] to 0-based
|
||||||
|
n2 = n2 - 1
|
||||||
|
while n <= n2 do
|
||||||
|
local a_mod = bitAnd(n, 31)
|
||||||
|
local b_mod = ((n2 > bitOr(n, 31)) and 31 or bitAnd(n2, 31)) + 1
|
||||||
|
local mask = bitAnd(2 ^ b_mod - 1, bitNot(2 ^ a_mod - 1))
|
||||||
|
local idx = bitRShift(n, 5) + 1
|
||||||
|
arr[idx] = bitOr(arr[idx], mask)
|
||||||
|
n = bitAnd(n + 32, bitNot(31))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Bit array for named keys
|
-- Bit array for named keys
|
||||||
--- @alias ImBitArrayForNamedKeys ImBitArray
|
--- @alias ImBitArrayForNamedKeys ImBitArray
|
||||||
|
|
||||||
@@ -1030,11 +1073,30 @@ function ImBitArray(BITCOUNT, OFFSET)
|
|||||||
--- @param n int # 1-based
|
--- @param n int # 1-based
|
||||||
this.SetBit = function(self, n) n = n + OFFSET; IM_ASSERT(n >= 1 and n <= BITCOUNT); ImBitArraySetBit(self.Data, n); end
|
this.SetBit = function(self, n) n = n + OFFSET; IM_ASSERT(n >= 1 and n <= BITCOUNT); ImBitArraySetBit(self.Data, n); end
|
||||||
|
|
||||||
|
--- @param n int # 1-based
|
||||||
|
this.ClearBit = function(self, n) n = n + OFFSET; IM_ASSERT(n >= 1 and n <= BITCOUNT); ImBitArrayClearBit(self.Data, n); end
|
||||||
|
--- @param n int # 1-based, range [n..n2)
|
||||||
|
this.SetBitRange = function(self, n, n2) n = n + OFFSET; n2 = n2 + OFFSET; IM_ASSERT(n >= 1 and n <= BITCOUNT and n2 > n and n2 <= BITCOUNT + 1); ImBitArraySetBitRange(self.Data, n, n2); end
|
||||||
|
|
||||||
this:ClearAllBits()
|
this:ClearAllBits()
|
||||||
|
|
||||||
return this
|
return this
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Helper: ImBitVector
|
||||||
|
-- Store 1-bit per value.
|
||||||
|
--- @class ImBitVector
|
||||||
|
--- @field Storage ImVector<ImU32>
|
||||||
|
MT.ImBitVector = {}
|
||||||
|
MT.ImBitVector.__index = MT.ImBitVector
|
||||||
|
function ImBitVector() return setmetatable({ Storage = ImVector() }, MT.ImBitVector) end
|
||||||
|
function MT.ImBitVector:Create(sz) self.Storage:resize(bitRShift(sz + 31, 5)); for i = 1, self.Storage.Size do self.Storage.Data[i] = 0 end end
|
||||||
|
function MT.ImBitVector:Clear() self.Storage:clear() end
|
||||||
|
--- @param n int # 1-based
|
||||||
|
function MT.ImBitVector:TestBit(n) IM_ASSERT(n <= bitLShift(self.Storage.Size, 5)); return IM_BITARRAY_TESTBIT(self.Storage.Data, n) end
|
||||||
|
function MT.ImBitVector:SetBit(n) IM_ASSERT(n <= bitLShift(self.Storage.Size, 5)); ImBitArraySetBit(self.Storage.Data, n) end
|
||||||
|
function MT.ImBitVector:ClearBit(n) IM_ASSERT(n <= bitLShift(self.Storage.Size, 5)); ImBitArrayClearBit(self.Storage.Data, n) end
|
||||||
|
|
||||||
-- Stateful path API, add points then finish with PathFillConvex() or PathStroke()
|
-- Stateful path API, add points then finish with PathFillConvex() or PathStroke()
|
||||||
-- - Important: filled shapes must always use clockwise winding order! The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing.
|
-- - Important: filled shapes must always use clockwise winding order! The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing.
|
||||||
-- so e.g. 'PathArcTo(center, radius, PI * -0.5, PI)' is ok, whereas 'PathArcTo(center, radius, PI, PI * -0.5)' won't have correct anti-aliasing when followed by PathFillConvex().
|
-- so e.g. 'PathArcTo(center, radius, PI * -0.5, PI)' is ok, whereas 'PathArcTo(center, radius, PI, PI * -0.5)' won't have correct anti-aliasing when followed by PathFillConvex().
|
||||||
@@ -1266,9 +1328,13 @@ end
|
|||||||
--- @param key string
|
--- @param key string
|
||||||
--- @return ImGuiStyleVarInfo
|
--- @return ImGuiStyleVarInfo
|
||||||
--- @nodiscard
|
--- @nodiscard
|
||||||
|
MT.ImGuiStyleVarInfo = {}
|
||||||
|
MT.ImGuiStyleVarInfo.__index = MT.ImGuiStyleVarInfo
|
||||||
function ImGuiStyleVarInfo(count, data_type, key)
|
function ImGuiStyleVarInfo(count, data_type, key)
|
||||||
return { Count = count, DataType = data_type, Key = key }
|
return setmetatable({ Count = count, DataType = data_type, Key = key }, MT.ImGuiStyleVarInfo)
|
||||||
end
|
end
|
||||||
|
-- [Luau] no pointers: returns the field value (number, or the live ImVec2 table) of 'parent' (e.g. ImGuiStyle)
|
||||||
|
function MT.ImGuiStyleVarInfo:GetVarPtr(parent) return parent[self.Key] end
|
||||||
|
|
||||||
-- Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable.
|
-- Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable.
|
||||||
--- @class ImGuiStyleMod
|
--- @class ImGuiStyleMod
|
||||||
@@ -1383,11 +1449,11 @@ end
|
|||||||
--- @field RefVal any
|
--- @field RefVal any
|
||||||
--- @field StorageId ImGuiID
|
--- @field StorageId ImGuiID
|
||||||
--- @field ColorMarker ImU32
|
--- @field ColorMarker ImU32
|
||||||
local IMGUI_NEXT_ITEM_DATA = {}
|
MT.ImGuiNextItemData = {}
|
||||||
IMGUI_NEXT_ITEM_DATA.__index = IMGUI_NEXT_ITEM_DATA
|
MT.ImGuiNextItemData.__index = MT.ImGuiNextItemData
|
||||||
|
|
||||||
-- Also cleared manually by ItemAdd()!
|
-- Also cleared manually by ItemAdd()!
|
||||||
function IMGUI_NEXT_ITEM_DATA:ClearFlags()
|
function MT.ImGuiNextItemData:ClearFlags()
|
||||||
self.HasFlags = ImGuiNextItemDataFlags.None
|
self.HasFlags = ImGuiNextItemDataFlags.None
|
||||||
self.ItemFlagsSet = ImGuiItemFlags.None
|
self.ItemFlagsSet = ImGuiItemFlags.None
|
||||||
end
|
end
|
||||||
@@ -1410,7 +1476,7 @@ function ImGuiNextItemData()
|
|||||||
RefVal = 0, -- Not exposed yet, for ImGuiInputTextFlags.ParseEmptyAsRefVal
|
RefVal = 0, -- Not exposed yet, for ImGuiInputTextFlags.ParseEmptyAsRefVal
|
||||||
StorageId = 0, -- Set by SetNextItemStorageID()
|
StorageId = 0, -- Set by SetNextItemStorageID()
|
||||||
ColorMarker = 0 -- Set by SetNextItemColorMarker(). Not exposed yet, supported by DragScalar,SliderScalar and for ImGuiSliderFlags.ColorMarkers.
|
ColorMarker = 0 -- Set by SetNextItemColorMarker(). Not exposed yet, supported by DragScalar,SliderScalar and for ImGuiSliderFlags.ColorMarkers.
|
||||||
}, IMGUI_NEXT_ITEM_DATA)
|
}, MT.ImGuiNextItemData)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Storage for SetNexWindow** functions
|
-- Storage for SetNexWindow** functions
|
||||||
@@ -1433,10 +1499,10 @@ end
|
|||||||
--- @field BgAlphaVal number?
|
--- @field BgAlphaVal number?
|
||||||
--- @field MenuBarOffsetMinVal ImVec2?
|
--- @field MenuBarOffsetMinVal ImVec2?
|
||||||
--- @field RefreshFlagsVal int?
|
--- @field RefreshFlagsVal int?
|
||||||
local IMGUI_NEXT_WINDOW_DATA = {}
|
MT.ImGuiNextWindowData = {}
|
||||||
IMGUI_NEXT_WINDOW_DATA.__index = IMGUI_NEXT_WINDOW_DATA
|
MT.ImGuiNextWindowData.__index = MT.ImGuiNextWindowData
|
||||||
|
|
||||||
function IMGUI_NEXT_WINDOW_DATA:ClearFlags()
|
function MT.ImGuiNextWindowData:ClearFlags()
|
||||||
self.HasFlags = ImGuiNextWindowDataFlags.None
|
self.HasFlags = ImGuiNextWindowDataFlags.None
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1475,7 +1541,7 @@ function ImGuiNextWindowData()
|
|||||||
RefreshFlagsVal = nil,
|
RefreshFlagsVal = nil,
|
||||||
CacheKeySet = false, -- [Port] SetNextWindowCached()
|
CacheKeySet = false, -- [Port] SetNextWindowCached()
|
||||||
CacheKeyVal = nil
|
CacheKeyVal = nil
|
||||||
}, IMGUI_NEXT_WINDOW_DATA)
|
}, MT.ImGuiNextWindowData)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @enum ImGuiWindowBgClickFlags
|
--- @enum ImGuiWindowBgClickFlags
|
||||||
@@ -1738,21 +1804,29 @@ local function ImGuiInputTextState()
|
|||||||
SelectedAllMouseLock = false, -- after a double-click to select all, we ignore further mouse drags to update selection
|
SelectedAllMouseLock = false, -- after a double-click to select all, we ignore further mouse drags to update selection
|
||||||
EditedBefore = false, -- edited since activated
|
EditedBefore = false, -- edited since activated
|
||||||
EditedThisFrame = false, -- edited this frame
|
EditedThisFrame = false, -- edited this frame
|
||||||
|
WantReloadUserBuf = false, -- force a reload of user buf so it may be modified externally. may be automatic in future version.
|
||||||
|
LastMoveDirectionLR = ImGuiDir.Left, -- ImGuiDir_Left or ImGuiDir_Right. track last movement direction so when cursor cross over a word-wrapping boundaries we can display it on either line depending on last move.s
|
||||||
|
ReloadSelectionStart = 0,
|
||||||
|
ReloadSelectionEnd = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
return setmetatable(this, MT.ImGuiInputTextState)
|
return setmetatable(this, MT.ImGuiInputTextState)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function MT.ImGuiInputTextState:ClearText() self.TextLen = 0; self.TextA.Data[1] = 0; self:CursorClamp() end
|
||||||
|
function MT.ImGuiInputTextState:ClearFreeMemory() self.TextA:clear(); self.TextToRevertTo:clear() end
|
||||||
|
function MT.ImGuiInputTextState:GetText() if self.TextA.Data then return self.TextA.Data else return { 0 } end end -- [Luau] byte table (char[])
|
||||||
|
|
||||||
-- Internal temporary state for deactivating InputText() instances.
|
-- Internal temporary state for deactivating InputText() instances.
|
||||||
-- Store as part of ImGuiDeactivatedItemData?
|
-- Store as part of ImGuiDeactivatedItemData?
|
||||||
--- @class ImGuiInputTextDeactivatedState
|
--- @class ImGuiInputTextDeactivatedState
|
||||||
--- @field ID ImGuiID # widget id owning the text state (which just got deactivated)
|
--- @field ID ImGuiID # widget id owning the text state (which just got deactivated)
|
||||||
--- @field ElapseFrame int
|
--- @field ElapseFrame int
|
||||||
--- @field TextA ImVector<char> # text buffer
|
--- @field TextA ImVector<char> # text buffer
|
||||||
local IMGUI_INPUT_TEXT_DEACTIVATED_STATE = {}
|
MT.ImGuiInputTextDeactivatedState = {}
|
||||||
IMGUI_INPUT_TEXT_DEACTIVATED_STATE.__index = IMGUI_INPUT_TEXT_DEACTIVATED_STATE
|
MT.ImGuiInputTextDeactivatedState.__index = MT.ImGuiInputTextDeactivatedState
|
||||||
|
|
||||||
function IMGUI_INPUT_TEXT_DEACTIVATED_STATE:ClearFreeMemory()
|
function MT.ImGuiInputTextDeactivatedState:ClearFreeMemory()
|
||||||
self.ID = 0
|
self.ID = 0
|
||||||
self.ElapseFrame = 0
|
self.ElapseFrame = 0
|
||||||
self.TextA:clear()
|
self.TextA:clear()
|
||||||
@@ -1765,7 +1839,7 @@ local function ImGuiInputTextDeactivatedState()
|
|||||||
ID = 0, -- widget id owning the text state (which just got deactivated)
|
ID = 0, -- widget id owning the text state (which just got deactivated)
|
||||||
ElapseFrame = 0,
|
ElapseFrame = 0,
|
||||||
TextA = ImVector() -- text buffer
|
TextA = ImVector() -- text buffer
|
||||||
}, IMGUI_INPUT_TEXT_DEACTIVATED_STATE)
|
}, MT.ImGuiInputTextDeactivatedState)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @alias ImGuiKeyRoutingIndex ImS16
|
--- @alias ImGuiKeyRoutingIndex ImS16
|
||||||
@@ -1798,10 +1872,10 @@ end
|
|||||||
--- @field Index ImGuiKeyRoutingIndex[] # Index of first entry in Entries[]
|
--- @field Index ImGuiKeyRoutingIndex[] # Index of first entry in Entries[]
|
||||||
--- @field Entries ImVector<ImGuiKeyRoutingData>
|
--- @field Entries ImVector<ImGuiKeyRoutingData>
|
||||||
--- @field EntriesNext ImVector<ImGuiKeyRoutingData> # Double-buffer to avoid reallocation (could use a shared buffer)
|
--- @field EntriesNext ImVector<ImGuiKeyRoutingData> # Double-buffer to avoid reallocation (could use a shared buffer)
|
||||||
local _ImGuiKeyRoutingTable = {}
|
MT.ImGuiKeyRoutingTable = {}
|
||||||
_ImGuiKeyRoutingTable.__index = _ImGuiKeyRoutingTable
|
MT.ImGuiKeyRoutingTable.__index = MT.ImGuiKeyRoutingTable
|
||||||
|
|
||||||
function _ImGuiKeyRoutingTable:Clear()
|
function MT.ImGuiKeyRoutingTable:Clear()
|
||||||
for n = 1, ImGuiKey.NamedKey_COUNT do self.Index[n] = -1 end
|
for n = 1, ImGuiKey.NamedKey_COUNT do self.Index[n] = -1 end
|
||||||
self.Entries:clear()
|
self.Entries:clear()
|
||||||
self.EntriesNext:clear()
|
self.EntriesNext:clear()
|
||||||
@@ -1813,7 +1887,7 @@ local function ImGuiKeyRoutingTable()
|
|||||||
Index = {}, -- Index of first entry in Entries[]
|
Index = {}, -- Index of first entry in Entries[]
|
||||||
Entries = ImVector(),
|
Entries = ImVector(),
|
||||||
EntriesNext = ImVector() -- Double-buffer to avoid reallocation (could use a shared buffer)
|
EntriesNext = ImVector() -- Double-buffer to avoid reallocation (could use a shared buffer)
|
||||||
}, _ImGuiKeyRoutingTable)
|
}, MT.ImGuiKeyRoutingTable)
|
||||||
|
|
||||||
this:Clear()
|
this:Clear()
|
||||||
|
|
||||||
@@ -1899,10 +1973,10 @@ end
|
|||||||
--- @field DistBox float # Move -- Best candidate box distance to current NavId
|
--- @field DistBox float # Move -- Best candidate box distance to current NavId
|
||||||
--- @field DistCenter float # Move -- Best candidate center distance to current NavId
|
--- @field DistCenter float # Move -- Best candidate center distance to current NavId
|
||||||
--- @field DistAxial float # Move -- Best candidate axial distance to current NavId
|
--- @field DistAxial float # Move -- Best candidate axial distance to current NavId
|
||||||
local IMGUI_NAV_ITEM_DATA = {}
|
MT.ImGuiNavItemData = {}
|
||||||
IMGUI_NAV_ITEM_DATA.__index = IMGUI_NAV_ITEM_DATA
|
MT.ImGuiNavItemData.__index = MT.ImGuiNavItemData
|
||||||
|
|
||||||
function IMGUI_NAV_ITEM_DATA:Clear()
|
function MT.ImGuiNavItemData:Clear()
|
||||||
self.Window = nil
|
self.Window = nil
|
||||||
self.ID = 0
|
self.ID = 0
|
||||||
self.FocusScopeId = 0
|
self.FocusScopeId = 0
|
||||||
@@ -1915,7 +1989,7 @@ end
|
|||||||
|
|
||||||
--- @return ImGuiNavItemData
|
--- @return ImGuiNavItemData
|
||||||
local function ImGuiNavItemData()
|
local function ImGuiNavItemData()
|
||||||
local this = setmetatable({ }, IMGUI_NAV_ITEM_DATA)
|
local this = setmetatable({ }, MT.ImGuiNavItemData)
|
||||||
this.RectRel = ImRect()
|
this.RectRel = ImRect()
|
||||||
this:Clear()
|
this:Clear()
|
||||||
return this
|
return this
|
||||||
@@ -2488,7 +2562,7 @@ function ImGuiContext(shared_font_atlas) -- TODO: tidy up / complete this struct
|
|||||||
DockContext = ImGuiDockContext(),
|
DockContext = ImGuiDockContext(),
|
||||||
DockNodeWindowMenuHandler = nil,
|
DockNodeWindowMenuHandler = nil,
|
||||||
DebugHoveredDockNode = nil, -- Hovered dock node.
|
DebugHoveredDockNode = nil, -- Hovered dock node.
|
||||||
CurrentTabBarStack = ImVector(), -- holds ImGuiTabBar references directly (no ImGuiPtrOrIndex needed in Lua)
|
CurrentTabBarStack = ImVector(), -- ImVector<ImGuiPtrOrIndex>
|
||||||
ShrinkWidthBuffer = ImVector(), -- ImGuiShrinkWidthItem
|
ShrinkWidthBuffer = ImVector(), -- ImGuiShrinkWidthItem
|
||||||
|
|
||||||
-- Multi-Select state
|
-- Multi-Select state
|
||||||
@@ -2652,10 +2726,10 @@ end
|
|||||||
--- @field WantApply bool # Set when loaded from .ini data
|
--- @field WantApply bool # Set when loaded from .ini data
|
||||||
--- @field WantDelete bool # Set to invalidate/delete the settings entry
|
--- @field WantDelete bool # Set to invalidate/delete the settings entry
|
||||||
--- @field Name string # Window name
|
--- @field Name string # Window name
|
||||||
local IMGUI_WINDOW_SETTINGS = {}
|
MT.ImGuiWindowSettings = {}
|
||||||
IMGUI_WINDOW_SETTINGS.__index = IMGUI_WINDOW_SETTINGS
|
MT.ImGuiWindowSettings.__index = MT.ImGuiWindowSettings
|
||||||
|
|
||||||
function IMGUI_WINDOW_SETTINGS:GetName()
|
function MT.ImGuiWindowSettings:GetName()
|
||||||
return self.Name
|
return self.Name
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2675,7 +2749,7 @@ function ImGuiWindowSettings()
|
|||||||
DockOrder = -1, -- Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible.
|
DockOrder = -1, -- Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible.
|
||||||
ClassId = 0, -- ID of window class if specified
|
ClassId = 0, -- ID of window class if specified
|
||||||
LastUsedDate = 0,
|
LastUsedDate = 0,
|
||||||
}, IMGUI_WINDOW_SETTINGS)
|
}, MT.ImGuiWindowSettings)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Simple column measurement, currently used for MenuItem() only.. This is very short-sighted/throw-away code and NOT a generic helper.
|
-- Simple column measurement, currently used for MenuItem() only.. This is very short-sighted/throw-away code and NOT a generic helper.
|
||||||
@@ -3391,6 +3465,8 @@ function ImGuiInputEvent()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- [Internal] Key ranges
|
-- [Internal] Key ranges
|
||||||
|
ImGuiKey_LegacyNativeKey_BEGIN = 0
|
||||||
|
ImGuiKey_LegacyNativeKey_END = 512
|
||||||
ImGuiKey_Keyboard_BEGIN = ImGuiKey.NamedKey_BEGIN
|
ImGuiKey_Keyboard_BEGIN = ImGuiKey.NamedKey_BEGIN
|
||||||
ImGuiKey_Keyboard_END = ImGuiKey.GamepadStart
|
ImGuiKey_Keyboard_END = ImGuiKey.GamepadStart
|
||||||
ImGuiKey_Gamepad_BEGIN = ImGuiKey.GamepadStart
|
ImGuiKey_Gamepad_BEGIN = ImGuiKey.GamepadStart
|
||||||
@@ -3715,5 +3791,86 @@ end
|
|||||||
--- @nodiscard
|
--- @nodiscard
|
||||||
function ImGuiFocusScopeData() return { ID = nil, WindowID = nil } end
|
function ImGuiFocusScopeData() return { ID = nil, WindowID = nil } end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- [Luau] Inline struct helpers / constructors from imgui.h + imgui_internal.h
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- Helper for running a block of code not more than once a frame
|
||||||
|
-- [Luau] no operator bool(): call the object, e.g. 'if once() then ... end'
|
||||||
|
MT.ImGuiOnceUponAFrame = {}
|
||||||
|
MT.ImGuiOnceUponAFrame.__index = MT.ImGuiOnceUponAFrame
|
||||||
|
MT.ImGuiOnceUponAFrame.__call = function(self) local current_frame = ImGui.GetFrameCount(); if self.RefFrame == current_frame then return false end; self.RefFrame = current_frame; return true end
|
||||||
|
function ImGuiOnceUponAFrame() return setmetatable({ RefFrame = -1 }, MT.ImGuiOnceUponAFrame) end
|
||||||
|
|
||||||
|
-- [Internal] ImGuiTextFilter item
|
||||||
|
-- [Luau] stores the item text as a Lua string (upstream: Begin pointer + Len)
|
||||||
|
--- @param buf string
|
||||||
|
--- @param b int # 1-based
|
||||||
|
--- @param e int # exclusive
|
||||||
|
function ImGuiTextFilterItem(buf, b, e) IM_ASSERT(e > b); return { Text = string.sub(buf, b, e - 1), CountInclude = 0, MatchIncludesMask = 0 } end
|
||||||
|
|
||||||
|
-- A date in YYYYMMDD format packed into 16-bits
|
||||||
|
--- @class ImGuiPackedDate
|
||||||
|
MT.ImGuiPackedDate = {}
|
||||||
|
MT.ImGuiPackedDate.__index = MT.ImGuiPackedDate
|
||||||
|
--- @param yyyymmdd? int
|
||||||
|
function ImGuiPackedDate(yyyymmdd)
|
||||||
|
local this = setmetatable({ Year = 0, Month = 0, Day = 0 }, MT.ImGuiPackedDate)
|
||||||
|
if yyyymmdd ~= nil then -- Pack
|
||||||
|
this.Year = bitAnd(math.floor(yyyymmdd / 10000) - 2000, 0x7F) -- Year since 2000 (7 bits)
|
||||||
|
this.Month = bitAnd(math.floor(yyyymmdd / 100) % 100, 0x0F) -- Month (1-12) (4 bits)
|
||||||
|
this.Day = bitAnd(yyyymmdd % 100, 0x1F) -- Day (1-31) (5 bits)
|
||||||
|
end
|
||||||
|
return this
|
||||||
|
end
|
||||||
|
function MT.ImGuiPackedDate:IsValid() return self.Year ~= 0 and self.Month ~= 0 and self.Day ~= 0 end
|
||||||
|
function MT.ImGuiPackedDate:Unpack() if self.Year ~= 0 and self.Month ~= 0 and self.Day ~= 0 then return ((self.Year + 2000) * 10000) + (self.Month * 100) + self.Day end; return 0 end -- Unpack
|
||||||
|
function MT.ImGuiPackedDate:SubtractMonths(m) while m > 0 do if self.Month == 1 then self.Year = bitAnd(self.Year - 1, 0x7F) end; self.Month = (self.Month == 1) and 12 or self.Month - 1; m = m - 1 end end -- FIXME-OPT: Stupid but enough for what we do with it.
|
||||||
|
|
||||||
|
-- Pointer or index, e.g. g.CurrentTabBarStack[]
|
||||||
|
-- [Luau] overload by argument type: number = index, otherwise pointer
|
||||||
|
function ImGuiPtrOrIndex(ptr_or_index)
|
||||||
|
if type(ptr_or_index) == "number" then return { Ptr = nil, Index = ptr_or_index } end
|
||||||
|
return { Ptr = ptr_or_index, Index = -1 }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Note that Max is exclusive, so perhaps should be using a Begin/End convention.
|
||||||
|
--- @class ImGuiListClipperRange
|
||||||
|
MT.ImGuiListClipperRange = {}
|
||||||
|
function MT.ImGuiListClipperRange.FromIndices(min, max) return { Min = min, Max = max, PosToIndexConvert = false, PosToIndexOffsetMin = 0, PosToIndexOffsetMax = 0 } end
|
||||||
|
function MT.ImGuiListClipperRange.FromPositions(y1, y2, off_min, off_max) return { Min = _Trunc(y1), Max = _Trunc(y2), PosToIndexConvert = true, PosToIndexOffsetMin = off_min, PosToIndexOffsetMax = off_max } end
|
||||||
|
|
||||||
|
-- Temporary clipper data, buffers shared/reused between instances
|
||||||
|
--- @class ImGuiListClipperData
|
||||||
|
MT.ImGuiListClipperData = {}
|
||||||
|
MT.ImGuiListClipperData.__index = MT.ImGuiListClipperData
|
||||||
|
function ImGuiListClipperData() return setmetatable({ ListClipper = nil, LossynessOffset = 0.0, StepNo = 0, ItemsFrozen = 0, Ranges = ImVector() }, MT.ImGuiListClipperData) end
|
||||||
|
function MT.ImGuiListClipperData:Reset(clipper) self.ListClipper = clipper; self.StepNo = 0; self.ItemsFrozen = 0; self.Ranges:resize(0) end
|
||||||
|
|
||||||
|
function ImGuiStackLevelInfo() return { ID = 0, QueryFrameCount = 0, QuerySuccess = false, DataType = -1, DescOffset = -1 } end
|
||||||
|
function ImGuiDebugItemPathQuery() return { MainID = 0, Active = false, Complete = false, Step = 0, Results = ImVector(), ResultsDescBuf = ImGuiTextBuffer(), ResultPathBuf = ImGuiTextBuffer() } end
|
||||||
|
function ImGuiIDStackTool() return { OptHexEncodeNonAsciiChars = true, OptCopyToClipboardOnCtrlC = false, LastActiveFrame = -1, CopyToClipboardLastTime = -FLT_MAX } end
|
||||||
|
function ImGuiContextHook() return { HookId = 0, Type = 0, Owner = 0, Callback = nil, UserData = nil } end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- [Luau] ImGui:: inline helpers from imgui_internal.h
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function ImGui.GetCurrentTable() local g = GImGui; return g.CurrentTable end
|
||||||
|
--- @param window ImGuiWindow
|
||||||
|
--- @param parent_window ImGuiWindow?
|
||||||
|
function ImGui.SetWindowParentWindowForFocusRoute(window, parent_window) window.ParentWindowForFocusRoute = parent_window end -- You may also use SetNextWindowClass()'s FocusRouteParentWindowId field.
|
||||||
|
function ImGui.GetPixelDensity() return GImGui.FontRasterizerDensity end -- [Luau] g.FontRasterizerDensity == upstream g.CurrentPixelDensity
|
||||||
|
function ImGui.ScrollToBringRectIntoView(window, rect) ImGui.ScrollToRect(window, rect, ImGuiScrollFlags.KeepVisibleEdgeY) end
|
||||||
|
function ImGui.GetItemStatusFlags() local g = GImGui; return g.LastItemData.StatusFlags end
|
||||||
|
function ImGui.GetActiveID() local g = GImGui; return g.ActiveId end
|
||||||
|
function ImGui.GetFocusID() local g = GImGui; return g.NavId end
|
||||||
|
function ImGui.IsLegacyKey(key) return key >= ImGuiKey_LegacyNativeKey_BEGIN and key < ImGuiKey_LegacyNativeKey_END end
|
||||||
|
function ImGui.GetWindowDockNode() local g = GImGui; return g.CurrentWindow.DockNode end
|
||||||
|
function ImGui.GetCurrentFocusScope() local g = GImGui; return g.CurrentFocusScopeId end -- Focus scope we are outputting into, set by PushFocusScope()
|
||||||
|
function ImGui.GetCurrentTabBar() local g = GImGui; return g.CurrentTabBar end
|
||||||
|
-- This may be useful to apply workaround that a based on distinguish whenever an item is active as a text input field.
|
||||||
|
function ImGui.IsItemActiveAsInputText() local g = GImGui; return g.ActiveId ~= 0 and g.ActiveId == g.LastItemData.ID and g.InputTextState.ID == g.LastItemData.ID end
|
||||||
|
|
||||||
|
|
||||||
return true -- [Roblox] ModuleScripts must return exactly one value
|
return true -- [Roblox] ModuleScripts must return exactly one value
|
||||||
|
|||||||
+53
-12
@@ -331,9 +331,13 @@ end
|
|||||||
|
|
||||||
-- Storage for a table .ini settings
|
-- Storage for a table .ini settings
|
||||||
--- @class ImGuiTableSettings
|
--- @class ImGuiTableSettings
|
||||||
|
MT.ImGuiTableSettings = {}
|
||||||
|
MT.ImGuiTableSettings.__index = MT.ImGuiTableSettings
|
||||||
function ImGuiTableSettings()
|
function ImGuiTableSettings()
|
||||||
return { ID = 0, SaveFlags = 0, RefScale = 0.0, ColumnsCount = 0, ColumnsCountMax = 0, LastUsedDate = 0, WantApply = false, Columns = {} }
|
return setmetatable({ ID = 0, SaveFlags = 0, RefScale = 0.0, ColumnsCount = 0, ColumnsCountMax = 0, LastUsedDate = 0, WantApply = false, Columns = {} }, MT.ImGuiTableSettings)
|
||||||
end
|
end
|
||||||
|
-- [Luau] column settings are stored in a 0-based .Columns table (upstream: allocated right after the struct)
|
||||||
|
function MT.ImGuiTableSettings:GetColumnSettings() return self.Columns end
|
||||||
|
|
||||||
-- Storage data for a single column for legacy Columns() api
|
-- Storage data for a single column for legacy Columns() api
|
||||||
--- @class ImGuiOldColumnData
|
--- @class ImGuiOldColumnData
|
||||||
@@ -4394,6 +4398,17 @@ function ImGui.TableLoadSettingsForColumn(column, column_settings, load_flags)
|
|||||||
column.SortDirection = column_settings.SortDirection
|
column.SortDirection = column_settings.SortDirection
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- [Luau] boolean "less than" for table.sort; takes (table, lhs column idx, rhs column idx) instead of ImGuiTableFixDisplayOrderColumnData
|
||||||
|
local function TableFixDisplayOrderComparer(table_, lhs_idx, rhs_idx)
|
||||||
|
-- Assume ImGuiTableColumnIdx == signed short, to turn -1 into a large value so that it always sort after.
|
||||||
|
local lhs_order, rhs_order = table_.Columns[lhs_idx].DisplayOrder, table_.Columns[rhs_idx].DisplayOrder
|
||||||
|
if lhs_order < 0 then lhs_order = lhs_order + 0x10000 end
|
||||||
|
if rhs_order < 0 then rhs_order = rhs_order + 0x10000 end
|
||||||
|
local order_delta = lhs_order - rhs_order
|
||||||
|
if order_delta ~= 0 then return order_delta < 0 end
|
||||||
|
return lhs_idx < rhs_idx
|
||||||
|
end
|
||||||
|
|
||||||
-- Fix invalid display order data: compact values (0,1,3 -> 0,1,2); preserve relative order (0,3,1 -> 0,2,1); deduplicate (0,4,1,1 -> 0,3,1,2)
|
-- Fix invalid display order data: compact values (0,1,3 -> 0,1,2); preserve relative order (0,3,1 -> 0,2,1); deduplicate (0,4,1,1 -> 0,3,1,2)
|
||||||
function ImGui.TableFixDisplayOrder(table_)
|
function ImGui.TableFixDisplayOrder(table_)
|
||||||
if band(table_.Flags, ImGuiTableFlags.Reorderable) == 0 then
|
if band(table_.Flags, ImGuiTableFlags.Reorderable) == 0 then
|
||||||
@@ -4408,17 +4423,7 @@ function ImGui.TableFixDisplayOrder(table_)
|
|||||||
fdo_columns[n + 1] = n
|
fdo_columns[n + 1] = n
|
||||||
end
|
end
|
||||||
-- Sort by DisplayOrder and then Index
|
-- Sort by DisplayOrder and then Index
|
||||||
-- Assume ImGuiTableColumnIdx == signed short, to turn -1 into a large value so that it always sort after.
|
table.sort(fdo_columns, function(lhs_idx, rhs_idx) return TableFixDisplayOrderComparer(table_, lhs_idx, rhs_idx) end)
|
||||||
local function key(idx)
|
|
||||||
local o = table_.Columns[idx].DisplayOrder
|
|
||||||
if o < 0 then o = o + 0x10000 end
|
|
||||||
return o
|
|
||||||
end
|
|
||||||
table.sort(fdo_columns, function(lhs_idx, rhs_idx)
|
|
||||||
local a, b = key(lhs_idx), key(rhs_idx)
|
|
||||||
if a ~= b then return a < b end
|
|
||||||
return lhs_idx < rhs_idx
|
|
||||||
end)
|
|
||||||
for n = 0, table_.ColumnsCount - 1 do
|
for n = 0, table_.ColumnsCount - 1 do
|
||||||
table_.Columns[fdo_columns[n + 1]].DisplayOrder = n
|
table_.Columns[fdo_columns[n + 1]].DisplayOrder = n
|
||||||
end
|
end
|
||||||
@@ -4427,6 +4432,27 @@ function ImGui.TableFixDisplayOrder(table_)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function TableSettingsHandler_Cleanup(ctx, handler, args)
|
||||||
|
local g = ctx
|
||||||
|
for i = 0, g.Tables:GetMapSize() - 1 do
|
||||||
|
local table_ = g.Tables:GetByIndex(i)
|
||||||
|
if table_ then
|
||||||
|
table_.SettingsOffset = -1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- [Luau] settings.LastUsedDate is stored unpacked (YYYYMMDD int, 0 = none); g.SessionDate is an ImGuiPackedDate when set
|
||||||
|
for _, settings in g.SettingsTables:iter() do
|
||||||
|
local is_valid = ImGuiPackedDate(settings.LastUsedDate):IsValid()
|
||||||
|
if args._DiscardOlderThanDate ~= 0 and settings.LastUsedDate < args._DiscardOlderThanDate then
|
||||||
|
settings.ID = 0
|
||||||
|
elseif args.DiscardWhenMissingDate and not is_valid then
|
||||||
|
settings.ID = 0
|
||||||
|
elseif args.SetCurrentSessionDateToAll or (args.SetCurrentSessionDateWhenMissingDate and not is_valid) then
|
||||||
|
settings.LastUsedDate = g.SessionDate and g.SessionDate:Unpack() or 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function ForEachTable(g, fn)
|
local function ForEachTable(g, fn)
|
||||||
for i = 0, g.Tables:GetMapSize() - 1 do
|
for i = 0, g.Tables:GetMapSize() - 1 do
|
||||||
local t = g.Tables:GetByIndex(i)
|
local t = g.Tables:GetByIndex(i)
|
||||||
@@ -4552,6 +4578,7 @@ function ImGui.TableSettingsAddSettingsHandler()
|
|||||||
ini_handler.ReadLineFn = TableSettingsHandler_ReadLine
|
ini_handler.ReadLineFn = TableSettingsHandler_ReadLine
|
||||||
ini_handler.ApplyAllFn = TableSettingsHandler_ApplyAll
|
ini_handler.ApplyAllFn = TableSettingsHandler_ApplyAll
|
||||||
ini_handler.WriteAllFn = TableSettingsHandler_WriteAll
|
ini_handler.WriteAllFn = TableSettingsHandler_WriteAll
|
||||||
|
ini_handler.CleanupFn = TableSettingsHandler_Cleanup
|
||||||
ImGui.AddSettingsHandler(ini_handler)
|
ImGui.AddSettingsHandler(ini_handler)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -4615,6 +4642,20 @@ function ImGui.TableGcCompactSettings()
|
|||||||
ForEachTable(g, function(t) t.SettingsOffset = -1 end)
|
ForEachTable(g, function(t) t.SettingsOffset = -1 end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- [SECTION] Tables: Debugging
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- [Luau] global (upstream: static) so ImGui.DebugNodeTable() in imgui.lua can use it
|
||||||
|
|
||||||
|
function DebugNodeTableGetSizingPolicyDesc(sizing_policy)
|
||||||
|
sizing_policy = band(sizing_policy, ImGuiTableFlags.SizingMask_)
|
||||||
|
if sizing_policy == ImGuiTableFlags.SizingFixedFit then return "FixedFit" end
|
||||||
|
if sizing_policy == ImGuiTableFlags.SizingFixedSame then return "FixedSame" end
|
||||||
|
if sizing_policy == ImGuiTableFlags.SizingStretchProp then return "StretchProp" end
|
||||||
|
if sizing_policy == ImGuiTableFlags.SizingStretchSame then return "StretchSame" end
|
||||||
|
return "N/A"
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- [SECTION] Columns, BeginColumns, EndColumns, etc.
|
-- [SECTION] Columns, BeginColumns, EndColumns, etc.
|
||||||
-- (This is a legacy API, prefer using BeginTable/EndTable!)
|
-- (This is a legacy API, prefer using BeginTable/EndTable!)
|
||||||
|
|||||||
+180
-42
@@ -2598,12 +2598,14 @@ function ImGui.RoundScalarWithFormatT(format, data_type, v)
|
|||||||
return v -- Don't apply if the value is not visible in the format string
|
return v -- Don't apply if the value is not visible in the format string
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Sanitize format
|
-- Sanitize format
|
||||||
|
local fmt_sanitized = ImParseFormatSanitizeForPrinting(string.sub(format, fmt_start), nil, 32)
|
||||||
|
|
||||||
-- Format value with our rounding, and read back
|
-- Format value with our rounding, and read back
|
||||||
local str = ImFormatString(format, v)
|
local v_str = ImFormatString(fmt_sanitized, v)
|
||||||
|
-- [Luau] leading spaces: ImAtof() skips them
|
||||||
|
|
||||||
v = ImAtof(str) or v
|
v = ImAtof(v_str) or v
|
||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2689,6 +2691,30 @@ local function ImParseFormatTrimDecorations(fmt)
|
|||||||
return string.sub(fmt, fmt_start, fmt_end - 1)
|
return string.sub(fmt, fmt_start, fmt_end - 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Sanitize format
|
||||||
|
-- - Zero terminate so extra characters after format (e.g. "%f123") don't confuse atof/atoi
|
||||||
|
-- - stb_sprintf.h supports several new modifiers which format numbers in a way that also makes them incompatible atof/atoi.
|
||||||
|
-- [Luau] fmt_out is a byte table (may be nil); returns the sanitized format as a string
|
||||||
|
--- @param fmt_in string
|
||||||
|
--- @param fmt_out char[]?
|
||||||
|
--- @param fmt_out_size size_t
|
||||||
|
function ImParseFormatSanitizeForPrinting(fmt_in, fmt_out, fmt_out_size)
|
||||||
|
local fmt_end = ImParseFormatFindEnd(fmt_in, 1)
|
||||||
|
-- IM_UNUSED(fmt_out_size)
|
||||||
|
IM_ASSERT(fmt_end < fmt_out_size) -- Format is too long, let us know if this happens to you!
|
||||||
|
fmt_out = fmt_out or {}
|
||||||
|
local n = 0
|
||||||
|
for i = 1, fmt_end - 1 do
|
||||||
|
local c = string.byte(fmt_in, i)
|
||||||
|
if c ~= 39 and c ~= 36 and c ~= 95 then -- Custom flags provided by stb_sprintf.h. POSIX 2008 also supports '.
|
||||||
|
n = n + 1
|
||||||
|
fmt_out[n] = c
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fmt_out[n + 1] = 0 -- Zero-terminate
|
||||||
|
return string.char(unpack(fmt_out, 1, n))
|
||||||
|
end
|
||||||
|
|
||||||
-- - For scanning we need to remove all width and precision fields and flags "%+3.7f" -> "%f". BUT don't strip types like "%I64d" which includes digits. ! "%07I64d" -> "%I64d"
|
-- - For scanning we need to remove all width and precision fields and flags "%+3.7f" -> "%f". BUT don't strip types like "%I64d" which includes digits. ! "%07I64d" -> "%I64d"
|
||||||
--- @param fmt_in string
|
--- @param fmt_in string
|
||||||
--- @param fmt_out char[]
|
--- @param fmt_out char[]
|
||||||
@@ -3290,6 +3316,18 @@ function ImGui.DragBehaviorT(TYPE, SIGNEDTYPE, data_type, v, v_speed, v_min, v_m
|
|||||||
return v, true
|
return v, true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function ShortcutsForCancel(id)
|
||||||
|
local g = GImGui
|
||||||
|
local is_cancel_with_keyboard = ImGui.Shortcut(ImGuiKey.Escape, ImGuiInputFlags.None, id)
|
||||||
|
-- [Luau] ImGuiKey_NavGamepadCancel macro inlined (io.ConfigNavSwapGamepadButtons is not ported: always FaceRight)
|
||||||
|
local is_cancel_with_gamepad = bit32.band(g.IO.ConfigFlags, ImGuiConfigFlags.NavEnableGamepad) ~= 0 and bit32.band(g.IO.BackendFlags, ImGuiBackendFlags.HasGamepad) ~= 0 and ImGui.Shortcut(ImGuiKey.GamepadFaceRight, ImGuiInputFlags.None, id)
|
||||||
|
local is_cancel_with_mouse = ImGui.IsMouseReleased(ImGuiMouseButton.Right, id)
|
||||||
|
if is_cancel_with_mouse then
|
||||||
|
ImGui.SetKeyOwner(ImGuiKey.MouseRight, id)
|
||||||
|
end
|
||||||
|
return is_cancel_with_keyboard or is_cancel_with_gamepad or is_cancel_with_mouse
|
||||||
|
end
|
||||||
|
|
||||||
--- @param id ImGuiID
|
--- @param id ImGuiID
|
||||||
--- @param data_type ImGuiDataType
|
--- @param data_type ImGuiDataType
|
||||||
--- @param v number
|
--- @param v number
|
||||||
@@ -3311,6 +3349,13 @@ function ImGui.DragBehavior(id, data_type, v, v_speed, min, max, format, flags)
|
|||||||
elseif (g.ActiveIdSource == ImGuiInputSource.Keyboard or g.ActiveIdSource == ImGuiInputSource.Gamepad) and g.NavActivatePressedId == id and not g.ActiveIdIsJustActivated then
|
elseif (g.ActiveIdSource == ImGuiInputSource.Keyboard or g.ActiveIdSource == ImGuiInputSource.Gamepad) and g.NavActivatePressedId == id and not g.ActiveIdIsJustActivated then
|
||||||
ImGui.ClearActiveID()
|
ImGui.ClearActiveID()
|
||||||
end
|
end
|
||||||
|
if ShortcutsForCancel(id) and g.ActiveId == id then
|
||||||
|
-- Canceling action reverts to initial value
|
||||||
|
local value_changed = (v ~= g.ActiveIdValueOnActivation)
|
||||||
|
v = g.ActiveIdValueOnActivation
|
||||||
|
ImGui.ClearActiveID()
|
||||||
|
return v, value_changed
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if g.ActiveId ~= id then
|
if g.ActiveId ~= id then
|
||||||
return v, false
|
return v, false
|
||||||
@@ -3869,9 +3914,7 @@ function ImGui.SliderBehaviorT(TYPE, SIGNEDTYPE, bb, id, data_type, v, v_min, v_
|
|||||||
local set_new_value = false
|
local set_new_value = false
|
||||||
local clicked_t = 0.0
|
local clicked_t = 0.0
|
||||||
if g.ActiveIdSource == ImGuiInputSource.Mouse then
|
if g.ActiveIdSource == ImGuiInputSource.Mouse then
|
||||||
if not g.IO.MouseDown[0] then
|
do
|
||||||
ImGui.ClearActiveID()
|
|
||||||
else
|
|
||||||
local mouse_abs_pos = g.IO.MousePos[axis_k]
|
local mouse_abs_pos = g.IO.MousePos[axis_k]
|
||||||
if g.ActiveIdIsJustActivated then
|
if g.ActiveIdIsJustActivated then
|
||||||
local grab_t = ImGui.ScaleRatioFromValueT(data_type, v, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize)
|
local grab_t = ImGui.ScaleRatioFromValueT(data_type, v, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize)
|
||||||
@@ -3891,11 +3934,6 @@ function ImGui.SliderBehaviorT(TYPE, SIGNEDTYPE, bb, id, data_type, v, v_min, v_
|
|||||||
set_new_value = true
|
set_new_value = true
|
||||||
end
|
end
|
||||||
elseif g.ActiveIdSource == ImGuiInputSource.Keyboard or g.ActiveIdSource == ImGuiInputSource.Gamepad then
|
elseif g.ActiveIdSource == ImGuiInputSource.Keyboard or g.ActiveIdSource == ImGuiInputSource.Gamepad then
|
||||||
if g.ActiveIdIsJustActivated then
|
|
||||||
g.SliderCurrentAccum = 0.0 -- Reset any stored nav delta upon activation
|
|
||||||
g.SliderCurrentAccumDirty = false
|
|
||||||
end
|
|
||||||
|
|
||||||
local input_delta = (axis == ImGuiAxis.X) and ImGui.GetNavTweakPressedAmount(axis) or -ImGui.GetNavTweakPressedAmount(axis)
|
local input_delta = (axis == ImGuiAxis.X) and ImGui.GetNavTweakPressedAmount(axis) or -ImGui.GetNavTweakPressedAmount(axis)
|
||||||
if input_delta ~= 0.0 then
|
if input_delta ~= 0.0 then
|
||||||
local tweak_slow = ImGui.IsKeyDown((g.NavInputSource == ImGuiInputSource.Gamepad) and ImGuiKey.NavGamepadTweakSlow or ImGuiKey.NavKeyboardTweakSlow)
|
local tweak_slow = ImGui.IsKeyDown((g.NavInputSource == ImGuiInputSource.Gamepad) and ImGuiKey.NavGamepadTweakSlow or ImGuiKey.NavKeyboardTweakSlow)
|
||||||
@@ -3922,9 +3960,7 @@ function ImGui.SliderBehaviorT(TYPE, SIGNEDTYPE, bb, id, data_type, v, v_min, v_
|
|||||||
end
|
end
|
||||||
|
|
||||||
local delta = g.SliderCurrentAccum
|
local delta = g.SliderCurrentAccum
|
||||||
if g.NavActivatePressedId == id and not g.ActiveIdIsJustActivated then
|
if g.SliderCurrentAccumDirty then
|
||||||
ImGui.ClearActiveID()
|
|
||||||
elseif g.SliderCurrentAccumDirty then
|
|
||||||
clicked_t = ImGui.ScaleRatioFromValueT(data_type, v, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize)
|
clicked_t = ImGui.ScaleRatioFromValueT(data_type, v, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize)
|
||||||
|
|
||||||
if (clicked_t >= 1.0 and delta > 0.0) or (clicked_t <= 0.0 and delta < 0.0) then -- This is to avoid applying the saturation when already past the limits
|
if (clicked_t >= 1.0 and delta > 0.0) or (clicked_t <= 0.0 and delta < 0.0) then -- This is to avoid applying the saturation when already past the limits
|
||||||
@@ -4016,6 +4052,30 @@ function ImGui.SliderBehavior(bb, id, data_type, v, min, max, format, flags, out
|
|||||||
IM_ASSERT((flags == 1 or bit32.band(flags, ImGuiSliderFlags.InvalidMask_) == 0), "Invalid ImGuiSliderFlags flags! Has the legacy 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead.")
|
IM_ASSERT((flags == 1 or bit32.band(flags, ImGuiSliderFlags.InvalidMask_) == 0), "Invalid ImGuiSliderFlags flags! Has the legacy 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead.")
|
||||||
IM_ASSERT(bit32.band(flags, ImGuiSliderFlags.WrapAround) == 0) -- Not supported by SliderXXX(), only by DragXXX()
|
IM_ASSERT(bit32.band(flags, ImGuiSliderFlags.WrapAround) == 0) -- Not supported by SliderXXX(), only by DragXXX()
|
||||||
|
|
||||||
|
-- Things we can do easily outside the SliderBehaviorT<> template, saves code generation.
|
||||||
|
local g = GImGui
|
||||||
|
if g.ActiveId == id then
|
||||||
|
if g.ActiveIdSource == ImGuiInputSource.Mouse and not g.IO.MouseDown[0] then
|
||||||
|
ImGui.ClearActiveID()
|
||||||
|
end
|
||||||
|
if g.ActiveIdSource == ImGuiInputSource.Keyboard or g.ActiveIdSource == ImGuiInputSource.Gamepad then
|
||||||
|
if g.ActiveIdIsJustActivated then
|
||||||
|
g.SliderCurrentAccum = 0.0 -- Reset any stored nav delta upon activation
|
||||||
|
g.SliderCurrentAccumDirty = false
|
||||||
|
end
|
||||||
|
if g.NavActivatePressedId == id and not g.ActiveIdIsJustActivated then
|
||||||
|
ImGui.ClearActiveID()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ShortcutsForCancel(id) and g.ActiveId == id then
|
||||||
|
-- Canceling action reverts to initial value
|
||||||
|
local value_changed = (v ~= g.ActiveIdValueOnActivation)
|
||||||
|
v = g.ActiveIdValueOnActivation
|
||||||
|
ImGui.ClearActiveID()
|
||||||
|
return v, value_changed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if data_type == ImGuiDataType.S8 then
|
if data_type == ImGuiDataType.S8 then
|
||||||
local v32 = (ImS32)((ImS8)(v)); local r
|
local v32 = (ImS32)((ImS8)(v)); local r
|
||||||
v32, r = ImGui.SliderBehaviorT(ImS32, ImS32, bb, id, ImGuiDataType.S32, v32, min, max, format, flags, out_grab_bb)
|
v32, r = ImGui.SliderBehaviorT(ImS32, ImS32, bb, id, ImGuiDataType.S32, v32, min, max, format, flags, out_grab_bb)
|
||||||
@@ -4602,7 +4662,7 @@ end
|
|||||||
|
|
||||||
--- @param obj ImGuiInputTextState
|
--- @param obj ImGuiInputTextState
|
||||||
--- @param idx int
|
--- @param idx int
|
||||||
local function STB_TEXTEDIT_MOVEWORDRIGHT_MAC(obj, idx)
|
function ImStb.TEXTEDIT_MOVEWORDRIGHT_MAC(obj, idx)
|
||||||
local len = obj.TextLen
|
local len = obj.TextLen
|
||||||
idx = ImStb.TEXTEDIT_GETNEXTCHARINDEX(obj, idx)
|
idx = ImStb.TEXTEDIT_GETNEXTCHARINDEX(obj, idx)
|
||||||
while idx <= len and not ImStb.is_word_boundary_from_left(obj, idx) do
|
while idx <= len and not ImStb.is_word_boundary_from_left(obj, idx) do
|
||||||
@@ -4613,7 +4673,7 @@ end
|
|||||||
|
|
||||||
--- @param obj ImGuiInputTextState
|
--- @param obj ImGuiInputTextState
|
||||||
--- @param idx int
|
--- @param idx int
|
||||||
local function STB_TEXTEDIT_MOVEWORDRIGHT_WIN(obj, idx)
|
function ImStb.TEXTEDIT_MOVEWORDRIGHT_WIN(obj, idx)
|
||||||
idx = ImStb.TEXTEDIT_GETNEXTCHARINDEX(obj, idx)
|
idx = ImStb.TEXTEDIT_GETNEXTCHARINDEX(obj, idx)
|
||||||
local len = obj.TextLen
|
local len = obj.TextLen
|
||||||
while idx <= len and not ImStb.is_word_boundary_from_right(obj, idx) do
|
while idx <= len and not ImStb.is_word_boundary_from_right(obj, idx) do
|
||||||
@@ -4627,9 +4687,9 @@ end
|
|||||||
function ImStb.TEXTEDIT_MOVEWORDRIGHT(obj, idx)
|
function ImStb.TEXTEDIT_MOVEWORDRIGHT(obj, idx)
|
||||||
local g = obj.Ctx
|
local g = obj.Ctx
|
||||||
if g.IO.ConfigMacOSXBehaviors then
|
if g.IO.ConfigMacOSXBehaviors then
|
||||||
return STB_TEXTEDIT_MOVEWORDRIGHT_MAC(obj, idx)
|
return ImStb.TEXTEDIT_MOVEWORDRIGHT_MAC(obj, idx)
|
||||||
else
|
else
|
||||||
return STB_TEXTEDIT_MOVEWORDRIGHT_WIN(obj, idx)
|
return ImStb.TEXTEDIT_MOVEWORDRIGHT_WIN(obj, idx)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -4830,6 +4890,13 @@ function MT.ImGuiInputTextState:CursorClamp()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function MT.ImGuiInputTextState:HasSelection() return self.Stb.select_start ~= self.Stb.select_end end
|
function MT.ImGuiInputTextState:HasSelection() return self.Stb.select_start ~= self.Stb.select_end end
|
||||||
|
function MT.ImGuiInputTextState:ClearSelection() self.Stb.select_start = self.Stb.cursor; self.Stb.select_end = self.Stb.cursor end
|
||||||
|
-- [Luau] positions are 1-based byte indices (upstream: 0-based)
|
||||||
|
function MT.ImGuiInputTextState:GetCursorPos() return self.Stb.cursor end
|
||||||
|
function MT.ImGuiInputTextState:GetSelectionStart() return self.Stb.select_start end
|
||||||
|
function MT.ImGuiInputTextState:GetSelectionEnd() return self.Stb.select_end end
|
||||||
|
function MT.ImGuiInputTextState:SetSelection(start, _end) self.Stb.select_start = start; self.Stb.cursor = _end; self.Stb.select_end = _end end
|
||||||
|
function MT.ImGuiInputTextState:GetPreferredOffsetX() if self.Stb.has_preferred_x then return self.Stb.preferred_x else return -1 end end
|
||||||
|
|
||||||
function MT.ImGuiInputTextState:SelectAll()
|
function MT.ImGuiInputTextState:SelectAll()
|
||||||
self.Stb.select_start = 1
|
self.Stb.select_start = 1
|
||||||
@@ -4838,6 +4905,10 @@ function MT.ImGuiInputTextState:SelectAll()
|
|||||||
self.Stb.has_preferred_x = false
|
self.Stb.has_preferred_x = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function MT.ImGuiInputTextState:ReloadUserBufAndSelectAll() self.WantReloadUserBuf = true; self.ReloadSelectionStart = 1; self.ReloadSelectionEnd = INT_MAX end
|
||||||
|
function MT.ImGuiInputTextState:ReloadUserBufAndKeepSelection() self.WantReloadUserBuf = true; self.ReloadSelectionStart = self.Stb.select_start; self.ReloadSelectionEnd = self.Stb.select_end end
|
||||||
|
function MT.ImGuiInputTextState:ReloadUserBufAndMoveToEnd() self.WantReloadUserBuf = true; self.ReloadSelectionStart = INT_MAX; self.ReloadSelectionEnd = INT_MAX end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function ImGui.PushPasswordFont()
|
function ImGui.PushPasswordFont()
|
||||||
@@ -4989,9 +5060,9 @@ local function InputTextFilterCharacter(ctx, state, char, callback, user_data, i
|
|||||||
callback_data.EventFlag = ImGuiInputTextFlags.CallbackCharFilter
|
callback_data.EventFlag = ImGuiInputTextFlags.CallbackCharFilter
|
||||||
callback_data.EventChar = c
|
callback_data.EventChar = c
|
||||||
callback_data.EventActivated = (state ~= nil and g.ActiveId == state.ID and g.ActiveIdIsJustActivated)
|
callback_data.EventActivated = (state ~= nil and g.ActiveId == state.ID and g.ActiveIdIsJustActivated)
|
||||||
callback_data.CursorPos = state.Stb.cursor
|
callback_data.CursorPos = state.Stb.cursor - 1 -- [Luau] callback positions are 0-based
|
||||||
callback_data.SelectionStart = state.Stb.select_start
|
callback_data.SelectionStart = state.Stb.select_start - 1
|
||||||
callback_data.SelectionEnd = state.Stb.select_end
|
callback_data.SelectionEnd = state.Stb.select_end - 1
|
||||||
callback_data.UserData = user_data
|
callback_data.UserData = user_data
|
||||||
if callback(callback_data) ~= 0 then
|
if callback(callback_data) ~= 0 then
|
||||||
return char, false
|
return char, false
|
||||||
@@ -5573,7 +5644,7 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
|
|||||||
if not stbte.HAS_SELECTION(state.Stb) then
|
if not stbte.HAS_SELECTION(state.Stb) then
|
||||||
stbte.prep_selection_at_cursor(state.Stb)
|
stbte.prep_selection_at_cursor(state.Stb)
|
||||||
end
|
end
|
||||||
state.Stb.cursor = STB_TEXTEDIT_MOVEWORDRIGHT_MAC(state, state.Stb.cursor)
|
state.Stb.cursor = ImStb.TEXTEDIT_MOVEWORDRIGHT_MAC(state, state.Stb.cursor)
|
||||||
state.Stb.select_end = state.Stb.cursor
|
state.Stb.select_end = state.Stb.cursor
|
||||||
stbte.clamp(state, state.Stb)
|
stbte.clamp(state, state.Stb)
|
||||||
else
|
else
|
||||||
@@ -5902,9 +5973,9 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
|
|||||||
callback_data.BufTextLen = state.TextLen
|
callback_data.BufTextLen = state.TextLen
|
||||||
callback_data.BufSize = state.BufCapacity
|
callback_data.BufSize = state.BufCapacity
|
||||||
callback_data.BufDirty = false
|
callback_data.BufDirty = false
|
||||||
callback_data.CursorPos = state.Stb.cursor
|
callback_data.CursorPos = state.Stb.cursor - 1 -- [Luau] callback positions are 0-based, stb ones 1-based
|
||||||
callback_data.SelectionStart = state.Stb.select_start
|
callback_data.SelectionStart = state.Stb.select_start - 1
|
||||||
callback_data.SelectionEnd = state.Stb.select_end
|
callback_data.SelectionEnd = state.Stb.select_end - 1
|
||||||
|
|
||||||
-- Call user code
|
-- Call user code
|
||||||
callback(callback_data)
|
callback(callback_data)
|
||||||
@@ -5914,12 +5985,12 @@ function ImGui.InputTextEx(label, hint, buf, buf_size, size_arg, flags, callback
|
|||||||
IM_ASSERT(callback_data.Buf == callback_buf) -- Invalid to modify those fields
|
IM_ASSERT(callback_data.Buf == callback_buf) -- Invalid to modify those fields
|
||||||
IM_ASSERT(callback_data.BufSize == state.BufCapacity)
|
IM_ASSERT(callback_data.BufSize == state.BufCapacity)
|
||||||
IM_ASSERT(callback_data.Flags == flags)
|
IM_ASSERT(callback_data.Flags == flags)
|
||||||
if callback_data.BufDirty or callback_data.CursorPos ~= state.Stb.cursor then
|
if callback_data.BufDirty or callback_data.CursorPos ~= state.Stb.cursor - 1 then
|
||||||
state.CursorFollow = true
|
state.CursorFollow = true
|
||||||
end
|
end
|
||||||
state.Stb.cursor = ImClamp(callback_data.CursorPos, 0, callback_data.BufTextLen)
|
state.Stb.cursor = ImClamp(callback_data.CursorPos, 0, callback_data.BufTextLen) + 1
|
||||||
state.Stb.select_start = ImClamp(callback_data.SelectionStart, 0, callback_data.BufTextLen)
|
state.Stb.select_start = ImClamp(callback_data.SelectionStart, 0, callback_data.BufTextLen) + 1
|
||||||
state.Stb.select_end = ImClamp(callback_data.SelectionEnd, 0, callback_data.BufTextLen)
|
state.Stb.select_end = ImClamp(callback_data.SelectionEnd, 0, callback_data.BufTextLen) + 1
|
||||||
if callback_data.BufDirty then
|
if callback_data.BufDirty then
|
||||||
-- Callback may update buffer and thus set buf_dirty even in read-only mode.
|
-- Callback may update buffer and thus set buf_dirty even in read-only mode.
|
||||||
IM_ASSERT(callback_data.BufTextLen == ImStd.ImStrlen(callback_data.Buf)) -- You need to maintain BufTextLen if you change the text!
|
IM_ASSERT(callback_data.BufTextLen == ImStd.ImStrlen(callback_data.Buf)) -- You need to maintain BufTextLen if you change the text!
|
||||||
@@ -6283,6 +6354,47 @@ function ImGui.InputTextWithHint(label, hint, buf, buf_size, flags, callback, us
|
|||||||
return ImGui.InputTextEx(label, hint, buf, buf_size, ImVec2(0, 0), flags, callback, user_data)
|
return ImGui.InputTextEx(label, hint, buf, buf_size, ImVec2(0, 0), flags, callback, user_data)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- [Luau] stb positions/undo indices are 1-based in this port (displayed as-is)
|
||||||
|
--- @param state ImGuiInputTextState
|
||||||
|
function ImGui.DebugNodeInputTextState(state)
|
||||||
|
local g = GImGui
|
||||||
|
local stb_state = state.Stb
|
||||||
|
local undo_state = stb_state.undostate
|
||||||
|
ImGui.Text("ID: 0x%08X, ActiveID: 0x%08X", state.ID, g.ActiveId)
|
||||||
|
if ImGui.DebugLocateItemOnHover then ImGui.DebugLocateItemOnHover(state.ID) end -- [Luau] not ported yet
|
||||||
|
local wrap_dir = ""
|
||||||
|
if bit32.band(state.Flags, ImGuiInputTextFlags.WordWrap) ~= 0 then
|
||||||
|
if state.LastMoveDirectionLR == ImGuiDir.Left then wrap_dir = " (L)" else wrap_dir = " (R)" end
|
||||||
|
end
|
||||||
|
ImGui.Text("TextLen: %d, Cursor: %d%s, Selection: %d..%d", state.TextLen, stb_state.cursor, wrap_dir, stb_state.select_start, stb_state.select_end)
|
||||||
|
ImGui.Text("BufCapacity: %d, LineCount: %d", state.BufCapacity, state.LineCount)
|
||||||
|
ImGui.Text("(Internal Buffer: TextA Size: %d, Capacity: %d)", state.TextA.Size, state.TextA.Capacity)
|
||||||
|
ImGui.Text("has_preferred_x: %d (%.2f)", stb_state.has_preferred_x and 1 or 0, stb_state.preferred_x)
|
||||||
|
ImGui.Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state.undo_point, undo_state.redo_point, undo_state.undo_char_point, undo_state.redo_char_point)
|
||||||
|
if ImGui.BeginChild("undopoints", ImVec2(0.0, ImGui.GetTextLineHeight() * 10), bit32.bor(ImGuiChildFlags.Borders, ImGuiChildFlags.ResizeY)) then -- Visualize undo state
|
||||||
|
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, ImVec2(0, 0))
|
||||||
|
for n = 1, IMSTB_TEXTEDIT_UNDOSTATECOUNT do
|
||||||
|
local undo_rec = undo_state.undo_rec[n]
|
||||||
|
local undo_rec_type = (n < undo_state.undo_point) and "u" or ((n >= undo_state.redo_point) and "r" or " ")
|
||||||
|
if undo_rec_type == " " then
|
||||||
|
ImGui.BeginDisabled()
|
||||||
|
end
|
||||||
|
local buf_preview_len = (undo_rec_type ~= " " and undo_rec.char_storage ~= -1) and undo_rec.insert_length or 0
|
||||||
|
local buf_preview_str = ""
|
||||||
|
if buf_preview_len > 0 then
|
||||||
|
buf_preview_str = string.char(unpack(undo_state.undo_char, undo_rec.char_storage, undo_rec.char_storage + buf_preview_len - 1))
|
||||||
|
end
|
||||||
|
ImGui.Text("%s [%02d] where %03d, insert %03d, delete %03d, char_storage %03d \"%s\"",
|
||||||
|
undo_rec_type, n, undo_rec.where, undo_rec.insert_length, undo_rec.delete_length, undo_rec.char_storage, buf_preview_str)
|
||||||
|
if undo_rec_type == " " then
|
||||||
|
ImGui.EndDisabled()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ImGui.PopStyleVar()
|
||||||
|
end
|
||||||
|
ImGui.EndChild()
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc.
|
-- [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -10648,14 +10760,37 @@ local function TabItemGetSectionIdx(tab)
|
|||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- [Luau] comparers return a boolean "less than" for table.sort (upstream: ImQsort int comparers)
|
||||||
|
local function TabItemComparerBySection(a, b)
|
||||||
|
if a == nil or b == nil then return false end
|
||||||
|
local a_section = TabItemGetSectionIdx(a)
|
||||||
|
local b_section = TabItemGetSectionIdx(b)
|
||||||
|
if a_section ~= b_section then
|
||||||
|
return a_section < b_section
|
||||||
|
end
|
||||||
|
return a.IndexDuringLayout < b.IndexDuringLayout
|
||||||
|
end
|
||||||
|
|
||||||
|
local function TabItemComparerByBeginOrder(a, b)
|
||||||
|
return a.BeginOrder < b.BeginOrder
|
||||||
|
end
|
||||||
|
|
||||||
|
local function GetTabBarFromTabBarRef(ref)
|
||||||
|
local g = GImGui
|
||||||
|
if ref.Ptr then return ref.Ptr else return g.TabBars:GetByIndex(ref.Index) end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function GetTabBarRefFromTabBar(tab_bar)
|
||||||
|
local g = GImGui
|
||||||
|
if g.TabBars:Contains(tab_bar) then
|
||||||
|
return ImGuiPtrOrIndex(g.TabBars:GetIndex(tab_bar))
|
||||||
|
end
|
||||||
|
return ImGuiPtrOrIndex(tab_bar)
|
||||||
|
end
|
||||||
|
|
||||||
-- Stable sorts (C++ ImQsort is not stable, but the comparers are total orders in practice)
|
-- Stable sorts (C++ ImQsort is not stable, but the comparers are total orders in practice)
|
||||||
local function SortTabsBySection(tab_bar)
|
local function SortTabsBySection(tab_bar)
|
||||||
table.sort(tab_bar.Tabs.Data, function(a, b)
|
table.sort(tab_bar.Tabs.Data, TabItemComparerBySection)
|
||||||
if a == nil or b == nil then return false end
|
|
||||||
local sa, sb = TabItemGetSectionIdx(a), TabItemGetSectionIdx(b)
|
|
||||||
if sa ~= sb then return sa < sb end
|
|
||||||
return a.IndexDuringLayout < b.IndexDuringLayout
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function SortTabsByBeginOrder(tab_bar)
|
local function SortTabsByBeginOrder(tab_bar)
|
||||||
@@ -10663,7 +10798,7 @@ local function SortTabsByBeginOrder(tab_bar)
|
|||||||
if not data then return end
|
if not data then return end
|
||||||
local arr = {}
|
local arr = {}
|
||||||
for i = 1, tab_bar.Tabs.Size do arr[i] = data[i] end
|
for i = 1, tab_bar.Tabs.Size do arr[i] = data[i] end
|
||||||
table.sort(arr, function(a, b) return a.BeginOrder < b.BeginOrder end)
|
table.sort(arr, TabItemComparerByBeginOrder)
|
||||||
for i = 1, tab_bar.Tabs.Size do data[i] = arr[i] end
|
for i = 1, tab_bar.Tabs.Size do data[i] = arr[i] end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -10677,6 +10812,12 @@ end
|
|||||||
-- Spacing: Horizontal spacing at the end of the section.
|
-- Spacing: Horizontal spacing at the end of the section.
|
||||||
local function ImGuiTabBarSection() return { TabCount = 0, Width = 0.0, WidthAfterShrinkMinWidth = 0.0, Spacing = 0.0 } end
|
local function ImGuiTabBarSection() return { TabCount = 0, Width = 0.0, WidthAfterShrinkMinWidth = 0.0, Spacing = 0.0 } end
|
||||||
|
|
||||||
|
-- [Luau] boolean "less than" for table.sort. Width compared exactly: upstream's (int) truncation isn't a strict weak order, which table.sort rejects
|
||||||
|
local function ShrinkWidthItemComparer(a, b)
|
||||||
|
if a.Width ~= b.Width then return a.Width > b.Width end
|
||||||
|
return a.Index > b.Index -- b->Index - a->Index
|
||||||
|
end
|
||||||
|
|
||||||
-- Shrink excess width from a set of item, by removing width from the larger items first.
|
-- Shrink excess width from a set of item, by removing width from the larger items first.
|
||||||
-- Set items Width to -1.0f to disable shrinking this item.
|
-- Set items Width to -1.0f to disable shrinking this item.
|
||||||
-- items: 1-based array of ImGuiShrinkWidthItem, `first` = 1-based index of first item, `count` items
|
-- items: 1-based array of ImGuiShrinkWidthItem, `first` = 1-based index of first item, `count` items
|
||||||
@@ -10690,10 +10831,7 @@ function ImGui.ShrinkWidths(items, first, count, width_excess, width_min)
|
|||||||
-- Sort largest first, smallest last.
|
-- Sort largest first, smallest last.
|
||||||
local slice = {}
|
local slice = {}
|
||||||
for n = 1, count do slice[n] = items[first + n - 1] end
|
for n = 1, count do slice[n] = items[first + n - 1] end
|
||||||
table.sort(slice, function(a, b)
|
table.sort(slice, ShrinkWidthItemComparer)
|
||||||
if a.Width ~= b.Width then return a.Width > b.Width end
|
|
||||||
return a.Index > b.Index -- ShrinkWidthItemComparer: b->Index - a->Index (Width compared exactly: upstream's (int) truncation isn't a strict weak order, which table.sort rejects)
|
|
||||||
end)
|
|
||||||
for n = 1, count do items[first + n - 1] = slice[n] end
|
for n = 1, count do items[first + n - 1] = slice[n] end
|
||||||
local it = slice
|
local it = slice
|
||||||
local count_same_width = 1
|
local count_same_width = 1
|
||||||
@@ -10804,7 +10942,7 @@ function ImGui.BeginTabBarEx(tab_bar, tab_bar_bb, flags)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Add to stack
|
-- Add to stack
|
||||||
g.CurrentTabBarStack:push_back(tab_bar)
|
g.CurrentTabBarStack:push_back(GetTabBarRefFromTabBar(tab_bar))
|
||||||
g.CurrentTabBar = tab_bar
|
g.CurrentTabBar = tab_bar
|
||||||
tab_bar.Window = window
|
tab_bar.Window = window
|
||||||
|
|
||||||
@@ -10886,7 +11024,7 @@ function ImGui.EndTabBar()
|
|||||||
end
|
end
|
||||||
|
|
||||||
g.CurrentTabBarStack:pop_back()
|
g.CurrentTabBarStack:pop_back()
|
||||||
if g.CurrentTabBarStack.Size == 0 then g.CurrentTabBar = nil else g.CurrentTabBar = g.CurrentTabBarStack.Data[g.CurrentTabBarStack.Size] end
|
if g.CurrentTabBarStack.Size == 0 then g.CurrentTabBar = nil else g.CurrentTabBar = GetTabBarFromTabBarRef(g.CurrentTabBarStack:back()) end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This is called only once a frame before by the first call to ItemTab()
|
-- This is called only once a frame before by the first call to ItemTab()
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ CHECKS=(
|
|||||||
"readme-min|README OK|MINIFY=1 $R --main tools/test/scripts/t_readme.luau --frames 30"
|
"readme-min|README OK|MINIFY=1 $R --main tools/test/scripts/t_readme.luau --frames 30"
|
||||||
"cached|CACHED OK|$R --main tools/test/scripts/t_cached_window.luau --frames 130"
|
"cached|CACHED OK|$R --main tools/test/scripts/t_cached_window.luau --frames 130"
|
||||||
"fixes|FIXES OK|$R --main tools/test/scripts/t_fixes.luau --frames 55"
|
"fixes|FIXES OK|$R --main tools/test/scripts/t_fixes.luau --frames 55"
|
||||||
|
"debugtools|DEBUGTOOLS OK|$R --main tools/test/scripts/t_debugtools.luau --frames 65"
|
||||||
|
"helpers|HELPERS OK|$R --main tools/test/scripts/t_helpers.luau --frames 35"
|
||||||
"multiselect|MULTISELECT OK|$R --main tools/test/scripts/t_multiselect.luau --frames 380"
|
"multiselect|MULTISELECT OK|$R --main tools/test/scripts/t_multiselect.luau --frames 380"
|
||||||
"nodemo|NODEMO OK|NO_DEMO=1 $R --main tools/test/scripts/t_nodemo.luau --frames 25"
|
"nodemo|NODEMO OK|NO_DEMO=1 $R --main tools/test/scripts/t_nodemo.luau --frames 25"
|
||||||
"widgets|OK|$R --main tools/test/scripts/t_widgets.luau --frames 80"
|
"widgets|OK|$R --main tools/test/scripts/t_widgets.luau --frames 80"
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
-- Debug tools + misc imgui.cpp ports: item picker, DebugFlashStyleColor, DebugLocateItem, context hooks, AddInputCharactersUTF8, ImBezierCubicClosestPoint
|
||||||
|
local G = require(game:GetService("ReplicatedStorage"):WaitForChild("ImGui"))
|
||||||
|
local ImGui, ImVec2 = G.ImGui, G.ImVec2
|
||||||
|
local ctx = ImGui.CreateContext(); G.ImGui_ImplRoblox.Init()
|
||||||
|
local io = ImGui.GetIO()
|
||||||
|
local failed = {}
|
||||||
|
local function check(ok, msg) if not ok then table.insert(failed, msg); print("FAIL " .. msg) end end
|
||||||
|
|
||||||
|
-- ImBezierCubicClosestPoint: straight-line cubic (0,0)-(30,0)-(60,0)-(90,0): closest point to (45,10) is (45,0)
|
||||||
|
local p1, p2, p3, p4 = ImVec2(0, 0), ImVec2(30, 0), ImVec2(60, 0), ImVec2(90, 0)
|
||||||
|
local cp = G.ImBezierCubicClosestPoint(p1, p2, p3, p4, ImVec2(45, 10), 20)
|
||||||
|
check(math.abs(cp.x - 45) < 1e-3 and math.abs(cp.y) < 1e-6, ("ImBezierCubicClosestPoint %g,%g"):format(cp.x, cp.y))
|
||||||
|
-- Curved: result must lie on the curve (distance to a dense sampling of the curve ~0) and beat the endpoints
|
||||||
|
local q1, q2, q3, q4 = ImVec2(0, 0), ImVec2(0, 100), ImVec2(100, 100), ImVec2(100, 0)
|
||||||
|
local target = ImVec2(50, 120)
|
||||||
|
for _, r in { G.ImBezierCubicClosestPoint(q1, q2, q3, q4, target, 64), G.ImBezierCubicClosestPointCasteljau(q1, q2, q3, q4, target, 0.25) } do
|
||||||
|
check(math.abs(r.x - 50) < 0.5 and math.abs(r.y - 75) < 0.5, ("closest point on curve %g,%g (expected ~50,75)"):format(r.x, r.y))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- AddInputCharactersUTF8 queues one Text event per codepoint
|
||||||
|
io:AddInputCharactersUTF8("a\u{e9}\u{20ac}\u{1F600}")
|
||||||
|
local chars = {}
|
||||||
|
for _, e in ctx.InputEventsQueue.Data do if e.Type == G.ImGuiInputEventType.Text then table.insert(chars, e.Text.Char) end end
|
||||||
|
-- (this build has IM_UNICODE_CODEPOINT_MAX = 0xFFFF like upstream's default ImWchar16: U+1F600 becomes IM_UNICODE_CODEPOINT_INVALID)
|
||||||
|
check(#chars == 4 and chars[1] == 0x61 and chars[2] == 0xE9 and chars[3] == 0x20AC and chars[4] == ((G.IM_UNICODE_CODEPOINT_MAX >= 0x1F600) and 0x1F600 or 0xFFFD), "AddInputCharactersUTF8 " .. table.concat(chars, ","))
|
||||||
|
|
||||||
|
-- Context hooks
|
||||||
|
local log = {}
|
||||||
|
local function hook(t, name)
|
||||||
|
local h = G.ImGuiContextHook(); h.Type = t; h.Callback = function(c, hk) table.insert(log, name) end
|
||||||
|
return ImGui.AddContextHook(ctx, h)
|
||||||
|
end
|
||||||
|
local T = G.ImGuiContextHookType
|
||||||
|
hook(T.NewFramePre, "nfpre"); hook(T.NewFramePost, "nfpost"); hook(T.RenderPre, "rpre"); local rpost = hook(T.RenderPost, "rpost")
|
||||||
|
|
||||||
|
-- Style color flash
|
||||||
|
local col = ImGui.GetStyle().Colors[G.ImGuiCol.Button]
|
||||||
|
local orig = { col.x, col.y, col.z, col.w }
|
||||||
|
|
||||||
|
local f, rect, picked, broke, button_id = 0, nil, nil, 0, 0
|
||||||
|
ctx.DebugBreakCallback = function() broke += 1 end
|
||||||
|
game:GetService("RunService").Stepped:Connect(function()
|
||||||
|
f += 1
|
||||||
|
G.ImGui_ImplRoblox.NewFrame()
|
||||||
|
if rect and f == 5 then io:AddMousePosEvent((rect[1].x + rect[2].x) / 2, (rect[1].y + rect[2].y) / 2) end
|
||||||
|
if f == 6 then ImGui.DebugStartItemPicker() end
|
||||||
|
if f == 8 then io:AddMouseButtonEvent(0, true) elseif f == 9 then io:AddMouseButtonEvent(0, false) end
|
||||||
|
ImGui.NewFrame()
|
||||||
|
if f == 1 then check(table.concat(log, " ") == "nfpre nfpost", "hooks after NewFrame: " .. table.concat(log, " ")) end
|
||||||
|
if f == 8 then picked = ctx.DebugItemPickerBreakId end
|
||||||
|
if f == 3 then ImGui.DebugFlashStyleColor(G.ImGuiCol.Button) end
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(10, 10), G.ImGuiCond.Always)
|
||||||
|
ImGui.Begin("DebugTools")
|
||||||
|
ImGui.Button("Target")
|
||||||
|
if f == 2 then local a, b = ImGui.GetItemRectMin(), ImGui.GetItemRectMax(); rect = { ImVec2(a.x, a.y), ImVec2(b.x, b.y) } end
|
||||||
|
local target_id = ctx.LastItemData.ID
|
||||||
|
button_id = target_id
|
||||||
|
if f == 12 then ImGui.DebugLocateItem(target_id) end
|
||||||
|
if f == 13 then check(ctx.DebugLocateId == 0, "DebugLocateItem resolved by ItemAdd()") end
|
||||||
|
ImGui.DebugDrawItemRect(); ImGui.DebugDrawCursorPos(); ImGui.DebugDrawLineExtents()
|
||||||
|
ImGui.DebugTextUnformattedWithLocateItem(("id 0x%08X here"):format(target_id))
|
||||||
|
ImGui.End()
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(400, 10), G.ImGuiCond.Always); ImGui.ShowMetricsWindow()
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(400, 300), G.ImGuiCond.Always); ImGui.ShowDebugLogWindow()
|
||||||
|
if f == 4 then
|
||||||
|
local c = ImGui.GetStyle().Colors[G.ImGuiCol.Button]
|
||||||
|
check(c.w == 1.0 and ctx.DebugFlashStyleColorIdx == G.ImGuiCol.Button, "flash active")
|
||||||
|
end
|
||||||
|
ImGui.Render(); G.ImGui_ImplRoblox.RenderDrawData(ImGui.GetDrawData())
|
||||||
|
if f == 1 then check(table.concat(log, " ") == "nfpre nfpost rpre rpost", "hooks after Render: " .. table.concat(log, " ")); ImGui.RemoveContextHook(ctx, rpost) end
|
||||||
|
if f == 2 then check(table.concat(log, " ") == "nfpre nfpost rpre rpost nfpre nfpost rpre", "RemoveContextHook: " .. table.concat(log, " ")) end
|
||||||
|
if f == 60 then
|
||||||
|
local c = ImGui.GetStyle().Colors[G.ImGuiCol.Button]
|
||||||
|
check(c.x == orig[1] and c.y == orig[2] and c.z == orig[3] and c.w == orig[4] and ctx.DebugFlashStyleColorIdx == nil, "flash restored color exactly")
|
||||||
|
check(picked ~= nil and picked ~= 0 and picked == button_id, ("item picker set DebugItemPickerBreakId (%s vs %s)"):format(tostring(picked), tostring(button_id)))
|
||||||
|
check(not ctx.DebugItemPickerActive and broke >= 1, ("item picker break hook called (%d)"):format(broke))
|
||||||
|
if #failed == 0 then print("DEBUGTOOLS OK") end
|
||||||
|
end
|
||||||
|
end)
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
-- Small upstream helpers: ImGuiInputTextState selection API + ReloadUserBuf*, ImGuiInputTextCallbackData:SetSelection, ImDrawList AddImageQuad/PrimQuadUV/
|
||||||
|
-- CloneOutput, ImDrawData DeIndexAllBuffers/ScaleClipRects, ImBitVector/ImBitArray*, ImGuiPackedDate, ImParseFormatSanitizeForPrinting, drag cancel (ShortcutsForCancel)
|
||||||
|
local G = require(game:GetService("ReplicatedStorage"):WaitForChild("ImGui"))
|
||||||
|
local ImGui, ImVec2 = G.ImGui, G.ImVec2
|
||||||
|
ImGui.CreateContext(); G.ImGui_ImplRoblox.Init()
|
||||||
|
local io = ImGui.GetIO()
|
||||||
|
local failed = {}
|
||||||
|
local function check(ok, msg) if not ok then table.insert(failed, msg); print("FAIL " .. msg) end end
|
||||||
|
|
||||||
|
-- Pure helpers
|
||||||
|
check(G.ImParseFormatSanitizeForPrinting("%.3f%%", nil, 32) == "%.3f", "sanitize %.3f%%")
|
||||||
|
check(G.ImParseFormatSanitizeForPrinting("%'_5.2f units", nil, 32) == "%5.2f", "sanitize stb flags: " .. G.ImParseFormatSanitizeForPrinting("%'_5.2f units", nil, 32))
|
||||||
|
local d = G.ImGuiPackedDate(20260315)
|
||||||
|
check(d:IsValid() and d:Unpack() == 20260315, "PackedDate round trip " .. d:Unpack())
|
||||||
|
d:SubtractMonths(3)
|
||||||
|
check(d:Unpack() == 20251215, "PackedDate SubtractMonths " .. d:Unpack())
|
||||||
|
check(not G.ImGuiPackedDate():IsValid() and G.ImGuiPackedDate():Unpack() == 0, "PackedDate empty")
|
||||||
|
local bv = G.ImBitVector()
|
||||||
|
bv:Create(70)
|
||||||
|
check(bv.Storage.Size == 3, "ImBitVector size")
|
||||||
|
bv:SetBit(1); bv:SetBit(70); bv:SetBit(33)
|
||||||
|
check(bv:TestBit(1) and bv:TestBit(70) and bv:TestBit(33) and not bv:TestBit(2) and not bv:TestBit(69), "ImBitVector SetBit/TestBit")
|
||||||
|
bv:ClearBit(33)
|
||||||
|
check(not bv:TestBit(33) and bv:TestBit(70), "ImBitVector ClearBit")
|
||||||
|
local arr = {}
|
||||||
|
G.ImBitArrayClearAllBits(arr, 96)
|
||||||
|
G.ImBitArraySetBitRange(arr, 3, 70) -- [3..70)
|
||||||
|
local ok_range = true
|
||||||
|
for n = 1, 96 do if G.ImBitArrayTestBit(arr, n) ~= (n >= 3 and n < 70) then ok_range = false end end
|
||||||
|
check(ok_range, "ImBitArraySetBitRange")
|
||||||
|
check(G.ImBitArrayGetStorageSizeInBytes(70) == 12, "ImBitArrayGetStorageSizeInBytes")
|
||||||
|
check(G.ImModPositive(-1, 5) == 4 and G.ImRoundSigned64(-1.5) == -2 and G.ImCharIsXdigitA(string.byte("F")), "math helpers")
|
||||||
|
|
||||||
|
local buf = ImGui.NewTextBuffer("hello world", 64)
|
||||||
|
local cbuf = ImGui.NewTextBuffer("abcdef", 64)
|
||||||
|
local cb_calls = 0
|
||||||
|
local function cb(data)
|
||||||
|
cb_calls += 1
|
||||||
|
if cb_calls == 1 then data:SetSelection(1, 3) end
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
local df, rect_df = 10.0, nil
|
||||||
|
local f = 0
|
||||||
|
local function center(r) return (r[1].x + r[2].x) / 2, (r[1].y + r[2].y) / 2 end
|
||||||
|
|
||||||
|
local function vtx(dl, i) -- 1-based vertex
|
||||||
|
local b, o = dl.VtxBuffer.Buf, (i - 1) * G.VTX_STRIDE
|
||||||
|
return buffer.readf64(b, o), buffer.readf64(b, o + 8), buffer.readf64(b, o + 16), buffer.readf64(b, o + 24), buffer.readu32(b, o + 32)
|
||||||
|
end
|
||||||
|
|
||||||
|
game:GetService("RunService").Stepped:Connect(function()
|
||||||
|
f += 1
|
||||||
|
G.ImGui_ImplRoblox.NewFrame()
|
||||||
|
-- drag + Escape cancels and reverts (ShortcutsForCancel)
|
||||||
|
if f == 20 then io:AddMousePosEvent(center(rect_df)) end
|
||||||
|
if f == 21 then io:AddMouseButtonEvent(0, true) end
|
||||||
|
if f == 22 then local x, y = center(rect_df); io:AddMousePosEvent(x + 40, y) end
|
||||||
|
if f == 24 then io:AddKeyEvent(G.ImGuiKey.Escape, true) end
|
||||||
|
if f == 25 then io:AddKeyEvent(G.ImGuiKey.Escape, false) end
|
||||||
|
if f == 26 then io:AddMouseButtonEvent(0, false) end
|
||||||
|
ImGui.NewFrame()
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(10, 10)); ImGui.SetNextWindowSize(ImVec2(400, 300))
|
||||||
|
ImGui.Begin("H")
|
||||||
|
if f == 2 then ImGui.SetKeyboardFocusHere() end
|
||||||
|
ImGui.InputText("##t", buf, 64)
|
||||||
|
local id = ImGui.GetItemID()
|
||||||
|
local st = ImGui.GetInputTextState(id)
|
||||||
|
if f == 5 then
|
||||||
|
check(st ~= nil, "InputText active")
|
||||||
|
if st then
|
||||||
|
st:SetSelection(3, 6)
|
||||||
|
check(st:GetSelectionStart() == 3 and st:GetSelectionEnd() == 6 and st:GetCursorPos() == 6 and st:HasSelection(), "SetSelection/Get*")
|
||||||
|
st:ClearSelection()
|
||||||
|
check(st:GetSelectionStart() == 6 and st:GetSelectionEnd() == 6 and not st:HasSelection(), "ClearSelection")
|
||||||
|
check(st:GetPreferredOffsetX() == -1, "GetPreferredOffsetX")
|
||||||
|
-- modify the user buffer externally then reload
|
||||||
|
local s = "bye"; for i = 1, #s do buf[i] = string.byte(s, i) end; buf[#s + 1] = 0
|
||||||
|
st:ReloadUserBufAndSelectAll()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if f == 7 and st then
|
||||||
|
check(G.ImGui._ByteArrayToString(st:GetText(), 1, st.TextLen + 1) == "bye", "ReloadUserBufAndSelectAll text")
|
||||||
|
check(st:GetSelectionStart() == 1 and st:GetSelectionEnd() == 4, ("ReloadUserBufAndSelectAll sel %d..%d"):format(st:GetSelectionStart(), st:GetSelectionEnd()))
|
||||||
|
st:SetSelection(2, 3); st:ReloadUserBufAndKeepSelection()
|
||||||
|
end
|
||||||
|
if f == 9 and st then
|
||||||
|
check(st:GetSelectionStart() == 2 and st:GetSelectionEnd() == 3, "ReloadUserBufAndKeepSelection")
|
||||||
|
st:ReloadUserBufAndMoveToEnd()
|
||||||
|
end
|
||||||
|
if f == 11 and st then
|
||||||
|
check(st:GetCursorPos() == 4 and not st:HasSelection(), "ReloadUserBufAndMoveToEnd " .. st:GetCursorPos())
|
||||||
|
end
|
||||||
|
-- callback SetSelection (0-based callback positions -> 1-based stb)
|
||||||
|
if f == 12 then ImGui.SetKeyboardFocusHere() end
|
||||||
|
ImGui.InputText("##c", cbuf, 64, G.ImGuiInputTextFlags.CallbackAlways, cb)
|
||||||
|
if f == 15 then
|
||||||
|
local cst = ImGui.GetInputTextState(ImGui.GetItemID())
|
||||||
|
check(cst ~= nil and cb_calls > 0 and cst:GetSelectionStart() == 2 and cst:GetSelectionEnd() == 4, "callback SetSelection " .. (cst and (cst:GetSelectionStart() .. ".." .. cst:GetSelectionEnd()) or "nil"))
|
||||||
|
end
|
||||||
|
df = ImGui.DragFloat("##df", df, 1.0)
|
||||||
|
local a, b = ImGui.GetItemRectMin(), ImGui.GetItemRectMax(); rect_df = { ImVec2(a.x, a.y), ImVec2(b.x, b.y) }
|
||||||
|
if f == 23 then check(df ~= 10.0, "drag changed value " .. df) end
|
||||||
|
if f == 25 then check(df == 10.0 and ImGui.GetActiveID() == 0, "Escape reverts drag " .. df) end
|
||||||
|
|
||||||
|
if f == 30 then
|
||||||
|
local dl = ImGui.GetWindowDrawList()
|
||||||
|
local v0, i0 = dl.VtxBuffer.Size, dl.IdxBuffer.Size
|
||||||
|
local tex = G.ImTextureRef(1234)
|
||||||
|
dl:AddImageQuad(tex, ImVec2(10, 10), ImVec2(50, 12), ImVec2(48, 60), ImVec2(8, 58), ImVec2(0, 0), ImVec2(1, 0), ImVec2(1, 1), ImVec2(0, 1), 0xFF00FF00)
|
||||||
|
check(dl.VtxBuffer.Size == v0 + 4 and dl.IdxBuffer.Size == i0 + 6, "AddImageQuad counts")
|
||||||
|
local x, y, u, v, col = vtx(dl, v0 + 3)
|
||||||
|
check(x == 48 and y == 60 and u == 1 and v == 1 and col == 0xFF00FF00, ("PrimQuadUV vertex %s %s %s %s %x"):format(x, y, u, v, col))
|
||||||
|
local idx = dl.IdxBuffer.Data
|
||||||
|
check(idx[i0 + 1] == v0 + 1 and idx[i0 + 5] == v0 + 3 and idx[i0 + 6] == v0 + 4, "PrimQuadUV indices")
|
||||||
|
local cmin, cmax = dl:GetClipRectMin(), dl:GetClipRectMax()
|
||||||
|
check(cmax.x > cmin.x and cmax.y > cmin.y, "GetClipRectMin/Max")
|
||||||
|
|
||||||
|
local clone = dl:CloneOutput()
|
||||||
|
check(clone.VtxBuffer.Size == dl.VtxBuffer.Size and clone.IdxBuffer.Size == dl.IdxBuffer.Size and clone.CmdBuffer.Size == dl.CmdBuffer.Size
|
||||||
|
and clone.VtxBuffer.Buf ~= dl.VtxBuffer.Buf and clone.CmdBuffer.Data[1] ~= dl.CmdBuffer.Data[1], "CloneOutput copies buffers")
|
||||||
|
local cx = vtx(clone, v0 + 3)
|
||||||
|
check(cx == 48, "CloneOutput vertex data")
|
||||||
|
|
||||||
|
local dd = G.ImDrawData()
|
||||||
|
dd.CmdLists:push_back(clone)
|
||||||
|
local n_idx = clone.IdxBuffer.Size
|
||||||
|
local ex, ey = vtx(clone, clone.IdxBuffer.Data[n_idx])
|
||||||
|
dd:DeIndexAllBuffers()
|
||||||
|
check(clone.IdxBuffer.Size == 0 and clone.VtxBuffer.Size == n_idx and dd.TotalVtxCount == n_idx and dd.TotalIdxCount == 0, "DeIndexAllBuffers counts")
|
||||||
|
local lx, ly = vtx(clone, n_idx)
|
||||||
|
check(lx == ex and ly == ey, "DeIndexAllBuffers vertex data")
|
||||||
|
|
||||||
|
local cr = clone.CmdBuffer.Data[1].ClipRect
|
||||||
|
local x1, y1, z1, w1 = cr.x, cr.y, cr.z, cr.w
|
||||||
|
dd:ScaleClipRects(ImVec2(2, 3))
|
||||||
|
local cr2 = clone.CmdBuffer.Data[1].ClipRect
|
||||||
|
check(cr2.x == x1 * 2 and cr2.y == y1 * 3 and cr2.z == z1 * 2 and cr2.w == w1 * 3 and dl.CmdBuffer.Data[1].ClipRect.z == z1, "ScaleClipRects")
|
||||||
|
end
|
||||||
|
ImGui.End()
|
||||||
|
ImGui.Render(); G.ImGui_ImplRoblox.RenderDrawData(ImGui.GetDrawData())
|
||||||
|
if f == 32 and #failed == 0 then print("HELPERS OK") end
|
||||||
|
end)
|
||||||
Reference in New Issue
Block a user