Port multi-select, box-select and typing-select (BeginMultiSelect/EndMultiSelect, SetNextItemSelectionUserData, MultiSelectItemHeader/Footer, BeginBoxSelect/EndBoxSelect, GetTypingSelectRequest/TypingSelectFind*, ImGuiSelectionBasicStorage/ExternalStorage, Metrics nodes); wired into Selectable/Checkbox/TreeNode/clipper/tables; t_multiselect
This commit is contained in:
@@ -1 +1 @@
|
|||||||
[[46, "imgui.lua"], [21413, "imgui_demo.lua"], [31841, "imgui_draw.lua"], [37784, "imgui_h.lua"], [40511, "imgui_impl_roblox.lua"], [42159, "imgui_impl_roblox_fonts.lua"], [48562, "imgui_internal.lua"], [52034, "imgui_tables.lua"], [57093, "imgui_widgets.lua"], [67757, "imstb_rectpack.lua"], [68421, "imstb_textedit.lua"], [69963, "imstb_truetype.lua"], [72751, "imstd_minstdio.lua"]]
|
[[46, "imgui.lua"], [21437, "imgui_demo.lua"], [31865, "imgui_draw.lua"], [37808, "imgui_h.lua"], [40651, "imgui_impl_roblox.lua"], [42299, "imgui_impl_roblox_fonts.lua"], [48702, "imgui_internal.lua"], [52369, "imgui_tables.lua"], [57428, "imgui_widgets.lua"], [69417, "imstb_rectpack.lua"], [70081, "imstb_textedit.lua"], [71623, "imstb_truetype.lua"], [74411, "imstd_minstdio.lua"]]
|
||||||
+1683
-8
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@ export type ImGuiAPI = {
|
|||||||
ArrowButton: (str_id: string, dir: number) -> boolean,
|
ArrowButton: (str_id: string, dir: number) -> boolean,
|
||||||
ArrowButtonEx: (...any) -> ...any,
|
ArrowButtonEx: (...any) -> ...any,
|
||||||
Begin: (name: string, open: boolean?, flags: number?) -> (boolean, boolean?),
|
Begin: (name: string, open: boolean?, flags: number?) -> (boolean, boolean?),
|
||||||
|
BeginBoxSelect: (...any) -> ...any,
|
||||||
BeginChild: (...any) -> ...any,
|
BeginChild: (...any) -> ...any,
|
||||||
BeginChildEx: (...any) -> ...any,
|
BeginChildEx: (...any) -> ...any,
|
||||||
BeginColumns: (...any) -> ...any,
|
BeginColumns: (...any) -> ...any,
|
||||||
@@ -36,6 +37,7 @@ export type ImGuiAPI = {
|
|||||||
BeginMenu: (label: string, enabled: boolean?) -> boolean,
|
BeginMenu: (label: string, enabled: boolean?) -> boolean,
|
||||||
BeginMenuBar: () -> boolean,
|
BeginMenuBar: () -> boolean,
|
||||||
BeginMenuEx: (...any) -> ...any,
|
BeginMenuEx: (...any) -> ...any,
|
||||||
|
BeginMultiSelect: (flags: number, selection_size: number?, items_count: number?) -> any,
|
||||||
BeginPopup: (str_id: string, flags: number?) -> boolean,
|
BeginPopup: (str_id: string, flags: number?) -> boolean,
|
||||||
BeginPopupContextItem: (str_id: string?, popup_flags: number?) -> boolean,
|
BeginPopupContextItem: (str_id: string?, popup_flags: number?) -> boolean,
|
||||||
BeginPopupContextVoid: (str_id: string?, popup_flags: number?) -> boolean,
|
BeginPopupContextVoid: (str_id: string?, popup_flags: number?) -> boolean,
|
||||||
@@ -117,11 +119,13 @@ export type ImGuiAPI = {
|
|||||||
DebugNodeFont: (...any) -> ...any,
|
DebugNodeFont: (...any) -> ...any,
|
||||||
DebugNodeFontGlyph: (...any) -> ...any,
|
DebugNodeFontGlyph: (...any) -> ...any,
|
||||||
DebugNodeFontGlyphsForSrcMask: (...any) -> ...any,
|
DebugNodeFontGlyphsForSrcMask: (...any) -> ...any,
|
||||||
|
DebugNodeMultiSelectState: (...any) -> ...any,
|
||||||
DebugNodeStorage: (...any) -> ...any,
|
DebugNodeStorage: (...any) -> ...any,
|
||||||
DebugNodeTabBar: (...any) -> ...any,
|
DebugNodeTabBar: (...any) -> ...any,
|
||||||
DebugNodeTable: (...any) -> ...any,
|
DebugNodeTable: (...any) -> ...any,
|
||||||
DebugNodeTableSettings: (...any) -> ...any,
|
DebugNodeTableSettings: (...any) -> ...any,
|
||||||
DebugNodeTexture: (...any) -> ...any,
|
DebugNodeTexture: (...any) -> ...any,
|
||||||
|
DebugNodeTypingSelectState: (...any) -> ...any,
|
||||||
DebugNodeViewport: (...any) -> ...any,
|
DebugNodeViewport: (...any) -> ...any,
|
||||||
DebugNodeWindow: (...any) -> ...any,
|
DebugNodeWindow: (...any) -> ...any,
|
||||||
DebugNodeWindowSettings: (...any) -> ...any,
|
DebugNodeWindowSettings: (...any) -> ...any,
|
||||||
@@ -220,6 +224,7 @@ export type ImGuiAPI = {
|
|||||||
DragScalarN: (label: string, data_type: number, v: any, components: number, v_speed: number?, v_min: any, v_max: any, format: string?, flags: number?) -> ...any,
|
DragScalarN: (label: string, data_type: number, v: any, components: number, v_speed: number?, v_min: any, v_max: any, format: string?, flags: number?) -> ...any,
|
||||||
Dummy: (size: ImVec2) -> (),
|
Dummy: (size: ImVec2) -> (),
|
||||||
End: () -> (),
|
End: () -> (),
|
||||||
|
EndBoxSelect: (...any) -> ...any,
|
||||||
EndChild: () -> (),
|
EndChild: () -> (),
|
||||||
EndColumns: (...any) -> ...any,
|
EndColumns: (...any) -> ...any,
|
||||||
EndCombo: () -> (),
|
EndCombo: () -> (),
|
||||||
@@ -235,6 +240,7 @@ export type ImGuiAPI = {
|
|||||||
EndMainMenuBar: () -> (),
|
EndMainMenuBar: () -> (),
|
||||||
EndMenu: () -> (),
|
EndMenu: () -> (),
|
||||||
EndMenuBar: () -> (),
|
EndMenuBar: () -> (),
|
||||||
|
EndMultiSelect: () -> any,
|
||||||
EndPopup: () -> (),
|
EndPopup: () -> (),
|
||||||
EndTabBar: () -> (),
|
EndTabBar: () -> (),
|
||||||
EndTabItem: () -> (),
|
EndTabItem: () -> (),
|
||||||
@@ -274,6 +280,7 @@ export type ImGuiAPI = {
|
|||||||
GcCompactTransientMiscBuffers: (...any) -> ...any,
|
GcCompactTransientMiscBuffers: (...any) -> ...any,
|
||||||
GcCompactTransientWindowBuffers: (...any) -> ...any,
|
GcCompactTransientWindowBuffers: (...any) -> ...any,
|
||||||
GetBackgroundDrawList: (viewport: any) -> ...any,
|
GetBackgroundDrawList: (viewport: any) -> ...any,
|
||||||
|
GetBoxSelectState: (...any) -> ...any,
|
||||||
GetClipboardText: () -> any,
|
GetClipboardText: () -> any,
|
||||||
GetColorU32: (...any) -> ...any,
|
GetColorU32: (...any) -> ...any,
|
||||||
GetColumnIndex: () -> number,
|
GetColumnIndex: () -> number,
|
||||||
@@ -331,6 +338,7 @@ export type ImGuiAPI = {
|
|||||||
GetMouseDragDelta: (button: number?, lock_threshold: number?) -> ImVec2,
|
GetMouseDragDelta: (button: number?, lock_threshold: number?) -> ImVec2,
|
||||||
GetMousePos: () -> ImVec2,
|
GetMousePos: () -> ImVec2,
|
||||||
GetMousePosOnOpeningCurrentPopup: () -> ImVec2,
|
GetMousePosOnOpeningCurrentPopup: () -> ImVec2,
|
||||||
|
GetMultiSelectState: (...any) -> ...any,
|
||||||
GetNavTweakPressedAmount: (...any) -> ...any,
|
GetNavTweakPressedAmount: (...any) -> ...any,
|
||||||
GetPlatformIO: () -> any,
|
GetPlatformIO: () -> any,
|
||||||
GetPopupAllowedExtentRect: (...any) -> ...any,
|
GetPopupAllowedExtentRect: (...any) -> ...any,
|
||||||
@@ -353,6 +361,7 @@ export type ImGuiAPI = {
|
|||||||
GetTopMostPopupModal: (...any) -> ...any,
|
GetTopMostPopupModal: (...any) -> ...any,
|
||||||
GetTreeNodeToLabelSpacing: () -> number,
|
GetTreeNodeToLabelSpacing: () -> number,
|
||||||
GetTypematicRepeatRate: (...any) -> ...any,
|
GetTypematicRepeatRate: (...any) -> ...any,
|
||||||
|
GetTypingSelectRequest: (...any) -> ...any,
|
||||||
GetVersion: () -> any,
|
GetVersion: () -> any,
|
||||||
GetViewportPlatformMonitor: (...any) -> ...any,
|
GetViewportPlatformMonitor: (...any) -> ...any,
|
||||||
GetWindowAlwaysWantOwnTabBar: (...any) -> ...any,
|
GetWindowAlwaysWantOwnTabBar: (...any) -> ...any,
|
||||||
@@ -479,6 +488,10 @@ export type ImGuiAPI = {
|
|||||||
MenuItem: (...any) -> ...any,
|
MenuItem: (...any) -> ...any,
|
||||||
MenuItemEx: (...any) -> ...any,
|
MenuItemEx: (...any) -> ...any,
|
||||||
MouseButtonToKey: (...any) -> ...any,
|
MouseButtonToKey: (...any) -> ...any,
|
||||||
|
MultiSelectAddSetAll: (...any) -> ...any,
|
||||||
|
MultiSelectAddSetRange: (...any) -> ...any,
|
||||||
|
MultiSelectItemFooter: (...any) -> ...any,
|
||||||
|
MultiSelectItemHeader: (...any) -> ...any,
|
||||||
NavApplyItemToResult: (...any) -> ...any,
|
NavApplyItemToResult: (...any) -> ...any,
|
||||||
NavBiasScoringRect: (...any) -> ...any,
|
NavBiasScoringRect: (...any) -> ...any,
|
||||||
NavCalcPreferredRefPos: (...any) -> ...any,
|
NavCalcPreferredRefPos: (...any) -> ...any,
|
||||||
@@ -639,6 +652,7 @@ export type ImGuiAPI = {
|
|||||||
SetNextItemColorMarker: (...any) -> ...any,
|
SetNextItemColorMarker: (...any) -> ...any,
|
||||||
SetNextItemOpen: (is_open: boolean, cond: number?) -> (),
|
SetNextItemOpen: (is_open: boolean, cond: number?) -> (),
|
||||||
SetNextItemRefVal: (...any) -> ...any,
|
SetNextItemRefVal: (...any) -> ...any,
|
||||||
|
SetNextItemSelectionUserData: (selection_user_data: any) -> (),
|
||||||
SetNextItemShortcut: (key_chord: any, flags: number?) -> (),
|
SetNextItemShortcut: (key_chord: any, flags: number?) -> (),
|
||||||
SetNextItemStorageID: (storage_id: number) -> (),
|
SetNextItemStorageID: (storage_id: number) -> (),
|
||||||
SetNextItemWidth: (item_width: number) -> (),
|
SetNextItemWidth: (item_width: number) -> (),
|
||||||
@@ -848,6 +862,9 @@ export type ImGuiAPI = {
|
|||||||
TreePop: () -> (),
|
TreePop: () -> (),
|
||||||
TreePush: (...any) -> ...any,
|
TreePush: (...any) -> ...any,
|
||||||
TreePushOverrideID: (...any) -> ...any,
|
TreePushOverrideID: (...any) -> ...any,
|
||||||
|
TypingSelectFindBestLeadingMatch: (...any) -> ...any,
|
||||||
|
TypingSelectFindMatch: (...any) -> ...any,
|
||||||
|
TypingSelectFindNextSingleCharMatch: (...any) -> ...any,
|
||||||
Unindent: (indent_w: number?) -> (),
|
Unindent: (indent_w: number?) -> (),
|
||||||
UnregisterFontAtlas: (...any) -> ...any,
|
UnregisterFontAtlas: (...any) -> ...any,
|
||||||
UpdateAliasKey: (...any) -> ...any,
|
UpdateAliasKey: (...any) -> ...any,
|
||||||
@@ -880,6 +897,7 @@ export type ImGuiAPI = {
|
|||||||
VSliderScalar: (label: string, size: ImVec2, data_type: number, data: any, min: any, max: any, format: string?, flags: number?) -> ...any,
|
VSliderScalar: (label: string, size: ImVec2, data_type: number, data: any, min: any, max: any, format: string?, flags: number?) -> ...any,
|
||||||
Value: (...any) -> ...any,
|
Value: (...any) -> ...any,
|
||||||
WindowPosAbsToRel: (...any) -> ...any,
|
WindowPosAbsToRel: (...any) -> ...any,
|
||||||
|
WindowPosRelToAbs: (...any) -> ...any,
|
||||||
WindowRectAbsToRel: (...any) -> ...any,
|
WindowRectAbsToRel: (...any) -> ...any,
|
||||||
WindowRectRelToAbs: (...any) -> ...any,
|
WindowRectRelToAbs: (...any) -> ...any,
|
||||||
WindowSelectViewport: (...any) -> ...any,
|
WindowSelectViewport: (...any) -> ...any,
|
||||||
@@ -913,9 +931,11 @@ export type ImGuiItemFlags = { None: number, NoTabStop: number, NoNav: number, N
|
|||||||
export type ImGuiItemStatusFlags = { None: number, HoveredRect: number, HasDisplayRect: number, Edited: number, ToggledSelection: number, ToggledOpen: number, HasDeactivated: number, Deactivated: number, HoveredWindow: number, Visible: number, HasClipRect: number, HasShortcut: number, EditedInternal: number, [string]: number }
|
export type ImGuiItemStatusFlags = { None: number, HoveredRect: number, HasDisplayRect: number, Edited: number, ToggledSelection: number, ToggledOpen: number, HasDeactivated: number, Deactivated: number, HoveredWindow: number, Visible: number, HasClipRect: number, HasShortcut: number, EditedInternal: number, [string]: number }
|
||||||
export type ImGuiKey = { None: number, NamedKey_BEGIN: number, Tab: number, LeftArrow: number, RightArrow: number, UpArrow: number, DownArrow: number, PageUp: number, PageDown: number, Home: number, End: number, Insert: number, Delete: number, Backspace: number, Space: number, Enter: number, Escape: number, LeftCtrl: number, RightCtrl: number, Menu: number, K0: number, A: number, K: number, U: number, F1: number, F7: number, F13: number, F19: number, Apostrophe: number, CapsLock: number, Keypad0: number, KeypadDecimal: number, AppBack: number, AppForward: number, Oem102: number, GamepadStart: number, GamepadFaceLeft: number, GamepadDpadLeft: number, GamepadL1: number, GamepadL2: number, GamepadL3: number, GamepadLStickLeft: number, GamepadRStickLeft: number, MouseLeft: number, ReservedForModCtrl: number, NamedKey_END: number, NamedKey_COUNT: number, NavKeyboardTweakSlow: number, NavKeyboardTweakFast: number, NavGamepadTweakSlow: number, NavGamepadTweakFast: number, NavGamepadMenu: number, NavGamepadContextMenu: number, [string]: number }
|
export type ImGuiKey = { None: number, NamedKey_BEGIN: number, Tab: number, LeftArrow: number, RightArrow: number, UpArrow: number, DownArrow: number, PageUp: number, PageDown: number, Home: number, End: number, Insert: number, Delete: number, Backspace: number, Space: number, Enter: number, Escape: number, LeftCtrl: number, RightCtrl: number, Menu: number, K0: number, A: number, K: number, U: number, F1: number, F7: number, F13: number, F19: number, Apostrophe: number, CapsLock: number, Keypad0: number, KeypadDecimal: number, AppBack: number, AppForward: number, Oem102: number, GamepadStart: number, GamepadFaceLeft: number, GamepadDpadLeft: number, GamepadL1: number, GamepadL2: number, GamepadL3: number, GamepadLStickLeft: number, GamepadRStickLeft: number, MouseLeft: number, ReservedForModCtrl: number, NamedKey_END: number, NamedKey_COUNT: number, NavKeyboardTweakSlow: number, NavKeyboardTweakFast: number, NavGamepadTweakSlow: number, NavGamepadTweakFast: number, NavGamepadMenu: number, NavGamepadContextMenu: number, [string]: number }
|
||||||
export type ImGuiMouseSource = { Mouse: number, TouchScreen: number, Pen: number, COUNT: number, [string]: number }
|
export type ImGuiMouseSource = { Mouse: number, TouchScreen: number, Pen: number, COUNT: number, [string]: number }
|
||||||
|
export type ImGuiMultiSelectFlags = { None: number, SingleSelect: number, NoSelectAll: number, NoRangeSelect: number, NoAutoSelect: number, NoAutoClear: number, NoAutoClearOnReselect: number, BoxSelect1d: number, BoxSelect2d: number, BoxSelectNoScroll: number, ClearOnEscape: number, ClearOnClickVoid: number, ScopeWindow: number, ScopeRect: number, SelectOnAuto: number, SelectOnClickAlways: number, SelectOnClickRelease: number, NavWrapX: number, NoSelectOnRightClick: number, CheckboxMode_: number, SelectOnMask_: number, SelectOnClick: number, [string]: number }
|
||||||
export type ImGuiNextItemDataFlags = { None: number, HasWidth: number, HasOpen: number, HasShortcut: number, HasRefVal: number, HasStorageID: number, HasColorMarker: number, [string]: number }
|
export type ImGuiNextItemDataFlags = { None: number, HasWidth: number, HasOpen: number, HasShortcut: number, HasRefVal: number, HasStorageID: number, HasColorMarker: number, [string]: number }
|
||||||
export type ImGuiPopupFlags = { None: number, MouseButtonLeft: number, MouseButtonRight: number, MouseButtonMiddle: number, NoReopen: number, NoOpenOverExistingPopup: number, NoOpenOverItems: number, AnyPopupId: number, AnyPopupLevel: number, AnyPopup: number, MouseButtonShift_: number, MouseButtonMask_: number, InvalidMask_: number, [string]: number }
|
export type ImGuiPopupFlags = { None: number, MouseButtonLeft: number, MouseButtonRight: number, MouseButtonMiddle: number, NoReopen: number, NoOpenOverExistingPopup: number, NoOpenOverItems: number, AnyPopupId: number, AnyPopupLevel: number, AnyPopup: number, MouseButtonShift_: number, MouseButtonMask_: number, InvalidMask_: number, [string]: number }
|
||||||
export type ImGuiSelectableFlags = { None: number, NoAutoClosePopups: number, SpanAllColumns: number, AllowDoubleClick: number, Disabled: number, AllowOverlap: number, Highlight: number, SelectOnNav: number, NoHoldingActiveID: number, SelectOnClick: number, SelectOnRelease: number, SpanAvailWidth: number, SetNavIdOnHover: number, NoPadWithHalfSpacing: number, NoSetKeyOwner: number, [string]: number }
|
export type ImGuiSelectableFlags = { None: number, NoAutoClosePopups: number, SpanAllColumns: number, AllowDoubleClick: number, Disabled: number, AllowOverlap: number, Highlight: number, SelectOnNav: number, NoHoldingActiveID: number, SelectOnClick: number, SelectOnRelease: number, SpanAvailWidth: number, SetNavIdOnHover: number, NoPadWithHalfSpacing: number, NoSetKeyOwner: number, [string]: number }
|
||||||
|
export type ImGuiSelectionRequestType = { None: number, SetAll: number, SetRange: number, [string]: number }
|
||||||
export type ImGuiSliderFlags = { None: number, Logarithmic: number, NoRoundToFormat: number, NoInput: number, WrapAround: number, ClampOnInput: number, ClampZeroRange: number, NoSpeedTweaks: number, ColorMarkers: number, InvalidMask_: number, AlwaysClamp: number, Vertical: number, ReadOnly: number, [string]: number }
|
export type ImGuiSliderFlags = { None: number, Logarithmic: number, NoRoundToFormat: number, NoInput: number, WrapAround: number, ClampOnInput: number, ClampZeroRange: number, NoSpeedTweaks: number, ColorMarkers: number, InvalidMask_: number, AlwaysClamp: number, Vertical: number, ReadOnly: number, [string]: number }
|
||||||
export type ImGuiStyleVar = { Alpha: number, DisabledAlpha: number, WindowPadding: number, WindowRounding: number, WindowBorderSize: number, WindowMinSize: number, WindowTitleAlign: number, ChildRounding: number, ChildBorderSize: number, PopupRounding: number, PopupBorderSize: number, FramePadding: number, FrameRounding: number, FrameBorderSize: number, ItemSpacing: number, ItemInnerSpacing: number, IndentSpacing: number, CellPadding: number, ScrollbarSize: number, ScrollbarRounding: number, ScrollbarPadding: number, GrabMinSize: number, GrabRounding: number, ImageRounding: number, ImageBorderSize: number, TabRounding: number, TabBorderSize: number, TabMinWidthBase: number, TabMinWidthShrink: number, TabBarBorderSize: number, TabBarOverlineSize: number, TableAngledHeadersAngle: number, TableAngledHeadersTextAlign: number, TreeLinesSize: number, TreeLinesRounding: number, MenuItemRounding: number, SelectableRounding: number, DragDropTargetRounding: number, ButtonTextAlign: number, SelectableTextAlign: number, SeparatorTextBorderSize: number, SeparatorTextAlign: number, SeparatorTextPadding: number, COUNT: number, [string]: number }
|
export type ImGuiStyleVar = { Alpha: number, DisabledAlpha: number, WindowPadding: number, WindowRounding: number, WindowBorderSize: number, WindowMinSize: number, WindowTitleAlign: number, ChildRounding: number, ChildBorderSize: number, PopupRounding: number, PopupBorderSize: number, FramePadding: number, FrameRounding: number, FrameBorderSize: number, ItemSpacing: number, ItemInnerSpacing: number, IndentSpacing: number, CellPadding: number, ScrollbarSize: number, ScrollbarRounding: number, ScrollbarPadding: number, GrabMinSize: number, GrabRounding: number, ImageRounding: number, ImageBorderSize: number, TabRounding: number, TabBorderSize: number, TabMinWidthBase: number, TabMinWidthShrink: number, TabBarBorderSize: number, TabBarOverlineSize: number, TableAngledHeadersAngle: number, TableAngledHeadersTextAlign: number, TreeLinesSize: number, TreeLinesRounding: number, MenuItemRounding: number, SelectableRounding: number, DragDropTargetRounding: number, ButtonTextAlign: number, SelectableTextAlign: number, SeparatorTextBorderSize: number, SeparatorTextAlign: number, SeparatorTextPadding: number, COUNT: number, [string]: number }
|
||||||
export type ImGuiTreeNodeFlags = { None: number, Selected: number, Framed: number, AllowOverlap: number, NoTreePushOnOpen: number, NoAutoOpenOnLog: number, DefaultOpen: number, OpenOnDoubleClick: number, OpenOnArrow: number, Leaf: number, Bullet: number, FramePadding: number, SpanAvailWidth: number, SpanFullWidth: number, SpanLabelWidth: number, SpanAllColumns: number, LabelSpanAllColumns: number, NavLeftJumpsToParent: number, DrawLinesNone: number, DrawLinesFull: number, DrawLinesToNodes: number, NoNavFocus: number, ClipLabelForTrailingButton: number, UpsideDownArrow: number, CollapsingHeader: number, OpenOnMask_: number, DrawLinesMask_: number, [string]: number }
|
export type ImGuiTreeNodeFlags = { None: number, Selected: number, Framed: number, AllowOverlap: number, NoTreePushOnOpen: number, NoAutoOpenOnLog: number, DefaultOpen: number, OpenOnDoubleClick: number, OpenOnArrow: number, Leaf: number, Bullet: number, FramePadding: number, SpanAvailWidth: number, SpanFullWidth: number, SpanLabelWidth: number, SpanAllColumns: number, LabelSpanAllColumns: number, NavLeftJumpsToParent: number, DrawLinesNone: number, DrawLinesFull: number, DrawLinesToNodes: number, NoNavFocus: number, ClipLabelForTrailingButton: number, UpsideDownArrow: number, CollapsingHeader: number, OpenOnMask_: number, DrawLinesMask_: number, [string]: number }
|
||||||
@@ -945,9 +965,11 @@ export type ImGuiModule = {
|
|||||||
ImGuiItemStatusFlags: ImGuiItemStatusFlags,
|
ImGuiItemStatusFlags: ImGuiItemStatusFlags,
|
||||||
ImGuiKey: ImGuiKey,
|
ImGuiKey: ImGuiKey,
|
||||||
ImGuiMouseSource: ImGuiMouseSource,
|
ImGuiMouseSource: ImGuiMouseSource,
|
||||||
|
ImGuiMultiSelectFlags: ImGuiMultiSelectFlags,
|
||||||
ImGuiNextItemDataFlags: ImGuiNextItemDataFlags,
|
ImGuiNextItemDataFlags: ImGuiNextItemDataFlags,
|
||||||
ImGuiPopupFlags: ImGuiPopupFlags,
|
ImGuiPopupFlags: ImGuiPopupFlags,
|
||||||
ImGuiSelectableFlags: ImGuiSelectableFlags,
|
ImGuiSelectableFlags: ImGuiSelectableFlags,
|
||||||
|
ImGuiSelectionRequestType: ImGuiSelectionRequestType,
|
||||||
ImGuiSliderFlags: ImGuiSliderFlags,
|
ImGuiSliderFlags: ImGuiSliderFlags,
|
||||||
ImGuiStyleVar: ImGuiStyleVar,
|
ImGuiStyleVar: ImGuiStyleVar,
|
||||||
ImGuiTreeNodeFlags: ImGuiTreeNodeFlags,
|
ImGuiTreeNodeFlags: ImGuiTreeNodeFlags,
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
[[183, "imgui.lua"], [21550, "imgui_demo.lua"], [31978, "imgui_draw.lua"], [37921, "imgui_h.lua"], [40648, "imgui_impl_love.lua"], [41188, "imgui_internal.lua"], [44660, "imgui_tables.lua"], [49719, "imgui_widgets.lua"], [60383, "imstb_rectpack.lua"], [61047, "imstb_textedit.lua"], [62589, "imstb_truetype.lua"], [65377, "imstd_minstdio.lua"]]
|
[[183, "imgui.lua"], [21574, "imgui_demo.lua"], [32002, "imgui_draw.lua"], [37945, "imgui_h.lua"], [40788, "imgui_impl_love.lua"], [41328, "imgui_internal.lua"], [44995, "imgui_tables.lua"], [50054, "imgui_widgets.lua"], [62043, "imstb_rectpack.lua"], [62707, "imstb_textedit.lua"], [64249, "imstb_truetype.lua"], [67037, "imstd_minstdio.lua"]]
|
||||||
+1683
-8
File diff suppressed because it is too large
Load Diff
+558
-573
File diff suppressed because it is too large
Load Diff
@@ -10828,6 +10828,8 @@ function ImGui.GcCompactTransientMiscBuffers()
|
|||||||
g.ItemFlagsStack:clear()
|
g.ItemFlagsStack:clear()
|
||||||
g.GroupStack:clear()
|
g.GroupStack:clear()
|
||||||
g.InputTextLineIndex:clear()
|
g.InputTextLineIndex:clear()
|
||||||
|
g.MultiSelectTempDataStacked = 0
|
||||||
|
g.MultiSelectTempData:clear()
|
||||||
ImGui.TableGcCompactSettings()
|
ImGui.TableGcCompactSettings()
|
||||||
for _, atlas in g.FontAtlases:iter() do
|
for _, atlas in g.FontAtlases:iter() do
|
||||||
atlas:CompactCache()
|
atlas:CompactCache()
|
||||||
@@ -14324,6 +14326,8 @@ function ImGui.Shutdown()
|
|||||||
-- TODO:
|
-- TODO:
|
||||||
|
|
||||||
-- Clear everything else
|
-- Clear everything else
|
||||||
|
g.MultiSelectStorage:Clear()
|
||||||
|
g.MultiSelectTempData:clear()
|
||||||
g.MenusIdSubmittedThisFrame:clear()
|
g.MenusIdSubmittedThisFrame:clear()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -19700,7 +19704,7 @@ local function ImGuiListClipper_StepInternal(clipper)
|
|||||||
|
|
||||||
-- Add box selection range
|
-- Add box selection range
|
||||||
local bs = g.BoxSelectState
|
local bs = g.BoxSelectState
|
||||||
if bs and bs.IsActive and bs.Window == window then
|
if bs.IsActive and bs.Window == window then
|
||||||
-- FIXME: Selectable() use of half-ItemSpacing isn't consistent in matter of layout, as ItemAdd(bb) stray above ItemSize()'s CursorPos.
|
-- FIXME: Selectable() use of half-ItemSpacing isn't consistent in matter of layout, as ItemAdd(bb) stray above ItemSize()'s CursorPos.
|
||||||
-- RangeSelect's BoxSelect relies on comparing overlap of previous and current rectangle and is sensitive to that.
|
-- RangeSelect's BoxSelect relies on comparing overlap of previous and current rectangle and is sensitive to that.
|
||||||
-- As a workaround we currently half ItemSpacing worth on each side.
|
-- As a workaround we currently half ItemSpacing worth on each side.
|
||||||
@@ -19846,7 +19850,7 @@ function ImGui.ErrorRecoveryTryToRecoverWindowState(state_in)
|
|||||||
IM_ASSERT_USER_ERROR(false, "Missing EndTabBar()")
|
IM_ASSERT_USER_ERROR(false, "Missing EndTabBar()")
|
||||||
ImGui.EndTabBar()
|
ImGui.EndTabBar()
|
||||||
end
|
end
|
||||||
while g.CurrentMultiSelect ~= nil and g.CurrentMultiSelect.Storage.Window == window and ImGui.EndMultiSelect do
|
while g.CurrentMultiSelect ~= nil and g.CurrentMultiSelect.Storage.Window == window do --V1044
|
||||||
IM_ASSERT_USER_ERROR(false, "Missing EndMultiSelect()")
|
IM_ASSERT_USER_ERROR(false, "Missing EndMultiSelect()")
|
||||||
ImGui.EndMultiSelect()
|
ImGui.EndMultiSelect()
|
||||||
end
|
end
|
||||||
@@ -21183,6 +21187,25 @@ function ImGui.ShowMetricsWindow(p_open)
|
|||||||
ImGui.TreePop()
|
ImGui.TreePop()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Details for TypingSelect
|
||||||
|
if ImGui.TreeNode("TypingSelect", "TypingSelect (%d)", (#g.TypingSelectState.SearchBuffer ~= 0) and 1 or 0) then
|
||||||
|
ImGui.DebugNodeTypingSelectState(g.TypingSelectState)
|
||||||
|
ImGui.TreePop()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Details for MultiSelect
|
||||||
|
if ImGui.TreeNode("MultiSelect", "MultiSelect (%d)", g.MultiSelectStorage.AliveCount) then
|
||||||
|
local bs = g.BoxSelectState
|
||||||
|
ImGui.BulletText("BoxSelect ID=0x%08X, Starting = %d, Active %d", bs.ID, B(bs.IsStarting), B(bs.IsActive))
|
||||||
|
for n = 0, g.MultiSelectStorage:GetMapSize() - 1 do
|
||||||
|
local state = g.MultiSelectStorage:GetByIndex(n)
|
||||||
|
if state then
|
||||||
|
ImGui.DebugNodeMultiSelectState(state)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ImGui.TreePop()
|
||||||
|
end
|
||||||
|
|
||||||
-- Details for Docking
|
-- Details for Docking
|
||||||
if ImGui.TreeNode("Docking") then
|
if ImGui.TreeNode("Docking") then
|
||||||
local dc = g.DockContext
|
local dc = g.DockContext
|
||||||
@@ -21310,6 +21333,7 @@ function ImGui.ShowMetricsWindow(p_open)
|
|||||||
ImGui.Indent()
|
ImGui.Indent()
|
||||||
ImGui.Text("NavWindow: '%s'", N(g.NavWindow))
|
ImGui.Text("NavWindow: '%s'", N(g.NavWindow))
|
||||||
ImGui.Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer)
|
ImGui.Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer)
|
||||||
|
ImGui.Text("NavLastValidSelectionUserData = %s", tostring(g.NavLastValidSelectionUserData)) -- [Port] any Lua value: tostring() instead of %lld (0x%llX)
|
||||||
ImGui.Text("NavActive: %d, NavVisible: %d", B(io.NavActive), B(io.NavVisible))
|
ImGui.Text("NavActive: %d, NavVisible: %d", B(io.NavActive), B(io.NavVisible))
|
||||||
ImGui.Text("NavActivateId/DownId/PressedId: %08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId or 0, g.NavActivatePressedId or 0)
|
ImGui.Text("NavActivateId/DownId/PressedId: %08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId or 0, g.NavActivatePressedId or 0)
|
||||||
ImGui.Text("NavActivateFlags: %04X", g.NavActivateFlags or 0)
|
ImGui.Text("NavActivateFlags: %04X", g.NavActivateFlags or 0)
|
||||||
|
|||||||
+116
@@ -2713,6 +2713,122 @@ function ImColorMT:U32() return ImGui.ColorConvertFloat4ToU32(self.Value) end
|
|||||||
function ImColorMT:SetHSV(h, s, v, a) self.Value.x, self.Value.y, self.Value.z = ImGui.ColorConvertHSVtoRGB(h, s, v); self.Value.w = a or 1.0 end
|
function ImColorMT:SetHSV(h, s, v, a) self.Value.x, self.Value.y, self.Value.z = ImGui.ColorConvertHSVtoRGB(h, s, v); self.Value.w = a or 1.0 end
|
||||||
function ImColor.HSV(h, s, v, a) local r, g, b = ImGui.ColorConvertHSVtoRGB(h, s, v); return ImColor(r, g, b, a or 1.0) end
|
function ImColor.HSV(h, s, v, a) local r, g, b = ImGui.ColorConvertHSVtoRGB(h, s, v); return ImColor(r, g, b, a or 1.0) end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- [SECTION] Multi-Select API flags and structures (ImGuiMultiSelectFlags, ImGuiSelectionRequestType, ImGuiSelectionRequest, ImGuiMultiSelectIO, ImGuiSelectionBasicStorage)
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- Multi-selection system
|
||||||
|
-- Documentation at: https://github.com/ocornut/imgui/wiki/Multi-Select
|
||||||
|
-- - Refer to 'Demo->Widgets->Selection State & Multi-Select' for demos using this.
|
||||||
|
-- - This system implements standard multi-selection idioms (Ctrl+Mouse/Keyboard, Shift+Mouse/Keyboard, etc)
|
||||||
|
-- with support for clipper (skipping non-visible items), box-select and many other details.
|
||||||
|
-- - Selectable(), Checkbox() are supported but custom widgets may use it as well.
|
||||||
|
-- - TreeNode() is technically supported but... using this correctly is more complicated: you need some sort of linear/random access to your tree,
|
||||||
|
-- which is suited to advanced trees setups also implementing filters and clipper. We will work toward simplifying and demoing it.
|
||||||
|
-- - In the spirit of Dear ImGui design, your code owns actual selection data.
|
||||||
|
-- This is designed to allow all kinds of selection storage you may use in your application e.g. set/map/hash.
|
||||||
|
-- About ImGuiSelectionBasicStorage:
|
||||||
|
-- - This is an optional helper to store a selection state and apply selection requests.
|
||||||
|
-- - It is used by our demos and provided as a convenience to quickly implement multi-selection.
|
||||||
|
-- Usage:
|
||||||
|
-- - Identify submitted items with SetNextItemSelectionUserData(), most likely using an index into your current data-set.
|
||||||
|
-- - Store and maintain actual selection data using persistent object identifiers.
|
||||||
|
-- - Usage flow:
|
||||||
|
-- BEGIN - (1) Call BeginMultiSelect() and retrieve the ImGuiMultiSelectIO result.
|
||||||
|
-- - (2) Honor request list (SetAll/SetRange requests) by updating your selection data. Same code as Step 6.
|
||||||
|
-- - (3) [If using clipper] You need to make sure RangeSrcItem is always submitted. Calculate its index and pass to clipper:IncludeItemByIndex(). If storing indices in ImGuiSelectionUserData, a simple clipper:IncludeItemByIndex(ms_io.RangeSrcItem) call will work.
|
||||||
|
-- LOOP - (4) Submit your items with SetNextItemSelectionUserData() + Selectable()/TreeNode() calls.
|
||||||
|
-- END - (5) Call EndMultiSelect() and retrieve the ImGuiMultiSelectIO result.
|
||||||
|
-- - (6) Honor request list (SetAll/SetRange requests) by updating your selection data. Same code as Step 2.
|
||||||
|
-- If you submit all items (no clipper), Step 2 and 3 are optional and will be handled by each item themselves. It is fine to always honor those steps.
|
||||||
|
-- About ImGuiSelectionUserData:
|
||||||
|
-- - This can store an application-defined identifier (e.g. index or pointer) submitted via SetNextItemSelectionUserData().
|
||||||
|
-- - In return we store them into RangeSrcItem/RangeFirstItem/RangeLastItem and other fields in ImGuiMultiSelectIO.
|
||||||
|
-- - Most applications will store an object INDEX, hence the chosen name and type. Storing an index is natural, because
|
||||||
|
-- SetRange requests will give you two end-points and you will need to iterate/interpolate between them to update your selection.
|
||||||
|
-- - However it is perfectly possible to store a POINTER or another IDENTIFIER inside ImGuiSelectionUserData.
|
||||||
|
-- Our system never assume that you identify items by indices, it never attempts to interpolate between two values.
|
||||||
|
-- - If you enable ImGuiMultiSelectFlags.NoRangeSelect then it is guaranteed that you will never have to interpolate
|
||||||
|
-- between two ImGuiSelectionUserData, which may be a convenient way to use part of the feature with less code work.
|
||||||
|
-- - As most users will want to store an index, for convenience and to reduce confusion we use ImS64 instead of void*,
|
||||||
|
-- being syntactically easier to downcast. Feel free to reinterpret_cast and store a pointer inside.
|
||||||
|
-- [Port] ImGuiSelectionUserData is any Lua value compared with '==' (an integer index, or e.g. a table reference instead of a pointer).
|
||||||
|
-- -1 (ImGuiSelectionUserData_Invalid) is reserved. ImGuiSelectionBasicStorage/ImGuiSelectionExternalStorage require integer indices.
|
||||||
|
|
||||||
|
-- Flags for BeginMultiSelect()
|
||||||
|
--- @enum ImGuiMultiSelectFlags
|
||||||
|
ImGuiMultiSelectFlags = {
|
||||||
|
None = 0,
|
||||||
|
SingleSelect = bitLShift(1, 0), -- Disable selecting more than one item. This is available to allow single-selection code to share same code/logic if desired. It essentially disables the main purpose of BeginMultiSelect() tho!
|
||||||
|
NoSelectAll = bitLShift(1, 1), -- Disable Ctrl+A shortcut to select all.
|
||||||
|
NoRangeSelect = bitLShift(1, 2), -- Disable Shift+selection mouse/keyboard support (useful for unordered 2D selection). With BoxSelect is also ensure contiguous SetRange requests are not combined into one. This allows not handling interpolation in SetRange requests.
|
||||||
|
NoAutoSelect = bitLShift(1, 3), -- Disable selecting items when navigating (useful for e.g. supporting range-select in a list of checkboxes).
|
||||||
|
NoAutoClear = bitLShift(1, 4), -- Disable clearing selection when navigating or selecting another one (generally used with ImGuiMultiSelectFlags.NoAutoSelect. useful for e.g. supporting range-select in a list of checkboxes).
|
||||||
|
NoAutoClearOnReselect = bitLShift(1, 5), -- Disable clearing selection when clicking/selecting an already selected item.
|
||||||
|
BoxSelect1d = bitLShift(1, 6), -- Enable box-selection with same width and same x pos items (e.g. full row Selectable()). Box-selection works better with little bit of spacing between items hit-box in order to be able to aim at empty space.
|
||||||
|
BoxSelect2d = bitLShift(1, 7), -- Enable box-selection with varying width or varying x pos items support (e.g. different width labels, or 2D layout/grid). This is slower: alters clipping logic so that e.g. horizontal movements will update selection of normally clipped items.
|
||||||
|
BoxSelectNoScroll = bitLShift(1, 8), -- Disable scrolling when box-selecting and moving mouse near edges of scope.
|
||||||
|
ClearOnEscape = bitLShift(1, 9), -- Clear selection when pressing Escape while scope is focused.
|
||||||
|
ClearOnClickVoid = bitLShift(1, 10), -- Clear selection when clicking on empty location within scope.
|
||||||
|
ScopeWindow = bitLShift(1, 11), -- Scope for _BoxSelect and _ClearOnClickVoid is whole window (Default). Use if BeginMultiSelect() covers a whole window or used a single time in same window.
|
||||||
|
ScopeRect = bitLShift(1, 12), -- Scope for _BoxSelect and _ClearOnClickVoid is rectangle encompassing BeginMultiSelect()/EndMultiSelect(). Use if BeginMultiSelect() is called multiple times in same window.
|
||||||
|
SelectOnAuto = bitLShift(1, 13), -- Apply selection on mouse down when clicking on unselected item, on mouse up when clicking on selected item. (Default)
|
||||||
|
SelectOnClickAlways = bitLShift(1, 14), -- Apply selection on mouse down when clicking on any items. Prevents Drag and Drop from being used on multiple-selection, but allows e.g. BoxSelect to always reselect even when clicking inside an existing selection. (Excel style behavior)
|
||||||
|
SelectOnClickRelease = bitLShift(1, 15), -- Apply selection on mouse release when clicking an unselected item. Allow dragging an unselected item without altering selection.
|
||||||
|
--RangeSelect2d = bitLShift(1, 15), -- Shift+Selection uses 2d geometry instead of linear sequence, so possible to use Shift+up/down to select vertically in grid. Analogous to what BoxSelect does.
|
||||||
|
NavWrapX = bitLShift(1, 16), -- [Temporary] Enable navigation wrapping on X axis. Provided as a convenience because we don't have a design for the general Nav API for this yet. When the more general feature be public we may obsolete this flag in favor of new one.
|
||||||
|
NoSelectOnRightClick = bitLShift(1, 17), -- Disable default right-click processing, which selects item on mouse down, and is designed for context-menus.
|
||||||
|
CheckboxMode_ = bitLShift(1, 20), -- [Internal]
|
||||||
|
}
|
||||||
|
ImGuiMultiSelectFlags.SelectOnMask_ = bit32.bor(ImGuiMultiSelectFlags.SelectOnAuto, ImGuiMultiSelectFlags.SelectOnClickAlways, ImGuiMultiSelectFlags.SelectOnClickRelease)
|
||||||
|
ImGuiMultiSelectFlags.SelectOnClick = ImGuiMultiSelectFlags.SelectOnAuto -- RENAMED in 1.92.6
|
||||||
|
|
||||||
|
-- Main IO structure returned by BeginMultiSelect()/EndMultiSelect().
|
||||||
|
-- This mainly contains a list of selection requests.
|
||||||
|
-- - Use 'Demo->Tools->Debug Log->Selection' to see requests as they happen.
|
||||||
|
-- - Some fields are only useful if your list is dynamic and allows deletion (getting post-deletion focus/state right is shown in the demo)
|
||||||
|
-- - Below: who reads/writes each fields? 'r'=read, 'w'=write, 'ms'=multi-select code, 'app'=application/user code.
|
||||||
|
--- @class ImGuiMultiSelectIO
|
||||||
|
--- @field Requests ImVector<ImGuiSelectionRequest> # ms:w, app:r / ms:w app:r // Requests to apply to your selection data. (1-based .Data)
|
||||||
|
--- @field RangeSrcItem ImGuiSelectionUserData # ms:w app:r / // (If using clipper) Begin: Source item (often the first selected item) must never be clipped: use clipper:IncludeItemByIndex() to ensure it is submitted.
|
||||||
|
--- @field NavIdItem ImGuiSelectionUserData # ms:w, app:r / // (If using deletion) Last known SetNextItemSelectionUserData() value for NavId (if part of submitted items).
|
||||||
|
--- @field NavIdSelected bool # ms:w, app:r / app:r // (If using deletion) Last known selection state for NavId (if part of submitted items).
|
||||||
|
--- @field RangeSrcReset bool # app:w / ms:r // (If using deletion) Set before EndMultiSelect() to reset ResetSrcItem (e.g. if deleted selection).
|
||||||
|
--- @field ItemsCount int # ms:w, app:r / app:r // 'int items_count' parameter to BeginMultiSelect() is copied here for convenience, allowing simpler calls to your ApplyRequests handler. Not used internally.
|
||||||
|
|
||||||
|
-- Selection request type
|
||||||
|
--- @enum ImGuiSelectionRequestType
|
||||||
|
ImGuiSelectionRequestType = {
|
||||||
|
None = 0,
|
||||||
|
SetAll = 1, -- Request app to clear selection (if Selected==false) or select all items (if Selected==true). We cannot set RangeFirstItem/RangeLastItem as its contents is entirely up to user (not necessarily an index)
|
||||||
|
SetRange = 2, -- Request app to select/unselect [RangeFirstItem..RangeLastItem] items (inclusive) based on value of Selected. Only EndMultiSelect() request this, app code can read after BeginMultiSelect() and it will always be false.
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Selection request item
|
||||||
|
--- @class ImGuiSelectionRequest
|
||||||
|
--- @field Type ImGuiSelectionRequestType # ms:w, app:r / ms:w, app:r // Request type. You'll most often receive 1 Clear + 1 SetRange with a single-item range.
|
||||||
|
--- @field Selected bool # ms:w, app:r / ms:w, app:r // Parameter for SetAll/SetRange requests (true = select, false = unselect)
|
||||||
|
--- @field RangeDirection int # / ms:w app:r // Parameter for SetRange request: +1 when RangeFirstItem comes before RangeLastItem, -1 otherwise. Useful if you want to preserve selection order on a backward Shift+Click.
|
||||||
|
--- @field RangeFirstItem ImGuiSelectionUserData # / ms:w, app:r // Parameter for SetRange request (this is generally == RangeSrcItem when shift selecting from top to bottom).
|
||||||
|
--- @field RangeLastItem ImGuiSelectionUserData # / ms:w, app:r // Parameter for SetRange request (this is generally == RangeSrcItem when shift selecting from bottom to top). Inclusive!
|
||||||
|
function ImGuiSelectionRequest()
|
||||||
|
return { Type = ImGuiSelectionRequestType.None, Selected = false, RangeDirection = 0, RangeFirstItem = -1, RangeLastItem = -1 }
|
||||||
|
end
|
||||||
|
-- [Port] ImVector<ImGuiSelectionRequest> copy function: push_back() copies fields into the preallocated element (C++ copies by value),
|
||||||
|
-- so callers can push a reused scratch request without allocating.
|
||||||
|
function ImGuiSelectionRequest_Copy(t, k, v)
|
||||||
|
local dst = t[k]
|
||||||
|
dst.Type = v.Type; dst.Selected = v.Selected; dst.RangeDirection = v.RangeDirection; dst.RangeFirstItem = v.RangeFirstItem; dst.RangeLastItem = v.RangeLastItem
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @return ImGuiMultiSelectIO
|
||||||
|
function ImGuiMultiSelectIO()
|
||||||
|
return { Requests = ImVector(ImGuiSelectionRequest, ImGuiSelectionRequest_Copy), RangeSrcItem = -1, NavIdItem = -1, NavIdSelected = false, RangeSrcReset = false, ItemsCount = 0 }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- ImGuiSelectionBasicStorage, ImGuiSelectionExternalStorage: see [SECTION] Widgets: Multi-Select helpers in imgui_widgets.lua
|
||||||
|
-- (constructors and methods are defined there, like upstream's out-of-line definitions in imgui_widgets.cpp).
|
||||||
|
|
||||||
--- @class ImGuiSettingsHandler
|
--- @class ImGuiSettingsHandler
|
||||||
--- Fns take (ctx, handler, ...) like upstream. ReadOpenFn(ctx, handler, name) returns entry; ReadLineFn(ctx, handler, entry, line);
|
--- Fns take (ctx, handler, ...) like upstream. ReadOpenFn(ctx, handler, name) returns entry; ReadLineFn(ctx, handler, entry, line);
|
||||||
--- WriteAllFn(ctx, handler, buf: ImGuiTextBuffer)
|
--- WriteAllFn(ctx, handler, buf: ImGuiTextBuffer)
|
||||||
|
|||||||
@@ -386,6 +386,16 @@ end
|
|||||||
--@hoist
|
--@hoist
|
||||||
function ImSaturate(f) return ((f < 0.0 and 0.0) or (f > 1.0 and 1.0) or f) end
|
function ImSaturate(f) return ((f < 0.0 and 0.0) or (f > 1.0 and 1.0) or f) end
|
||||||
|
|
||||||
|
--- @param x float
|
||||||
|
--- @return float # Sign operator - returns -1, 0 or 1 based on sign of argument
|
||||||
|
function ImSign(x) if x < 0.0 then return -1.0 elseif x > 0.0 then return 1.0 end return 0.0 end
|
||||||
|
|
||||||
|
function ImLinearRemapClamp(s0, s1, d0, d1, x) return ImSaturate((x - s0) / (s1 - s0)) * (d1 - d0) + d0 end
|
||||||
|
|
||||||
|
--- @param c int # byte
|
||||||
|
--- @return int
|
||||||
|
function ImToUpper(c) if c >= 97 and c <= 122 then return bit32.band(c, bit32.bnot(32)) end return c end
|
||||||
|
|
||||||
IM_F32_TO_INT8_UNBOUND = function(val) return math.floor(val * 255.0 + (val >= 0 and 0.5 or -0.5)) end -- Unsaturated, for display purpose
|
IM_F32_TO_INT8_UNBOUND = function(val) return math.floor(val * 255.0 + (val >= 0 and 0.5 or -0.5)) end -- Unsaturated, for display purpose
|
||||||
IM_F32_TO_INT8_SAT = function(val) return math.floor(ImSaturate(val) * 255.0 + 0.5) end -- Saturated, always output 0..255
|
IM_F32_TO_INT8_SAT = function(val) return math.floor(ImSaturate(val) * 255.0 + 0.5) end -- Saturated, always output 0..255
|
||||||
|
|
||||||
@@ -658,6 +668,12 @@ end
|
|||||||
--- @nodiscard
|
--- @nodiscard
|
||||||
function ImGui.WindowPosAbsToRel(window, p) local off = window.DC.CursorStartPos return ImVec2(p.x - off.x, p.y - off.y) end
|
function ImGui.WindowPosAbsToRel(window, p) local off = window.DC.CursorStartPos return ImVec2(p.x - off.x, p.y - off.y) end
|
||||||
|
|
||||||
|
--- @param window ImGuiWindow
|
||||||
|
--- @param p ImVec2
|
||||||
|
--- @return ImVec2
|
||||||
|
--- @nodiscard
|
||||||
|
function ImGui.WindowPosRelToAbs(window, p) local off = window.DC.CursorStartPos return ImVec2(p.x + off.x, p.y + off.y) end
|
||||||
|
|
||||||
--- @param c char
|
--- @param c char
|
||||||
--- @return bool # True if this character is a ' ' or '\t'
|
--- @return bool # True if this character is a ' ' or '\t'
|
||||||
function ImCharIsBlankA(c) return c == 32 or c == 9 end
|
function ImCharIsBlankA(c) return c == 32 or c == 9 end
|
||||||
@@ -880,6 +896,9 @@ function IM_RECT:Add(p)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function IM_RECT:AddX(x) if self.Min.x > x then self.Min.x = x end if self.Max.x < x then self.Max.x = x end end
|
||||||
|
function IM_RECT:AddY(y) if self.Min.y > y then self.Min.y = y end if self.Max.y < y then self.Max.y = y end end
|
||||||
|
|
||||||
--- @param amount float|ImVec2
|
--- @param amount float|ImVec2
|
||||||
@native
|
@native
|
||||||
function IM_RECT:Expand(amount)
|
function IM_RECT:Expand(amount)
|
||||||
@@ -1848,6 +1867,164 @@ local function ImGuiNavItemData()
|
|||||||
return this
|
return this
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- [SECTION] Typing-select support
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- Flags for GetTypingSelectRequest()
|
||||||
|
--- @enum ImGuiTypingSelectFlags
|
||||||
|
ImGuiTypingSelectFlags = {
|
||||||
|
None = 0,
|
||||||
|
AllowBackspace = bitLShift(1, 0), -- Backspace to delete character inputs. If using: ensure GetTypingSelectRequest() is not called more than once per frame (filter by e.g. focus state)
|
||||||
|
AllowSingleCharMode = bitLShift(1, 1), -- Allow "single char" search mode which is activated when pressing the same character multiple times.
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Returned by GetTypingSelectRequest(), designed to eventually be public.
|
||||||
|
--- @class ImGuiTypingSelectRequest
|
||||||
|
--- @field Flags ImGuiTypingSelectFlags # Flags passed to GetTypingSelectRequest()
|
||||||
|
--- @field SearchBufferLen int
|
||||||
|
--- @field SearchBuffer string # Search buffer contents (use full string. unless SingleCharMode is set, in which case use SingleCharSize).
|
||||||
|
--- @field SelectRequest bool # Set when buffer was modified this frame, requesting a selection.
|
||||||
|
--- @field SingleCharMode bool # Notify when buffer contains same character repeated, to implement special mode. In this situation it preferred to not display any on-screen search indication.
|
||||||
|
--- @field SingleCharSize int # Length in bytes of first letter codepoint (1 for ascii, 2-4 for UTF-8). If (SearchBufferLen==RepeatCharSize) only 1 letter has been input.
|
||||||
|
local function ImGuiTypingSelectRequest()
|
||||||
|
return { Flags = 0, SearchBufferLen = 0, SearchBuffer = "", SelectRequest = false, SingleCharMode = false, SingleCharSize = 0 }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Storage for GetTypingSelectRequest()
|
||||||
|
-- [Port] SearchBuffer is an immutable Lua string (C++: char[64], 63 bytes max + zero terminator). SearchBuffer[0] != 0 -> #SearchBuffer ~= 0.
|
||||||
|
--- @class ImGuiTypingSelectState
|
||||||
|
--- @field Request ImGuiTypingSelectRequest # User-facing data
|
||||||
|
--- @field SearchBuffer string # Search buffer: no need to make dynamic as this search is very transient.
|
||||||
|
--- @field FocusScope ImGuiID
|
||||||
|
--- @field LastRequestFrame int
|
||||||
|
--- @field LastRequestTime float
|
||||||
|
--- @field SingleCharModeLock bool # After a certain single char repeat count we lock into SingleCharMode. Two benefits: 1) buffer never fill, 2) we can provide an immediate SingleChar mode without timer elapsing.
|
||||||
|
MT.ImGuiTypingSelectState = {}
|
||||||
|
MT.ImGuiTypingSelectState.__index = MT.ImGuiTypingSelectState
|
||||||
|
|
||||||
|
--- @return ImGuiTypingSelectState
|
||||||
|
function ImGuiTypingSelectState()
|
||||||
|
return setmetatable({ Request = ImGuiTypingSelectRequest(), SearchBuffer = "", FocusScope = 0, LastRequestFrame = 0, LastRequestTime = 0.0, SingleCharModeLock = false }, MT.ImGuiTypingSelectState)
|
||||||
|
end
|
||||||
|
function MT.ImGuiTypingSelectState:Clear() self.SearchBuffer = ""; self.SingleCharModeLock = false end -- We preserve remaining data for easier debugging
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- [SECTION] Box-select support
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- @class ImGuiBoxSelectState
|
||||||
|
--- @field ID ImGuiID
|
||||||
|
--- @field IsActive bool
|
||||||
|
--- @field IsStarting bool
|
||||||
|
--- @field IsStartedFromVoid bool # Starting click was not from an item.
|
||||||
|
--- @field IsStartedSetNavIdOnce bool
|
||||||
|
--- @field RequestClear bool
|
||||||
|
--- @field KeyMods ImGuiKeyChord # Latched key-mods for box-select logic.
|
||||||
|
--- @field StartPosRel ImVec2 # Start position in window-contents relative space (to support scrolling)
|
||||||
|
--- @field EndPosRel ImVec2 # End position in window-contents relative space
|
||||||
|
--- @field ScrollAccum ImVec2 # Scrolling accumulator (to behave at high-frame spaces)
|
||||||
|
--- @field Window ImGuiWindow?
|
||||||
|
--- @field UnclipMode bool # (Temp/Transient, here in hot area). Set/cleared by the BeginMultiSelect()/EndMultiSelect() owning active box-select.
|
||||||
|
--- @field UnclipRect ImRect # Rectangle where ItemAdd() clipping may be temporarily disabled. Need support by multi-select supporting widgets.
|
||||||
|
--- @field UnclipRects ImRect[] # Per-axis versions. [Port] 1-based: [1] = upstream [0] (X), [2] = upstream [1] (Y)
|
||||||
|
--- @field BoxSelectRectPrev ImRect # Selection rectangle in absolute coordinates (derived every frame from BoxSelectStartPosRel and MousePos)
|
||||||
|
--- @field BoxSelectRectCurr ImRect
|
||||||
|
--- @return ImGuiBoxSelectState
|
||||||
|
function ImGuiBoxSelectState()
|
||||||
|
return {
|
||||||
|
-- Active box-selection data (persistent, 1 active at a time)
|
||||||
|
ID = 0, IsActive = false, IsStarting = false, IsStartedFromVoid = false, IsStartedSetNavIdOnce = false, RequestClear = false,
|
||||||
|
KeyMods = 0,
|
||||||
|
StartPosRel = ImVec2(), EndPosRel = ImVec2(), ScrollAccum = ImVec2(),
|
||||||
|
Window = nil,
|
||||||
|
|
||||||
|
-- Temporary/Transient data
|
||||||
|
UnclipMode = false,
|
||||||
|
UnclipRect = ImRect(),
|
||||||
|
UnclipRects = { ImRect(), ImRect() },
|
||||||
|
BoxSelectRectPrev = ImRect(),
|
||||||
|
BoxSelectRectCurr = ImRect(),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- [SECTION] Multi-select support
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- We always assume that -1 is an invalid value (which works for indices and pointers)
|
||||||
|
-- (ImGuiSelectionUserData_Invalid is defined above with the ImGuiSelectionUserData alias)
|
||||||
|
|
||||||
|
-- Temporary storage for multi-select
|
||||||
|
--- @class ImGuiMultiSelectTempData
|
||||||
|
--- @field IO ImGuiMultiSelectIO # MUST BE FIRST FIELD. Requests are set and returned by BeginMultiSelect()/EndMultiSelect() + written to by user during the loop.
|
||||||
|
--- @field Storage ImGuiMultiSelectState?
|
||||||
|
--- @field FocusScopeId ImGuiID # Copied from g.CurrentFocusScopeId (unless another selection scope was pushed manually)
|
||||||
|
--- @field Flags ImGuiMultiSelectFlags
|
||||||
|
--- @field ScopeRectMin ImVec2
|
||||||
|
--- @field BackupCursorMaxPos ImVec2
|
||||||
|
--- @field BoxSelectId ImGuiID
|
||||||
|
--- @field KeyMods ImGuiKeyChord
|
||||||
|
--- @field LoopRequestSetAll int # -1: no operation, 0: clear all, 1: select all.
|
||||||
|
--- @field IsEndIO bool # Set when switching IO from BeginMultiSelect() to EndMultiSelect() state.
|
||||||
|
--- @field IsFocused bool # Set if currently focusing the selection scope (any item of the selection). May be used if you have custom shortcut associated to selection.
|
||||||
|
--- @field IsKeyboardSetRange bool # Set by BeginMultiSelect() when using Shift+Navigation. Because scrolling may be affected we can't afford a frame of lag with Shift+Navigation.
|
||||||
|
--- @field NavIdPassedBy bool
|
||||||
|
--- @field RangeSrcPassedBy bool # Set by the item that matches RangeSrcItem.
|
||||||
|
--- @field RangeDstPassedBy bool # Set by the item that matches NavJustMovedToId when IsSetRange is set.
|
||||||
|
--- @field IsSoleOrUnknownSelectionSize bool
|
||||||
|
MT.ImGuiMultiSelectTempData = {}
|
||||||
|
MT.ImGuiMultiSelectTempData.__index = MT.ImGuiMultiSelectTempData
|
||||||
|
|
||||||
|
--- @return ImGuiMultiSelectTempData
|
||||||
|
function ImGuiMultiSelectTempData()
|
||||||
|
local this = setmetatable({ IO = ImGuiMultiSelectIO(), ScopeRectMin = ImVec2(), BackupCursorMaxPos = ImVec2() }, MT.ImGuiMultiSelectTempData)
|
||||||
|
this:Clear()
|
||||||
|
return this
|
||||||
|
end
|
||||||
|
-- Zero-clear except IO as we preserve IO.Requests[] buffer allocation.
|
||||||
|
function MT.ImGuiMultiSelectTempData:Clear()
|
||||||
|
self:ClearIO()
|
||||||
|
self.Storage = nil
|
||||||
|
self.FocusScopeId = 0
|
||||||
|
self.Flags = 0
|
||||||
|
ImVec2_CopyV(self.ScopeRectMin, 0.0, 0.0)
|
||||||
|
ImVec2_CopyV(self.BackupCursorMaxPos, 0.0, 0.0)
|
||||||
|
self.BoxSelectId = 0
|
||||||
|
self.KeyMods = 0
|
||||||
|
self.LoopRequestSetAll = 0
|
||||||
|
self.IsEndIO = false
|
||||||
|
self.IsFocused = false
|
||||||
|
self.IsKeyboardSetRange = false
|
||||||
|
self.NavIdPassedBy = false
|
||||||
|
self.RangeSrcPassedBy = false
|
||||||
|
self.RangeDstPassedBy = false
|
||||||
|
self.IsSoleOrUnknownSelectionSize = false
|
||||||
|
end
|
||||||
|
function MT.ImGuiMultiSelectTempData:ClearIO() local io = self.IO; io.Requests:resize(0); io.RangeSrcItem = ImGuiSelectionUserData_Invalid; io.NavIdItem = ImGuiSelectionUserData_Invalid; io.NavIdSelected = false; io.RangeSrcReset = false end
|
||||||
|
|
||||||
|
-- Persistent storage for multi-select (as long as selection is alive)
|
||||||
|
--- @class ImGuiMultiSelectState
|
||||||
|
--- @field Window ImGuiWindow?
|
||||||
|
--- @field ID ImGuiID
|
||||||
|
--- @field LastFrameActive int # Last used frame-count, for GC.
|
||||||
|
--- @field LastSelectionSize int # Set by BeginMultiSelect() based on optional info provided by user. May be -1 if unknown.
|
||||||
|
--- @field RangeSelected int # -1 (don't have) or true/false
|
||||||
|
--- @field NavIdSelected int # -1 (don't have) or true/false
|
||||||
|
--- @field RangeSrcItem ImGuiSelectionUserData #
|
||||||
|
--- @field NavIdItem ImGuiSelectionUserData # SetNextItemSelectionUserData() value for NavId (if part of submitted items)
|
||||||
|
--- @return ImGuiMultiSelectState
|
||||||
|
function ImGuiMultiSelectState()
|
||||||
|
return { Window = nil, ID = 0, LastFrameActive = 0, LastSelectionSize = 0, RangeSelected = -1, NavIdSelected = -1, RangeSrcItem = ImGuiSelectionUserData_Invalid, NavIdItem = ImGuiSelectionUserData_Invalid }
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param id ImGuiID
|
||||||
|
--- @return ImGuiBoxSelectState?
|
||||||
|
function ImGui.GetBoxSelectState(id) local g = GImGui; if id ~= 0 and g.BoxSelectState.ID == id and g.BoxSelectState.IsActive then return g.BoxSelectState end return nil end
|
||||||
|
--- @param id ImGuiID
|
||||||
|
--- @return ImGuiMultiSelectState?
|
||||||
|
function ImGui.GetMultiSelectState(id) local g = GImGui; return g.MultiSelectStorage:GetByKey(id) end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- [SECTION] ImGuiContext (main Dear ImGui context)
|
-- [SECTION] ImGuiContext (main Dear ImGui context)
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@@ -2129,6 +2306,7 @@ function ImGuiContext(shared_font_atlas) -- TODO: tidy up / complete this struct
|
|||||||
NavHighlightItemUnderNav = false, -- Disable mouse hovering highlight. Highlight navigation focused item instead of mouse hovered item.
|
NavHighlightItemUnderNav = false, -- Disable mouse hovering highlight. Highlight navigation focused item instead of mouse hovered item.
|
||||||
NavIdIsAlive = false, -- Nav widget has been seen this frame ~~ NavRectRel is valid
|
NavIdIsAlive = false, -- Nav widget has been seen this frame ~~ NavRectRel is valid
|
||||||
NavInputSource = ImGuiInputSource.Keyboard, -- Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource.Keyboard or ImGuiInputSource.Gamepad
|
NavInputSource = ImGuiInputSource.Keyboard, -- Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource.Keyboard or ImGuiInputSource.Gamepad
|
||||||
|
NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid, -- Last valid data passed to SetNextItemSelectionUser(), or -1. For current window. Not reset when focusing an item that doesn't have selection data.
|
||||||
NavWindowingTarget = nil, NavWindowingTargetAnim = nil, NavWindowingListWindow = nil, -- Target window when doing Ctrl+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most!
|
NavWindowingTarget = nil, NavWindowingTargetAnim = nil, NavWindowingListWindow = nil, -- Target window when doing Ctrl+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most!
|
||||||
NavWindowingTimer = 0.0, NavWindowingHighlightAlpha = 0.0,
|
NavWindowingTimer = 0.0, NavWindowingHighlightAlpha = 0.0,
|
||||||
NavWindowingToggleLayer = false, -- Set while Alt or GamepadMenu is held, may be cleared by other operations, and processed when releasing the key.
|
NavWindowingToggleLayer = false, -- Set while Alt or GamepadMenu is held, may be cleared by other operations, and processed when releasing the key.
|
||||||
@@ -2168,6 +2346,14 @@ function ImGuiContext(shared_font_atlas) -- TODO: tidy up / complete this struct
|
|||||||
NavActivateId = 0, NavActivateDownId = 0, NavActivatePressedId = 0, -- ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey.Space) || IsKeyDown(ImGuiKey.Enter) || IsKeyPressed(ImGuiKey.NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItemByID()
|
NavActivateId = 0, NavActivateDownId = 0, NavActivatePressedId = 0, -- ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey.Space) || IsKeyDown(ImGuiKey.Enter) || IsKeyPressed(ImGuiKey.NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItemByID()
|
||||||
NavActivateFlags = ImGuiActivateFlags.None,
|
NavActivateFlags = ImGuiActivateFlags.None,
|
||||||
|
|
||||||
|
-- Navigation: record of last move request
|
||||||
|
NavJustMovedFromFocusScopeId = 0, -- Just navigated from this focus scope id (result of a successfully MoveRequest).
|
||||||
|
NavJustMovedToId = 0, -- Just navigated to this id (result of a successfully MoveRequest).
|
||||||
|
NavJustMovedToFocusScopeId = 0, -- Just navigated to this focus scope id (result of a successfully MoveRequest).
|
||||||
|
NavJustMovedToKeyMods = 0,
|
||||||
|
NavJustMovedToIsTabbing = false, -- Copy of ImGuiNavMoveFlags.IsTabbing. Maybe we should store whole flags.
|
||||||
|
NavJustMovedToHasSelectionData = false, -- Copy of move result's ItemFlags & ImGuiItemFlags.HasSelectionUserData). Maybe we should just store ImGuiNavItemData.
|
||||||
|
|
||||||
FrameCount = 0,
|
FrameCount = 0,
|
||||||
|
|
||||||
FrameCountEnded = -1,
|
FrameCountEnded = -1,
|
||||||
@@ -2228,6 +2414,8 @@ function ImGuiContext(shared_font_atlas) -- TODO: tidy up / complete this struct
|
|||||||
MouseCursor = ImGuiMouseCursor.Arrow,
|
MouseCursor = ImGuiMouseCursor.Arrow,
|
||||||
MouseStationaryTimer = 0.0, -- Time the mouse has been stationary (with some loose heuristic)
|
MouseStationaryTimer = 0.0, -- Time the mouse has been stationary (with some loose heuristic)
|
||||||
|
|
||||||
|
TypingSelectState = ImGuiTypingSelectState(), -- State for GetTypingSelectRequest()
|
||||||
|
|
||||||
InputTextState = ImGuiInputTextState(),
|
InputTextState = ImGuiInputTextState(),
|
||||||
InputTextLineIndex = ImGuiTextIndex(), -- Temporary storage
|
InputTextLineIndex = ImGuiTextIndex(), -- Temporary storage
|
||||||
InputTextDeactivatedState = ImGuiInputTextDeactivatedState(),
|
InputTextDeactivatedState = ImGuiInputTextDeactivatedState(),
|
||||||
@@ -2249,6 +2437,13 @@ function ImGuiContext(shared_font_atlas) -- TODO: tidy up / complete this struct
|
|||||||
CurrentTabBarStack = ImVector(), -- holds ImGuiTabBar references directly (no ImGuiPtrOrIndex needed in Lua)
|
CurrentTabBarStack = ImVector(), -- holds ImGuiTabBar references directly (no ImGuiPtrOrIndex needed in Lua)
|
||||||
ShrinkWidthBuffer = ImVector(), -- ImGuiShrinkWidthItem
|
ShrinkWidthBuffer = ImVector(), -- ImGuiShrinkWidthItem
|
||||||
|
|
||||||
|
-- Multi-Select state
|
||||||
|
BoxSelectState = ImGuiBoxSelectState(),
|
||||||
|
CurrentMultiSelect = nil,
|
||||||
|
MultiSelectTempDataStacked = 0, -- Temporary multi-select data size (because we leave previous instances undestructed, we generally don't use MultiSelectTempData.Size)
|
||||||
|
MultiSelectTempData = ImVector(), -- ImVector<ImGuiMultiSelectTempData>, 1-based
|
||||||
|
MultiSelectStorage = ImPool(ImGuiMultiSelectState), -- ImPool<ImGuiMultiSelectState>
|
||||||
|
|
||||||
WindowResizeBorderExpectedRect = ImRect(), -- Expected border rect, switch to relative edit if moving
|
WindowResizeBorderExpectedRect = ImRect(), -- Expected border rect, switch to relative edit if moving
|
||||||
WindowResizeRelativeMode = false,
|
WindowResizeRelativeMode = false,
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1539,7 +1539,7 @@ function ImGui.TableUpdateLayout(table_)
|
|||||||
|
|
||||||
local inner_window = table_.InnerWindow
|
local inner_window = table_.InnerWindow
|
||||||
local bs = g.BoxSelectState
|
local bs = g.BoxSelectState
|
||||||
if bs and bs.Window == inner_window and bs.UnclipMode then
|
if bs.Window == inner_window and bs.UnclipMode then
|
||||||
ImGui.TableApplyExternalUnclipRect(table_, bs.UnclipRect)
|
ImGui.TableApplyExternalUnclipRect(table_, bs.UnclipRect)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+1329
-4
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@ 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"
|
||||||
|
"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"
|
||||||
"tables|OK|$R --main tools/test/scripts/t_tables.luau --frames 150"
|
"tables|OK|$R --main tools/test/scripts/t_tables.luau --frames 150"
|
||||||
|
|||||||
@@ -0,0 +1,265 @@
|
|||||||
|
-- Multi-select / box-select / typing-select: ImGuiSelectionBasicStorage + Selectable list (click, Ctrl+click, Shift+click, Ctrl+A,
|
||||||
|
-- Escape, box-select drag, keyboard nav + Shift, typing-select), ImGuiListClipper + IncludeItemByIndex(RangeSrcItem),
|
||||||
|
-- ImGuiSelectionExternalStorage on a bool array, checkboxes and tree nodes inside a multi-select scope.
|
||||||
|
local G = require(game:GetService("ReplicatedStorage"):WaitForChild("ImGui"))
|
||||||
|
local ImGui, ImVec2 = G.ImGui, G.ImVec2
|
||||||
|
local MSF = G.ImGuiMultiSelectFlags
|
||||||
|
ImGui.CreateContext(); G.ImGui_ImplRoblox.Init()
|
||||||
|
local io = ImGui.GetIO()
|
||||||
|
io.ConfigFlags = bit32.bor(io.ConfigFlags, G.ImGuiConfigFlags.NavEnableKeyboard)
|
||||||
|
local failed = {}
|
||||||
|
local function check(ok, msg) if not ok then table.insert(failed, msg); print("FAIL " .. msg) end end
|
||||||
|
|
||||||
|
local NAMES = { "Apple", "Apricot", "Banana", "Blueberry", "Cherry", "Coconut", "Date", "Durian", "Elderberry", "Fig",
|
||||||
|
"Grape", "Guava", "Kiwi", "Lemon", "Lime", "Mango", "Melon", "Orange", "Papaya", "Peach" }
|
||||||
|
local N = #NAMES
|
||||||
|
|
||||||
|
-- Iterate with GetNextSelectedItem() (sorted by key) -> "a,b,c"
|
||||||
|
local function sel_str(sel)
|
||||||
|
local out, it, id, has_more = {}, nil, 0, false
|
||||||
|
while true do
|
||||||
|
has_more, it, id = sel:GetNextSelectedItem(it)
|
||||||
|
if not has_more then break end
|
||||||
|
table.insert(out, tostring(id))
|
||||||
|
end
|
||||||
|
return table.concat(out, ",")
|
||||||
|
end
|
||||||
|
local function bools_str(t, n)
|
||||||
|
local out = {}
|
||||||
|
for i = 1, n do if t[i] then table.insert(out, tostring(i - 1)) end end
|
||||||
|
return table.concat(out, ",")
|
||||||
|
end
|
||||||
|
|
||||||
|
local sel_list = G.ImGuiSelectionBasicStorage()
|
||||||
|
local sel_clip = G.ImGuiSelectionBasicStorage()
|
||||||
|
local sel_tree = G.ImGuiSelectionBasicStorage()
|
||||||
|
local ext_bools = {}
|
||||||
|
local sel_ext = G.ImGuiSelectionExternalStorage()
|
||||||
|
sel_ext.UserData = ext_bools
|
||||||
|
sel_ext.AdapterSetItemSelected = function(self, idx, selected) self.UserData[idx + 1] = selected end
|
||||||
|
local chk_bools = {}
|
||||||
|
local sel_chk = G.ImGuiSelectionExternalStorage()
|
||||||
|
sel_chk.UserData = chk_bools
|
||||||
|
sel_chk.AdapterSetItemSelected = function(self, idx, selected) self.UserData[idx + 1] = selected end
|
||||||
|
|
||||||
|
local rects = {} -- [name] = { min, max } (copies)
|
||||||
|
local ids = {} -- [name] = item id
|
||||||
|
local function rect() local a, b = ImGui.GetItemRectMin(), ImGui.GetItemRectMax(); return { ImVec2(a.x, a.y), ImVec2(b.x, b.y) } end
|
||||||
|
local function center(name) local r = rects[name]; return (r[1].x + r[2].x) / 2, (r[1].y + r[2].y) / 2 end
|
||||||
|
local function key(k) io:AddKeyEvent(k, true); io:AddKeyEvent(k, false) end
|
||||||
|
local function mods(ctrl, shift) io:AddKeyEvent(G.ImGuiMod_Ctrl, ctrl == true); io:AddKeyEvent(G.ImGuiMod_Shift, shift == true) end
|
||||||
|
|
||||||
|
-- Schedule: each step = { input = fn (before NewFrame), check = fn (after Render) }. Steps run on consecutive frames.
|
||||||
|
local steps = {}
|
||||||
|
local function step(input, chk) table.insert(steps, { input = input, check = chk }) end
|
||||||
|
local function idle(n) for _ = 1, n or 1 do step(nil, nil) end end
|
||||||
|
-- click: press (+mods) on frame A, release on frame B, then one idle frame for EndMultiSelect requests to be applied
|
||||||
|
local function click(name, ctrl, shift)
|
||||||
|
step(function() mods(ctrl, shift); io:AddMousePosEvent(center(name)); io:AddMouseButtonEvent(0, true) end)
|
||||||
|
step(function() io:AddMouseButtonEvent(0, false) end)
|
||||||
|
step(function() mods(false, false) end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local typed_focus_idx = -1
|
||||||
|
local clip_scroll_request = false
|
||||||
|
local f = 0
|
||||||
|
|
||||||
|
idle(3)
|
||||||
|
-- 1. List: click selects one
|
||||||
|
click("L2"); step(nil, function() check(sel_str(sel_list) == "2", "click: " .. sel_str(sel_list)) end)
|
||||||
|
-- 2. Ctrl+click toggles
|
||||||
|
click("L5", true); step(nil, function() check(sel_str(sel_list) == "2,5", "ctrl+click add: " .. sel_str(sel_list)) end)
|
||||||
|
click("L2", true); step(nil, function() check(sel_str(sel_list) == "5", "ctrl+click remove: " .. sel_str(sel_list)) end)
|
||||||
|
-- 3. Shift+click range (from RangeSrc = 2, the last Ctrl+clicked item)
|
||||||
|
click("L8", false, true); step(nil, function() check(sel_str(sel_list) == "2,3,4,5,6,7,8", "shift+click range: " .. sel_str(sel_list)) end)
|
||||||
|
-- 4. Ctrl+A
|
||||||
|
step(function() io:AddKeyEvent(G.ImGuiMod_Ctrl, true); io:AddKeyEvent(G.ImGuiKey.A, true) end)
|
||||||
|
step(function() io:AddKeyEvent(G.ImGuiKey.A, false); io:AddKeyEvent(G.ImGuiMod_Ctrl, false) end)
|
||||||
|
step(nil, function() check(sel_list.Size == N, "ctrl+A size " .. sel_list.Size) end)
|
||||||
|
-- 5. Escape clears (ClearOnEscape)
|
||||||
|
step(function() key(G.ImGuiKey.Escape) end)
|
||||||
|
step(nil, function() check(sel_list.Size == 0 and sel_str(sel_list) == "", "escape clear: " .. sel_str(sel_list)) end)
|
||||||
|
-- 6. Box-select drag (BoxSelect1d) from item 2 to item 5
|
||||||
|
step(function() io:AddMousePosEvent(center("L2")); io:AddMouseButtonEvent(0, true) end)
|
||||||
|
step(function() local x, y = center("L2"); io:AddMousePosEvent(x + 2, y + 10) end)
|
||||||
|
step(function() local x, y = center("L4"); io:AddMousePosEvent(x + 4, y) end)
|
||||||
|
step(function() local x, y = center("L5"); io:AddMousePosEvent(x + 4, y) end,
|
||||||
|
function() check(ImGui.GetCurrentContext().BoxSelectState.IsActive, "box-select active while dragging") end)
|
||||||
|
step(nil)
|
||||||
|
step(function() io:AddMouseButtonEvent(0, false) end)
|
||||||
|
step(nil, function() check(sel_str(sel_list) == "2,3,4,5", "box-select: " .. sel_str(sel_list)); check(not ImGui.GetCurrentContext().BoxSelectState.IsActive, "box-select ended") end)
|
||||||
|
-- 7. Keyboard nav: click 3, Down -> 4 (auto-select), Shift+Down x2 -> 4..6
|
||||||
|
click("L3"); step(nil, function() check(sel_str(sel_list) == "3", "click before nav: " .. sel_str(sel_list)) end)
|
||||||
|
step(function() key(G.ImGuiKey.DownArrow) end); idle(2)
|
||||||
|
step(nil, function() check(sel_str(sel_list) == "4", "nav down auto-select: " .. sel_str(sel_list)) end)
|
||||||
|
step(function() io:AddKeyEvent(G.ImGuiMod_Shift, true); key(G.ImGuiKey.DownArrow) end); idle(1)
|
||||||
|
step(function() key(G.ImGuiKey.DownArrow) end); idle(1)
|
||||||
|
step(function() io:AddKeyEvent(G.ImGuiMod_Shift, false) end); idle(1)
|
||||||
|
step(nil, function() check(sel_str(sel_list) == "4,5,6", "shift+nav range: " .. sel_str(sel_list)) end)
|
||||||
|
-- 8. Typing-select: "ch" -> Cherry (5), then single-char mode "b" "b" -> Banana (2) then Blueberry (3)
|
||||||
|
step(function() io:AddInputCharacter(string.byte("c")); io:AddInputCharacter(string.byte("h")) end); idle(2)
|
||||||
|
step(nil, function() check(ImGui.GetCurrentContext().NavId == ids.L4, "typing 'ch' -> Cherry"); check(sel_str(sel_list) == "4", "typing focus selects: " .. sel_str(sel_list)) end)
|
||||||
|
idle(120) -- TYPING_SELECT_RESET_TIMER
|
||||||
|
step(function() io:AddInputCharacter(string.byte("b")) end); idle(2)
|
||||||
|
step(nil, function() check(ImGui.GetCurrentContext().NavId == ids.L2, "typing 'b' -> Banana") end)
|
||||||
|
step(function() io:AddInputCharacter(string.byte("b")) end); idle(2)
|
||||||
|
step(nil, function() check(ImGui.GetCurrentContext().NavId == ids.L3, "typing 'bb' -> Blueberry") end)
|
||||||
|
idle(120)
|
||||||
|
|
||||||
|
-- 9. Clipper (1000 items): click 5, scroll down, Shift+click item 40 -> 5..40 (RangeSrcItem 5 kept submitted by IncludeItemByIndex)
|
||||||
|
click("C5")
|
||||||
|
-- move NavId away with Ctrl+Down (no selection change, RangeSrc stays 5) so the clipper doesn't keep item 5 alive as the nav item
|
||||||
|
step(function() io:AddKeyEvent(G.ImGuiMod_Ctrl, true); key(G.ImGuiKey.DownArrow) end); idle(1)
|
||||||
|
step(function() key(G.ImGuiKey.DownArrow) end); idle(1)
|
||||||
|
step(function() key(G.ImGuiKey.DownArrow) end); idle(1)
|
||||||
|
step(function() io:AddKeyEvent(G.ImGuiMod_Ctrl, false) end)
|
||||||
|
step(nil, function() check(sel_str(sel_clip) == "5", "clipper ctrl+nav keeps selection: " .. sel_str(sel_clip)) end)
|
||||||
|
step(function() clip_scroll_request = true end); idle(2)
|
||||||
|
step(nil, function() check(rects.C40 ~= nil and rects.C5 == nil, "clipper scrolled (item 5 not visible)") end)
|
||||||
|
click("C40", false, true)
|
||||||
|
step(nil, function() check(sel_clip.Size == 36, "clipper shift+click range size " .. sel_clip.Size); check(sel_clip:Contains(5) and sel_clip:Contains(40) and not sel_clip:Contains(4) and not sel_clip:Contains(41), "clipper range bounds") end)
|
||||||
|
|
||||||
|
-- 10. External storage on bool array: click 1, Shift+click 3, Ctrl+click 2
|
||||||
|
click("E1"); click("E3", false, true)
|
||||||
|
step(nil, function() check(bools_str(ext_bools, 10) == "1,2,3", "external storage range: " .. bools_str(ext_bools, 10)) end)
|
||||||
|
click("E2", true)
|
||||||
|
step(nil, function() check(bools_str(ext_bools, 10) == "1,3", "external storage ctrl+click: " .. bools_str(ext_bools, 10)) end)
|
||||||
|
|
||||||
|
-- 11. Checkboxes (NoAutoSelect|NoAutoClear): click 1 toggles on, Shift+click 4 -> 1..4 on, click 2 toggles off
|
||||||
|
click("K1"); step(nil, function() check(bools_str(chk_bools, 8) == "1", "checkbox click: " .. bools_str(chk_bools, 8)) end)
|
||||||
|
click("K4", false, true); step(nil, function() check(bools_str(chk_bools, 8) == "1,2,3,4", "checkbox shift+click: " .. bools_str(chk_bools, 8)) end)
|
||||||
|
click("K2"); step(nil, function() check(bools_str(chk_bools, 8) == "1,3,4", "checkbox toggle off: " .. bools_str(chk_bools, 8)) end)
|
||||||
|
|
||||||
|
-- 12. Tree nodes: click 0, Ctrl+click 2, Shift+click 4 (range from 2)
|
||||||
|
click("T0"); click("T2", true)
|
||||||
|
step(nil, function() check(sel_str(sel_tree) == "0,2", "tree ctrl+click: " .. sel_str(sel_tree)) end)
|
||||||
|
click("T4", false, true)
|
||||||
|
step(nil, function() check(sel_str(sel_tree) == "2,3,4", "tree shift+click: " .. sel_str(sel_tree)) end)
|
||||||
|
|
||||||
|
-- 13. Metrics window renders the TypingSelect / MultiSelect debug nodes
|
||||||
|
local show_metrics = false
|
||||||
|
step(function() show_metrics = true end); idle(3)
|
||||||
|
step(nil, function() if #failed == 0 then print("MULTISELECT OK") end end)
|
||||||
|
|
||||||
|
local function list_window()
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(10, 10)); ImGui.SetNextWindowSize(ImVec2(200, 420))
|
||||||
|
ImGui.Begin("L")
|
||||||
|
local flags = bit32.bor(MSF.ClearOnEscape, MSF.BoxSelect1d)
|
||||||
|
local ms_io = ImGui.BeginMultiSelect(flags, sel_list.Size, N)
|
||||||
|
sel_list:ApplyRequests(ms_io)
|
||||||
|
-- typing-select
|
||||||
|
local focus_idx = -1
|
||||||
|
if ImGui.IsWindowFocused() then
|
||||||
|
local req = ImGui.GetTypingSelectRequest(G.ImGuiTypingSelectFlags.AllowSingleCharMode)
|
||||||
|
local nav_idx = (type(ms_io.NavIdItem) == "number") and ms_io.NavIdItem or -1
|
||||||
|
focus_idx = ImGui.TypingSelectFindMatch(req, N, function(_, idx) return NAMES[idx + 1] end, nil, nav_idx)
|
||||||
|
end
|
||||||
|
for n = 0, N - 1 do
|
||||||
|
if n == focus_idx then ImGui.SetKeyboardFocusHere() end
|
||||||
|
ImGui.SetNextItemSelectionUserData(n)
|
||||||
|
ImGui.Selectable(NAMES[n + 1], sel_list:Contains(n))
|
||||||
|
rects["L" .. n] = rect(); ids["L" .. n] = ImGui.GetItemID()
|
||||||
|
end
|
||||||
|
ms_io = ImGui.EndMultiSelect()
|
||||||
|
sel_list:ApplyRequests(ms_io)
|
||||||
|
ImGui.End()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clipper_window()
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(220, 10)); ImGui.SetNextWindowSize(ImVec2(200, 300))
|
||||||
|
ImGui.Begin("C")
|
||||||
|
if clip_scroll_request then ImGui.SetScrollY(ImGui.GetTextLineHeightWithSpacing() * 30); clip_scroll_request = false end
|
||||||
|
local COUNT = 1000
|
||||||
|
local ms_io = ImGui.BeginMultiSelect(MSF.ClearOnEscape, sel_clip.Size, COUNT)
|
||||||
|
sel_clip:ApplyRequests(ms_io)
|
||||||
|
local clipper = G.ImGuiListClipper()
|
||||||
|
clipper:Begin(COUNT)
|
||||||
|
if ms_io.RangeSrcItem ~= -1 then clipper:IncludeItemByIndex(ms_io.RangeSrcItem) end -- Ensure RangeSrc item is not clipped.
|
||||||
|
for k in rects do if string.sub(k, 1, 1) == "C" then rects[k] = nil end end
|
||||||
|
while clipper:Step() do
|
||||||
|
for n = clipper.DisplayStart, clipper.DisplayEnd - 1 do
|
||||||
|
ImGui.SetNextItemSelectionUserData(n)
|
||||||
|
ImGui.Selectable(("Object %04d"):format(n), sel_clip:Contains(n))
|
||||||
|
if ImGui.IsItemVisible() then rects["C" .. n] = rect() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ms_io = ImGui.EndMultiSelect()
|
||||||
|
sel_clip:ApplyRequests(ms_io)
|
||||||
|
ImGui.End()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function external_window()
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(430, 10)); ImGui.SetNextWindowSize(ImVec2(180, 220))
|
||||||
|
ImGui.Begin("E")
|
||||||
|
local ms_io = ImGui.BeginMultiSelect(MSF.None, -1, 10)
|
||||||
|
sel_ext:ApplyRequests(ms_io)
|
||||||
|
for n = 0, 9 do
|
||||||
|
ImGui.SetNextItemSelectionUserData(n)
|
||||||
|
ImGui.Selectable("Ext " .. n, ext_bools[n + 1] == true)
|
||||||
|
rects["E" .. n] = rect()
|
||||||
|
end
|
||||||
|
ms_io = ImGui.EndMultiSelect()
|
||||||
|
sel_ext:ApplyRequests(ms_io)
|
||||||
|
ImGui.End()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function checkbox_window()
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(430, 240)); ImGui.SetNextWindowSize(ImVec2(180, 200))
|
||||||
|
ImGui.Begin("K")
|
||||||
|
local ms_io = ImGui.BeginMultiSelect(bit32.bor(MSF.NoAutoSelect, MSF.NoAutoClear, MSF.ClearOnEscape), -1, 8)
|
||||||
|
sel_chk:ApplyRequests(ms_io)
|
||||||
|
for n = 0, 7 do
|
||||||
|
ImGui.SetNextItemSelectionUserData(n)
|
||||||
|
local _, v = ImGui.Checkbox("Check " .. n, chk_bools[n + 1] == true)
|
||||||
|
rects["K" .. n] = rect()
|
||||||
|
local _ = v -- the selection is updated through requests (ApplyRequests), like upstream's demo
|
||||||
|
end
|
||||||
|
ms_io = ImGui.EndMultiSelect()
|
||||||
|
sel_chk:ApplyRequests(ms_io)
|
||||||
|
ImGui.End()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function tree_window()
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(220, 320)); ImGui.SetNextWindowSize(ImVec2(200, 160))
|
||||||
|
ImGui.Begin("T")
|
||||||
|
local ms_io = ImGui.BeginMultiSelect(MSF.None, sel_tree.Size, 5)
|
||||||
|
sel_tree:ApplyRequests(ms_io)
|
||||||
|
for n = 0, 4 do
|
||||||
|
local flags = bit32.bor(G.ImGuiTreeNodeFlags.Leaf, G.ImGuiTreeNodeFlags.NoTreePushOnOpen, G.ImGuiTreeNodeFlags.SpanAvailWidth)
|
||||||
|
if sel_tree:Contains(n) then flags = bit32.bor(flags, G.ImGuiTreeNodeFlags.Selected) end
|
||||||
|
ImGui.SetNextItemSelectionUserData(n)
|
||||||
|
ImGui.TreeNodeEx("Node " .. n, flags)
|
||||||
|
rects["T" .. n] = rect()
|
||||||
|
end
|
||||||
|
ms_io = ImGui.EndMultiSelect()
|
||||||
|
sel_tree:ApplyRequests(ms_io)
|
||||||
|
ImGui.End()
|
||||||
|
end
|
||||||
|
|
||||||
|
game:GetService("RunService").Stepped:Connect(function()
|
||||||
|
f += 1
|
||||||
|
G.ImGui_ImplRoblox.NewFrame()
|
||||||
|
local s = steps[f]
|
||||||
|
if s and s.input then s.input() end
|
||||||
|
ImGui.NewFrame()
|
||||||
|
list_window()
|
||||||
|
clipper_window()
|
||||||
|
external_window()
|
||||||
|
checkbox_window()
|
||||||
|
tree_window()
|
||||||
|
if show_metrics then
|
||||||
|
ImGui.SetNextWindowPos(ImVec2(620, 10)); ImGui.SetNextWindowSize(ImVec2(400, 600))
|
||||||
|
ImGui.ShowMetricsWindow()
|
||||||
|
local ctx = ImGui.GetCurrentContext()
|
||||||
|
ImGui.Begin("DebugNodes")
|
||||||
|
ImGui.DebugNodeTypingSelectState(ctx.TypingSelectState)
|
||||||
|
for n = 0, ctx.MultiSelectStorage:GetMapSize() - 1 do
|
||||||
|
local st = ctx.MultiSelectStorage:GetByIndex(n)
|
||||||
|
if st then ImGui.SetNextItemOpen(true); ImGui.DebugNodeMultiSelectState(st) end
|
||||||
|
end
|
||||||
|
ImGui.End()
|
||||||
|
end
|
||||||
|
ImGui.Render(); G.ImGui_ImplRoblox.RenderDrawData(ImGui.GetDrawData())
|
||||||
|
if s and s.check then s.check() end
|
||||||
|
end)
|
||||||
|
print(("t_multiselect: %d steps"):format(#steps))
|
||||||
Reference in New Issue
Block a user