-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathimgui_internal.lua
More file actions
2769 lines (2287 loc) · 90.1 KB
/
Copy pathimgui_internal.lua
File metadata and controls
2769 lines (2287 loc) · 90.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
--- Some internal structures
-- I will avoid extensive type checks, since I ensure that types are correct in internal usage,
-- and runtime type checking is probably slow
--- @meta
--- @alias ImGuiTableColumnIdx ImS16
-- TODO: Implement actual ImString type
--- @alias ImString char[]|string
--- @alias ImStringBuffer char[]
--- @type ImGuiContext?
local GImGui
-- Sets local `GImGui` in this file(imgui_internal.lua).
-- This is currently only used in main code `ImGui.SetCurrentContext()`
--- @param ctx ImGuiContext?
function ImGui._SetCurrentContext_Internal(ctx)
GImGui = ctx
end
local setmetatable = setmetatable
local MT = ImGui.GetMetatables()
IM_TABSIZE = 4
FLT_MIN = 1.1754943508223e-38
FLT_MAX = 3.4028234663853e+38
DBL_MAX = 1.7976931348623e+308
INT_MIN = -0x7fffffff - 1
INT_MAX = 0x7fffffff
UINT_MAX = 0x7fffffff * 2 + 1
IM_PI = math.pi
ImPow = math.pow
ImLog = math.log
ImAbs = math.abs
ImFabs = math.abs
ImFmod = function(a, b) if b < 0 then b = -b end; if a < 0 then return -(-a % b) else return a % b end; end
ImMin = math.min
--- @param a ImVec2
--- @param b ImVec2
--- @return ImVec2
--- @nodiscard
function ImMinVec2(a, b) return ImVec2(ImMin(a.x, b.x), ImMin(a.y, b.y)) end
ImMax = math.max
--- @param a ImVec2
--- @param b ImVec2
--- @return ImVec2
--- @nodiscard
function ImMaxVec2(a, b) return ImVec2(ImMax(a.x, b.x), ImMax(a.y, b.y)) end
ImRound64 = function(val) return math.floor(val + 0.5) end -- FIXME: Positive values only
ImCeil = math.ceil
ImSin = math.sin
ImCos = math.cos
ImAcos = math.acos
ImAtan2 = math.atan2
ImSqrt = math.sqrt
--- @generic T: number
--- @param a T
--- @param b T
--- @param mn T
--- @param mx T
--- @return T
function ImAddClampOverflow(a, b, mn, mx)
if b < 0 and (a < mn - b) then return mn end
if b > 0 and (a > mx - b) then return mx end
return a + b
end
--- @generic T: number
--- @param a T
--- @param b T
--- @param mn T
--- @param mx T
--- @return T
function ImSubClampOverflow(a, b, mn, mx)
if b > 0 and (a < mn + b) then return mn end
if b < 0 and (a > mx + b) then return mx end
return a - b
end
--- @param base table
--- @param count int
--- @param cmp_func fun(lhs, rhs): bool
ImStd.ImQsort = function(base, count, cmp_func) if count > 0 then table.sort(base, cmp_func) end end
--- @param a number
--- @param b number
--- @param t number
function ImLerp(a, b, t) return ((a) + ((b) - (a)) * (t)) end
--- @param a ImVec2
--- @param b ImVec2
--- @param t float
function ImLerpV2V2(a, b, t)
return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t)
end
--- @param a ImVec2
--- @param b ImVec2
--- @param t ImVec2
--- @return ImVec2
--- @nodiscard
function ImLerpV2V2V2(a, b, t) return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y) end
--- @param a ImVec4
--- @param b ImVec4
--- @param t float
--- @nodiscard
function ImLerpV4V4(a, b, t) return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t) end
--- @param v number
--- @param min number
--- @param max number
function ImClamp(v, min, max) return ImMin(ImMax(v, min), max) end
--- @param v ImVec2
--- @param min ImVec2
--- @param max ImVec2
--- @return ImVec2
--- @nodiscard
function ImClampV2(v, min, max) return ImVec2(ImMin(ImMax(v.x, min.x), max.x), ImMin(ImMax(v.y, min.y), max.y)) end
--- @param f number
function ImTrunc(f) if f >= 0 then return math.floor(f) else return math.ceil(f) end end
--- @param v ImVec2
--- @nodiscard
function ImTruncV2(v) return ImVec2(ImTrunc(v.x), ImTrunc(v.y)) end
--- @param f float
function ImTrunc64(f) return ImTrunc(f) end
--- @param f float
function ImCeilFast(f)
local i
if f >= 0 then i = math.floor(f) else i = math.ceil(f) end -- same as `ImTrunc()`
if f > i then return i + 1 end
return i
end
function IM_ROUNDUP_TO_EVEN(n) return (ImCeil((n) / 2) * 2) end
function ImRsqrt(x) return (1 / ImSqrt(x)) end
function IM_TRUNC(VAL) return math.floor(VAL) end -- Positive values only!
function IM_ROUND(VAL) return math.floor(VAL + 0.5) end
function ImFloor(f) if f >= 0 or math.floor(f) == f then return math.floor(f) else return math.floor(f) - 1 end end
--- @param v int
function ImIsPowerOfTwo(v)
return (v ~= 0) and (bit.band(v, (v - 1)) == 0)
end
function ImUpperPowerOfTwo(v)
if v <= 0 then return 0 end
if v <= 1 then return 1 end
v = v - 1
v = bit.bor(v, bit.rshift(v, 1))
v = bit.bor(v, bit.rshift(v, 2))
v = bit.bor(v, bit.rshift(v, 4))
v = bit.bor(v, bit.rshift(v, 8))
v = bit.bor(v, bit.rshift(v, 16))
return v + 1
end
--- @param avg float
--- @param sample float
--- @param n int
--- @return float
function ImStd.ImExponentialMovingAverage(avg, sample, n)
avg = avg - avg / n
avg = avg + sample / n
return avg
end
-- Uses `string.match` internally
--- @param str string
function ImAtof(str)
return tonumber(string.match(str, "[+-]?%d*%.?%d+"))
end
--- @param s table # 1-based
--- @param c any
--- @param n int
function ImStd.memset(s, c, n)
for i = 1, n do s[i] = c end
end
do
local _memmove = function(dest, dest_start, src, src_start, count)
if count <= 0 then return end
-- more compact instead of writing separate if-else and for loops
local c = (dest == src and dest_start >= src_start)
for i = (c and count - 1 or 0), (c and 0 or count - 1), (c and -1 or 1) do
dest[dest_start + i] = src[src_start + i]
end
end
if table.move then
--- [GMod] Platform specific: the `table.move` polyfill in non-x86-64 currently uses `unpack` which will break if too many elements
-- Remove this check when the polyfill is fixed or removed
if not gmod or (gmod and BRANCH == "x86-64") then
_memmove = function(dest, dest_start, src, src_start, count)
table.move(src, src_start, src_start + count - 1, dest_start, dest)
end
end
end
ImStd.memmove = _memmove
end
--- @param str1 ImStringBuffer
--- @param str2 ImStringBuffer
function ImStd.strcmp(str1, str2)
local i = 1
while true do
local c1 = str1[i] or 0
local c2 = str2[i] or 0
if c1 ~= c2 then
return c1 - c2
end
if c1 == 0 then
return 0
end
i = i + 1
end
end
--- @param str1 ImStringBuffer
--- @param str2 ImStringBuffer
--- @param max_count int
function ImStd.strncmp(str1, str2, max_count)
for i = 1, max_count do
local c1 = str1[i] or 0
local c2 = str2[i] or 0
if c1 ~= c2 then
return c1 - c2
end
if c1 == 0 then
return 0
end
end
return 0
end
function ImSaturate(f) return ((f < 0.0 and 0.0) or (f > 1.0 and 1.0) or f) end
IM_F32_TO_INT8_UNBOUND = function(val) return math.floor(val * 255.0 + (val >= 0 and 0.5 or -0.5)) end
IM_F32_TO_INT8_SAT = function(val) return math.floor(ImSaturate(val) * 255.0 + 0.5) end
--- @param s ImString
--- @param i int
--- @return char
function ImStrByte(s, i)
if type(s) == "string" then
return string.byte(s, i, i)
else --- @cast s char[]
return s[i]
end
end
--- @class ImGuiColorMod
--- @field Col ImGuiCol
--- @field BackupValue ImVec4
--- @param col ImGuiCol
--- @param backup_value ImVec4
--- @return ImGuiColorMod
function ImGuiColorMod(col, backup_value)
local this = {
Col = col,
BackupValue = ImVec4()
}
ImVec4_Copy(this.BackupValue, backup_value)
return this
end
--- @param lhs ImVec2
--- @return float
function ImLengthSqr(lhs) return (lhs.x * lhs.x) + (lhs.y * lhs.y) end
--- @param v ImVec2
--- @param cos_a float
--- @param sin_a float
--- @return ImVec2
--- @nodiscard
function ImRotate(v, cos_a, sin_a)
return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a)
end
--- @param a ImVec2
--- @param b ImVec2
function ImDot(a, b)
return a.x * b.x + a.y * b.y
end
--- @param lhs ImVec2
--- @param rhs ImVec2
--- @nodiscard
function ImMul(lhs, rhs)
return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y)
end
--- @param str char[]
--- @param begin? int
function ImStd.ImStrlen(str, begin)
if begin == nil then begin = 1 end
local l = #str
for i = begin, l do
if str[i] == 0 then
return i - begin
end
end
IM_ASSERT(false)
end
-- FIXME: should also accept count?
-- FIXME: avoid dynamic type checking?
-- string.find with patterns disabled
--- @param str string|char[]
--- @param s string|char
--- @param start_pos? int
--- @return int?
function ImMemchr(str, s, start_pos)
local start = start_pos or 1
if start < 1 then start = 1 end
if type(str) == "table" then
for i = start, #str do
if str[i] == 0 then break end
if str[i] == s then
return i
end
end
return nil
end
--- @cast str string
local pos = string.find(str, s, start, true)
return pos
end
IMGUI_FONT_SIZE_MAX = 512.0
IMGUI_FONT_SIZE_THRESHOLD_FOR_LOADADVANCEXONLYMODE = 128.0
IMGUI_WINDOW_HARD_MIN_SIZE = 4.0
IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN = 4
IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX = 512
IM_DRAWLIST_ARCFAST_TABLE_SIZE = 48
IM_DRAWLIST_ARCFAST_SAMPLE_MAX = IM_DRAWLIST_ARCFAST_TABLE_SIZE
function IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD, _MAXERROR) return ImClamp(IM_ROUNDUP_TO_EVEN(ImCeil(IM_PI / ImAcos(1 - ImMin((_MAXERROR), (_RAD)) / (_RAD)))), IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX) end
function IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(_N, _MAXERROR) return ((_MAXERROR) / (1 - ImCos(IM_PI / ImMax(_N, IM_PI)))) end
function IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_ERROR(_N, _RAD) return ((1 - ImCos(IM_PI / ImMax((_N), IM_PI))) / (_RAD)) end
function IM_ASSERT_USER_ERROR(_EXPR, _MSG) if not (_EXPR) or (_EXPR) == 0 then error(_MSG, 2) end end
function IM_ASSERT_USER_ERROR_RET(_EXPR, _MSG) if not (_EXPR) or (_EXPR) == 0 then error(_MSG, 2) end end
function IMGUI_DEBUG_LOG_ACTIVEID(_str, ...) local g = GImGui if bit.band(g.DebugLogFlags, ImGuiDebugLogFlags.EventActiveId) ~= 0 then print(string.format(_str, ...)) end end
function IMGUI_DEBUG_LOG_POPUP(_str, ...) local g = GImGui if bit.band(g.DebugLogFlags, ImGuiDebugLogFlags.EventPopup) ~= 0 then print(string.format(_str, ...)) end end
function IMGUI_DEBUG_LOG_FONT(_str, ...) local g2 = GImGui if g2 and bit.band(g2.DebugLogFlags, ImGuiDebugLogFlags.EventFont) ~= 0 then print(string.format(_str, ...)) end end
function IMGUI_DEBUG_LOG_VIEWPORT(_str, ...) local g = GImGui if bit.band(g.DebugLogFlags, ImGuiDebugLogFlags.EventViewport) ~= 0 then print(string.format(_str, ...)) end end
ImGuiSelectionUserData_Invalid = -1
ImGuiKeyOwner_Any = 0
ImGuiKeyOwner_NoOwner = 4294967295
--- @param button ImGuiMouseButton
--- @return ImGuiKey
function ImGui.MouseButtonToKey(button) IM_ASSERT(button >= 0 and button < ImGuiMouseButton.COUNT) return ImGuiKey.MouseLeft + button end
--- @param key ImGuiKey
function ImGui.IsNamedKey(key)
return key >= ImGuiKey.NamedKey_BEGIN and key < ImGuiKey.NamedKey_END
end
--- @param key ImGuiKey
function ImGui.IsKeyboardKey(key)
return key >= ImGuiKey_Keyboard_BEGIN and key < ImGuiKey_Keyboard_END
end
--- @param key ImGuiKey
function ImGui.IsGamepadKey(key)
return key >= ImGuiKey_Gamepad_BEGIN and key < ImGuiKey_Gamepad_END
end
--- @param key ImGuiKey
function ImGui.IsMouseKey(key)
return key >= ImGuiKey_Mouse_BEGIN and key < ImGuiKey_Mouse_END
end
--- @param key ImGuiKey
function ImGui.IsAliasKey(key)
return key >= ImGuiKey_Aliases_BEGIN and key < ImGuiKey_Aliases_END
end
--- @param key ImGuiKey
function ImGui.IsLRModKey(key)
return key >= ImGuiKey.LeftCtrl and key <= ImGuiKey.RightSuper
end
--- @param key ImGuiKey
--- @return bool
function ImGui.IsNamedKeyOrMod(key)
return (key >= ImGuiKey.NamedKey_BEGIN and key < ImGuiKey.NamedKey_END) or key == ImGuiMod_Ctrl or key == ImGuiMod_Shift or key == ImGuiMod_Alt or key == ImGuiMod_Super
end
--- @param key ImGuiKey
--- @return ImGuiKey
function ImGui.ConvertSingleModFlagToKey(key)
if key == ImGuiMod_Ctrl then
return ImGuiKey.ReservedForModCtrl
elseif key == ImGuiMod_Shift then
return ImGuiKey.ReservedForModShift
elseif key == ImGuiMod_Alt then
return ImGuiKey.ReservedForModAlt
elseif key == ImGuiMod_Super then
return ImGuiKey.ReservedForModSuper
end
return key
end
--- @param ctx ImGuiContext
--- @param key ImGuiKey
function ImGui.GetKeyOwnerData(ctx, key)
if bit.band(key, ImGuiMod_Mask_) ~= 0 then key = ImGui.ConvertSingleModFlagToKey(key) end
IM_ASSERT(ImGui.IsNamedKey(key))
return ctx.KeysOwnerData[key - ImGuiKey.NamedKey_BEGIN]
end
--- @class ImGuiKeyOwnerData
--- @return ImGuiKeyOwnerData
--- @nodiscard
function ImGuiKeyOwnerData()
return {
OwnerCurr = ImGuiKeyOwner_NoOwner,
OwnerNext = ImGuiKeyOwner_NoOwner,
LockThisFrame = false,
LockUntilRelease = false
}
end
--- @param size float
--- @return float
function ImGui.GetRoundedFontSize(size) return IM_ROUND(size) end
--- @param window ImGuiWindow
--- @param r ImRect
--- @return ImRect
--- @nodiscard
function ImGui.WindowRectAbsToRel(window, r) local off = window.DC.CursorStartPos return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y) end
--- @param window ImGuiWindow
--- @param p ImVec2
--- @return ImVec2
--- @nodiscard
function ImGui.WindowPosAbsToRel(window, p) local off = window.DC.CursorStartPos return ImVec2(p.x - off.x, p.y - off.y) end
--- @param c char
--- @return bool # True if this character is a ' ' or '\t'
function ImCharIsBlankA(c) return c == 32 or c == 9 end
--- @param c char
function ImCharIsBlankW(c) return c == 32 or c == 9 or c == 0x3000 end
--- @enum ImGuiNavMoveFlags
ImGuiNavMoveFlags = {
None = 0,
LoopX = bit.lshift(1, 0),
LoopY = bit.lshift(1, 1),
WrapX = bit.lshift(1, 2),
WrapY = bit.lshift(1, 3),
AllowCurrentNavId = bit.lshift(1, 4),
AlsoScoreVisibleSet = bit.lshift(1, 5),
ScrollToEdgeY = bit.lshift(1, 6),
Forwarded = bit.lshift(1, 7),
DebugNoResult = bit.lshift(1, 8),
FocusApi = bit.lshift(1, 9),
IsTabbing = bit.lshift(1, 10),
IsPageMove = bit.lshift(1, 11),
Activate = bit.lshift(1, 12),
NoSelect = bit.lshift(1, 13),
NoSetNavCursorVisible = bit.lshift(1, 14),
NoClearActiveId = bit.lshift(1, 15),
}
ImGuiNavMoveFlags.WrapMask_ = bit.bor(ImGuiNavMoveFlags.LoopX, ImGuiNavMoveFlags.LoopY, ImGuiNavMoveFlags.WrapX, ImGuiNavMoveFlags.WrapY)
--- @enum ImGuiNavLayer
ImGuiNavLayer = {
Main = 0,
Menu = 1,
COUNT = 2
}
ImGuiItemFlags.ReadOnly = bit.lshift(1, 11)
ImGuiItemFlags.MixedValue = bit.lshift(1, 12)
ImGuiItemFlags.NoWindowHoverableCheck = bit.lshift(1, 13)
ImGuiItemFlags.AllowOverlap = bit.lshift(1, 14)
ImGuiItemFlags.NoNavDisableMouseHover = bit.lshift(1, 15)
ImGuiItemFlags.NoMarkEdited = bit.lshift(1, 16)
ImGuiItemFlags.NoFocus = bit.lshift(1, 17)
ImGuiItemFlags.Inputable = bit.lshift(1, 20)
ImGuiItemFlags.HasSelectionUserData = bit.lshift(1, 21)
ImGuiItemFlags.IsMultiSelect = bit.lshift(1, 22)
ImGuiItemFlags.Default_ = ImGuiItemFlags.AutoClosePopups
--- @enum ImDrawTextFlags
ImDrawTextFlags = {
None = 0,
CpuFineClip = bit.lshift(1, 0),
WrapKeepBlanks = bit.lshift(1, 1),
StopOnNewLine = bit.lshift(1, 2)
}
--- @enum ImGuiFocusRequestFlags
ImGuiFocusRequestFlags = {
None = 0,
RestoreFocusedChild = bit.lshift(1, 0),
UnlessBelowModal = bit.lshift(1, 1)
}
--- @enum ImGuiTextFlags
ImGuiTextFlags = {
None = 0,
NoWidthForLargeClippedText = bit.lshift(1, 0)
}
--- @enum ImWcharClass
ImWcharClass = {
Blank = 0,
Punct = 1,
Other = 2
}
--- @class ImVec1
--- @field x number
MT.ImVec1 = {}
MT.ImVec1.__index = MT.ImVec1
local function ImVec1(x) return setmetatable({x = x or 0}, MT.ImVec1) end
function MT.ImVec1:__tostring() return string.format("ImVec1(%g)", self.x) end
--- @param dest ImVec1
--- @param src ImVec1
function ImVec1_Copy(dest, src)
dest.x = src.x
end
--- @class ImRect
--- @field Min ImVec2
--- @field Max ImVec2
MT.ImRect = {}
MT.ImRect.__index = MT.ImRect
--- @nodiscard
function ImRect(a, b, c, d) if c and d then return setmetatable({Min = ImVec2(a, b), Max = ImVec2(c, d)}, MT.ImRect) end return setmetatable({Min = ImVec2(a and a.x or 0, a and a.y or 0), Max = ImVec2(b and b.x or 0, b and b.y or 0)}, MT.ImRect) end
function MT.ImRect:__eq(other) return self.Min == other.Min and self.Max == other.Max end
function MT.ImRect:__tostring() return string.format("ImRect(Min: %g,%g, Max: %g,%g)", self.Min.x, self.Min.y, self.Max.x, self.Max.y) end
--- @param other ImRect
function MT.ImRect:Contains(other) return other.Min.x >= self.Min.x and other.Max.x <= self.Max.x and other.Min.y >= self.Min.y and other.Max.y <= self.Max.y end
--- @param p ImVec2
function MT.ImRect:ContainsV2(p) return p.x >= self.Min.x and p.y >= self.Min.y and p.x < self.Max.x and p.y < self.Max.y end
--- @param p ImVec2
--- @param pad ImVec2
function MT.ImRect:ContainsWithPad(p, pad)
return p.x >= self.Min.x - pad.x and p.y >= self.Min.y - pad.y and p.x < self.Max.x + pad.x and p.y < self.Max.y + pad.y
end
function MT.ImRect:Overlaps(other)
local min_x, min_y, max_x, max_y
if other.Min then
--- @cast other ImRect
min_x = other.Min.x; min_y = other.Min.y
max_x = other.Max.x; max_y = other.Max.y
elseif other.z then
--- @cast other ImVec4
min_x = other.x; min_y = other.y
max_x = other.z; max_y = other.w
else
IM_ASSERT(false)
end
return self.Min.x <= max_x and self.Max.x >= min_x and self.Min.y <= max_y and self.Max.y >= min_y
end
function MT.ImRect:GetCenter() return ImVec2((self.Min.x + self.Max.x) * 0.5, (self.Min.y + self.Max.y) * 0.5) end
function MT.ImRect:GetWidth() return self.Max.x - self.Min.x end
function MT.ImRect:GetHeight() return self.Max.y - self.Min.y end
function MT.ImRect:GetSize() return ImVec2(self.Max.x - self.Min.x, self.Max.y - self.Min.y) end
function MT.ImRect:GetTL() return ImVec2(self.Min.x, self.Min.y) end
function MT.ImRect:GetTR() return ImVec2(self.Max.x, self.Min.y) end
function MT.ImRect:GetBL() return ImVec2(self.Min.x, self.Max.y) end
function MT.ImRect:GetBR() return ImVec2(self.Max.x, self.Max.y) end
--- @param r ImRect|ImVec4
function MT.ImRect:ClipWith(r)
if r.Min then
--- @cast r ImRect
self.Min.x = ImMax(self.Min.x, r.Min.x) self.Min.y = ImMax(self.Min.y, r.Min.y)
self.Max.x = ImMin(self.Max.x, r.Max.x) self.Max.y = ImMin(self.Max.y, r.Max.y)
elseif r.z then
--- @cast r ImVec4
self.Min.x = ImMax(self.Min.x, r.x) self.Min.y = ImMax(self.Min.y, r.y)
self.Max.x = ImMin(self.Max.x, r.z) self.Max.y = ImMin(self.Max.y, r.w)
else
IM_ASSERT(false)
end
end
function MT.ImRect:ClipWithFull(r)
self.Min.x = ImClamp(self.Min.x, r.Min.x, r.Max.x) self.Min.y = ImClamp(self.Min.y, r.Min.y, r.Max.y)
self.Max.x = ImClamp(self.Max.x, r.Min.x, r.Max.x) self.Max.y = ImClamp(self.Max.y, r.Min.y, r.Max.y)
end
--- @param p ImRect|ImVec2
function MT.ImRect:Add(p)
if p.Min then
--- @cast p ImRect
self:Add(p.Min)
self:Add(p.Max)
else
--- @cast p ImVec2
if p.x < self.Min.x then self.Min.x = p.x end
if p.y < self.Min.y then self.Min.y = p.y end
if p.x > self.Max.x then self.Max.x = p.x end
if p.y > self.Max.y then self.Max.y = p.y end
end
end
--- @param amount float
function MT.ImRect:Expand(amount)
self.Min.x = self.Min.x - amount; self.Min.y = self.Min.y - amount
self.Max.x = self.Max.x + amount; self.Max.y = self.Max.y + amount
end
--- @param amount ImVec2
function MT.ImRect:ExpandV2(amount)
self.Min.x = self.Min.x - amount.x; self.Min.y = self.Min.y - amount.y
self.Max.x = self.Max.x + amount.x; self.Max.y = self.Max.y + amount.y
end
function MT.ImRect:ToVec4()
return ImVec4(self.Min.x, self.Min.y, self.Max.x, self.Max.y)
end
--- @param d ImVec2
function MT.ImRect:Translate(d)
self.Min.x = self.Min.x + d.x; self.Min.y = self.Min.y + d.y
self.Max.x = self.Max.x + d.x; self.Max.y = self.Max.y + d.y
end
function MT.ImRect:GetArea() return (self.Max.x - self.Min.x) * (self.Max.y - self.Min.y) end
--- @nodiscard
function MT.ImRect:AsVec4() return ImVec4(self.Min.x, self.Min.y, self.Max.x, self.Max.y) end
--- @param dest ImRect
--- @param src ImRect
function ImRect_Copy(dest, src)
dest.Min[1] = src.Min[1]; dest.Min[2] = src.Min[2]
dest.Max[1] = src.Max[1]; dest.Max[2] = src.Max[2]
end
--- @param dest ImRect
--- @param src ImVec4
function ImRect_CopyFromV4(dest, src)
dest.Min.x = src.x; dest.Min.y = src.y
dest.Max.x = src.z; dest.Max.y = src.w
end
--- @param _ARRAY ImU32[]
--- @param _N int
function IM_BITARRAY_TESTBIT(_ARRAY, _N)
return bit.band(_ARRAY[bit.rshift(_N - 1, 5) + 1], bit.lshift(1, bit.band(_N - 1, 31))) ~= 0
end
--- @param _ARRAY ImU32[]
--- @param _N int
function IM_BITARRAY_CLEARBIT(_ARRAY, _N)
local idx = bit.rshift(_N - 1, 5) + 1
_ARRAY[idx] = bit.band(_ARRAY[idx], bit.bnot(bit.lshift(1, bit.band(_N - 1, 31))))
end
--- @param arr ImU32[]
--- @param n int
function ImBitArraySetBit(arr, n)
local mask = bit.lshift(1, bit.band(n - 1, 31))
local idx = bit.rshift(n - 1, 5) + 1
arr[idx] = bit.bor(arr[idx], mask)
end
--- @alias ImBitArrayForNamedKeys ImBitArray
--- NOTE: This struct is expensive to create
--- @class ImBitArray<BITCOUNT, OFFSET>
--- @field Data ImU32[]
--- @param BITCOUNT int
--- @param OFFSET? int
--- @return ImBitArray
function ImBitArray(BITCOUNT, OFFSET)
if OFFSET == nil then OFFSET = 0 end
local this = { Data = {} }
local size = bit.rshift(BITCOUNT + 31, 5)
this.ClearAllBits = function(self) local data = self.Data; for i = 1, size do data[i] = 0 end end
this.SetAllBits = function(self) local data = self.Data; for i = 1, size do data[i] = 0xFFFFFFFF end end
--- @param n int # 1-based
--- @return boolean
this.TestBit = function(self, n) n = n + OFFSET; IM_ASSERT(n >= 1 and n <= BITCOUNT); return IM_BITARRAY_TESTBIT(self.Data, n); end
--- @param n int # 1-based
this.SetBit = function(self, n) IM_ASSERT(n >= 1 and n <= BITCOUNT); ImBitArraySetBit(self.Data, n); end
this:ClearAllBits()
return this
end
function MT.ImDrawList:PathClear() self._Path:clear() end
--- @param pos ImVec2
function MT.ImDrawList:PathLineTo(pos) self._Path:push_back(pos) end
function MT.ImDrawList:PathLineToMergeDuplicate(pos)
local path_size = self._Path.Size
if path_size == 0 or self._Path.Data[path_size].x ~= pos.x or self._Path.Data[path_size].y ~= pos.y then
self._Path:push_back(pos)
end
end
function MT.ImDrawList:PathFillConvex(col)
self:AddConvexPolyFilled(self._Path.Data, self._Path.Size, col)
self._Path.Size = 0
end
--- @param col ImU32
--- @param thickness? float
--- @param flags? ImDrawFlags
function MT.ImDrawList:PathStroke(col, thickness, flags)
if not thickness then thickness = 1.0 end
if not flags then flags = 0 end
self:AddPolyline(self._Path.Data, self._Path.Size, col, thickness, flags)
self._Path.Size = 0
end
--- @param col ImU32
function ImGui.SetNextItemColorMarker(col)
local g = GImGui
g.NextItemData.HasFlags = bit.bor(g.NextItemData.HasFlags, ImGuiNextItemDataFlags.HasColorMarker)
g.NextItemData.ColorMarker = col
end
--- @class ImDrawListSharedData
--- @field TexUvWhitePixel ImVec2
--- @field TexUvLines ImVec4[]
--- @field FontAtlas ImFontAtlas
--- @field Font ImFont
--- @field FontSize float
--- @field FontScale float
--- @field CurveTessellationTol float
--- @field CircleTessellationMaxError float
--- @field InitialFringeScale float
--- @field InitialFlags ImDrawListFlags
--- @field ClipRectFullscreen? ImVec4
--- @field TempBuffer ImVector<ImVec2>
--- @field DrawLists ImVector<ImDrawList>
--- @field Context? ImGuiContext
--- @field ArcFastVtx table<ImVec2> # 1-based table
--- @field ArcFastRadiusCutoff float
--- @field CircleSegmentCounts table<int> # 1-based table
MT.ImDrawListSharedData = {}
MT.ImDrawListSharedData.__index = MT.ImDrawListSharedData
--- @return ImDrawListSharedData
--- @nodiscard
function ImDrawListSharedData()
local this = setmetatable({
TexUvWhitePixel = nil,
TexUvLines = nil,
FontAtlas = nil,
Font = nil,
FontSize = 0,
FontScale = 0,
CurveTessellationTol = 0,
CircleTessellationMaxError = 0,
InitialFringeScale = 1,
InitialFlags = 0,
ClipRectFullscreen = nil,
TempBuffer = ImVector(ImVec2),
DrawLists = ImVector(),
ArcFastVtx = {},
ArcFastRadiusCutoff = nil,
CircleSegmentCounts = {},
Context = nil
}, MT.ImDrawListSharedData)
for i = 1, IM_DRAWLIST_ARCFAST_TABLE_SIZE do
local a = ((i - 1) * 2 * IM_PI) / IM_DRAWLIST_ARCFAST_TABLE_SIZE
this.ArcFastVtx[i] = ImVec2(ImCos(a), ImSin(a))
end
return this
end
--- @class ImFontAtlasBuilder
--- @field PackContext stbrp_context
--- @field PackNodes ImVector<stbrp_node>
--- @field Rects ImVector<ImTextureRect>
--- @field RectsIndex ImVector<ImFontAtlasRectEntry>
--- @field TempBuffer ImVector<char>
--- @field RectsIndexFreeListStart int
--- @field RectsPackedCount int
--- @field RectsPackedSurface int
--- @field RectsDiscardedCount int
--- @field RectsDiscardedSurface int
--- @field FrameCount int
--- @field MaxRectSize ImVec2
--- @field MaxRectBounds ImVec2
--- @field LockDisableResize bool
--- @field PreloadedAllGlyphsRanges bool
--- @field BakedPool ImVector<ImFontBaked>
--- @field BakedMap table<ImGuiID, any> # LUA: No ImGuiStorage
--- @field BakedDiscardedCount int
--- @field PackIdMouseCursors ImFontAtlasRectId
--- @field PackIdLinesTexData ImFontAtlasRectId
MT.ImFontAtlasBuilder = {}
MT.ImFontAtlasBuilder.__index = MT.ImFontAtlasBuilder
--- @return ImFontAtlasBuilder
function ImFontAtlasBuilder()
--- @type ImFontAtlasBuilder
local this = setmetatable({}, MT.ImFontAtlasBuilder)
this.PackContext = nil -- struct stbrp_context_opaque { char data[80]; };
this.PackNodes = ImVector()
this.Rects = ImVector()
this.RectsIndex = ImVector()
this.TempBuffer = ImVector()
this.RectsIndexFreeListStart = -1
this.RectsPackedCount = 0
this.RectsPackedSurface = 0
this.RectsDiscardedCount = 0
this.RectsDiscardedSurface = 0
this.FrameCount = -1
this.MaxRectSize = ImVec2()
this.MaxRectBounds = ImVec2()
this.LockDisableResize = false
this.PreloadedAllGlyphsRanges = false
this.BakedPool = ImVector() -- ImStableVector<ImFontBaked,32>
this.BakedMap = {}
this.BakedDiscardedCount = 0
this.PackIdMouseCursors = -1
this.PackIdLinesTexData = -1
return this
end
--- @class ImFontStackData
--- @field Font ImFont
--- @field FontSizeBeforeScaling float
--- @field FontSizeAfterScaling float
--- @return ImFontStackData
--- @param font ImFont
--- @param font_size_before_scaling float
--- @param font_size_after_scaling float
--- @nodiscard
function ImFontStackData(font, font_size_before_scaling, font_size_after_scaling)
return {
Font = font,
FontSizeBeforeScaling = font_size_before_scaling,
FontSizeAfterScaling = font_size_after_scaling
}
end
--- `GetVarPtr()` is currently only used on `g.Style` in Dear ImGui, and we don't have pointers!
--- @class ImGuiStyleVarInfo
--- @field Count ImU32
--- @field DataType ImGuiDataType
--- @field Key string # key in parent structure. Note that the cpp Dear ImGui uses `ImU32 Offset`!
--- @param count ImU32
--- @param data_type ImGuiDataType
--- @param key string
--- @return ImGuiStyleVarInfo
--- @nodiscard
function ImGuiStyleVarInfo(count, data_type, key)
return { Count = count, DataType = data_type, Key = key }
end
--- @class ImGuiStyleMod
--- @field VarIdx ImGuiStyleVar
--- @field BackupVal table
--- @param idx ImGuiStyleVar
--- @param v int|float|ImVec2
function ImGuiStyleMod(idx, v)
local this = { VarIdx = idx, BackupVal = {nil, nil} }
--- @cast this ImGuiStyleMod
if type(v) == "number" then
this.BackupVal[1] = v
else -- ImVec2
this.BackupVal[1] = v.x; this.BackupVal[2] = v.y
end
return this
end
--- Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo()
--- @class ImGuiDataTypeInfo
--- @field Size size_t # Size in bytes
--- @field Name string # Short descriptive name for the type, for debugging
--- @field PrintFmt string # Default printf format for the type
--- @field ScanFmt string # Default scanf format for the type
--- @class ImGuiLastItemData
--- @field ID ImGuiID
--- @field ItemFlags ImGuiItemFlags
--- @field StatusFlags ImGuiItemStatusFlags
--- @field Rect ImRect
--- @field NavRect ImRect
--- @field DisplayRect ImRect
--- @field ClipRect ImRect
--- @field Shortcut ImGuiKeyChord
--- @return ImGuiLastItemData
--- @nodiscard
function ImGuiLastItemData()
return {
ID = 0,
ItemFlags = 0,
StatusFlags = 0,
Rect = ImRect(),
NavRect = ImRect(),
DisplayRect = ImRect(),
ClipRect = ImRect(),
Shortcut = 0
}
end
--- @param dest ImGuiLastItemData
--- @param src ImGuiLastItemData
function ImGuiLastItemData_Copy(dest, src)
dest.ID = src.ID
dest.ItemFlags = src.ItemFlags
dest.StatusFlags = src.StatusFlags
ImRect_Copy(dest.Rect, src.Rect)
ImRect_Copy(dest.NavRect, src.NavRect)
ImRect_Copy(dest.DisplayRect, src.DisplayRect)