-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimgui_demo.js
3483 lines (3483 loc) · 452 KB
/
imgui_demo.js
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
// dear imgui, v1.60 WIP
// (demo code)
System.register(["./imgui"], function (exports_1, context_1) {
"use strict";
var ImGui, imgui_1, imgui_2, imgui_3, imgui_4, imgui_5, imgui_6, imgui_7, imgui_8, imgui_9, imgui_10, imgui_11, imgui_12, imgui_13, imgui_14, imgui_15, imgui_16, imgui_17, imgui_18, imgui_19, imgui_20, imgui_21, imgui_22, imgui_23, imgui_24, imgui_25, imgui_26, IM_NEWLINE, Static, _static, done, ExampleAppConsole, ExampleAppLog;
var __moduleName = context_1 && context_1.id;
// #ifdef _MSC_VER
// #pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
// #define snprintf _snprintf
// #endif
// #ifdef __clang__
// #pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse.
// #pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning : 'xx' is deprecated: The POSIX name for this item.. // for strdup used in demo code (so user can copy & paste the code)
// #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int'
// #pragma clang diagnostic ignored "-Wformat-security" // warning : warning: format string is not a string literal
// #pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
// #if __has_warning("-Wreserved-id-macro")
// #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier //
// #endif
// #elif defined(__GNUC__)
// #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
// #pragma GCC diagnostic ignored "-Wformat-security" // warning : format string is not a string literal (potentially insecure)
// #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
// #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
// #if (__GNUC__ >= 6)
// #pragma GCC diagnostic ignored "-Wmisleading-indentation" // warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub.
// #endif
// #endif
function format_number(n, radix = 10, pad = 0, pad_char = "0") {
return pad > 0 ? (pad_char.repeat(pad) + n.toString(radix)).substr(-pad) : n.toString(radix);
}
function format_number_dec(n, pad = 0, pad_char = "0") {
return format_number(n, 10, pad, pad_char);
}
function format_number_hex(n, pad = 0, pad_char = "0") {
return format_number(n, 16, pad, pad_char);
}
// #define IM_MAX(_A,_B) (((_A) >= (_B)) ? (_A) : (_B))
function IM_MAX(_A, _B) { return ((_A) >= (_B)) ? (_A) : (_B); }
function STATIC(key, value) {
return _static[key] || (_static[key] = new Static(value));
}
// static void ShowExampleAppConsole(bool* p_open);
// static void ShowExampleAppLog(bool* p_open);
// static void ShowExampleAppLayout(bool* p_open);
// static void ShowExampleAppPropertyEditor(bool* p_open);
// static void ShowExampleAppLongText(bool* p_open);
// static void ShowExampleAppAutoResize(bool* p_open);
// static void ShowExampleAppConstrainedResize(bool* p_open);
// static void ShowExampleAppSimpleOverlay(bool* p_open);
// static void ShowExampleAppWindowTitles(bool* p_open);
// static void ShowExampleAppCustomRendering(bool* p_open);
// static void ShowExampleAppMainMenuBar();
// static void ShowExampleMenuFile();
function ShowHelpMarker(desc) {
ImGui.TextDisabled("(?)");
if (ImGui.IsItemHovered()) {
ImGui.BeginTooltip();
ImGui.PushTextWrapPos(ImGui.GetFontSize() * 35.0);
ImGui.TextUnformatted(desc);
ImGui.PopTextWrapPos();
ImGui.EndTooltip();
}
}
function ShowUserGuide() {
ImGui.BulletText("Double-click on title bar to collapse window.");
ImGui.BulletText("Click and drag on lower right corner to resize window\n(double-click to auto fit window to its contents).");
ImGui.BulletText("Click and drag on any empty space to move window.");
ImGui.BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields.");
ImGui.BulletText("CTRL+Click on a slider or drag box to input value as text.");
if (ImGui.GetIO().FontAllowUserScaling)
ImGui.BulletText("CTRL+Mouse Wheel to zoom window contents.");
ImGui.BulletText("Mouse Wheel to scroll.");
ImGui.BulletText("While editing text:\n");
ImGui.Indent();
ImGui.BulletText("Hold SHIFT or use mouse to select text.");
ImGui.BulletText("CTRL+Left/Right to word jump.");
ImGui.BulletText("CTRL+A or double-click to select all.");
ImGui.BulletText("CTRL+X,CTRL+C,CTRL+V to use clipboard.");
ImGui.BulletText("CTRL+Z,CTRL+Y to undo/redo.");
ImGui.BulletText("ESCAPE to revert.");
ImGui.BulletText("You can apply arithmetic operators +,*,/ on numerical values.\nUse +- to subtract.");
ImGui.Unindent();
}
exports_1("ShowUserGuide", ShowUserGuide);
// Demonstrate most Dear ImGui features (this is big function!)
// You may execute this function to experiment with the UI and understand what it does. You may then search for keywords in the code when you are interested by a specific feature.
function ShowDemoWindow(p_open = null) {
done = false;
// Examples Apps (accessible from the "Examples" menu)
/* static */ const show_app_main_menu_bar = STATIC("show_app_main_menu_bar", false);
/* static */ const show_app_console = STATIC("show_app_console", false);
/* static */ const show_app_log = STATIC("show_app_log", false);
/* static */ const show_app_layout = STATIC("show_app_layout", false);
/* static */ const show_app_property_editor = STATIC("show_app_property_editor", false);
/* static */ const show_app_long_text = STATIC("show_app_long_text", false);
/* static */ const show_app_auto_resize = STATIC("show_app_auto_resize", false);
/* static */ const show_app_constrained_resize = STATIC("show_app_constrained_resize", false);
/* static */ const show_app_simple_overlay = STATIC("show_app_simple_overlay", false);
/* static */ const show_app_window_titles = STATIC("show_app_window_titles", false);
/* static */ const show_app_custom_rendering = STATIC("show_app_custom_rendering", false);
if (show_app_main_menu_bar.value)
ShowExampleAppMainMenuBar();
if (show_app_console.value)
ShowExampleAppConsole((value = show_app_console.value) => show_app_console.value = value);
if (show_app_log.value)
ShowExampleAppLog((value = show_app_log.value) => show_app_log.value = value);
if (show_app_layout.value)
ShowExampleAppLayout((value = show_app_layout.value) => show_app_layout.value = value);
if (show_app_property_editor.value)
ShowExampleAppPropertyEditor((value = show_app_property_editor.value) => show_app_property_editor.value = value);
if (show_app_long_text.value)
ShowExampleAppLongText((value = show_app_long_text.value) => show_app_long_text.value = value);
if (show_app_auto_resize.value)
ShowExampleAppAutoResize((value = show_app_auto_resize.value) => show_app_auto_resize.value = value);
if (show_app_constrained_resize.value)
ShowExampleAppConstrainedResize((value = show_app_constrained_resize.value) => show_app_constrained_resize.value = value);
if (show_app_simple_overlay.value)
ShowExampleAppSimpleOverlay((value = show_app_simple_overlay.value) => show_app_simple_overlay.value = value);
if (show_app_window_titles.value)
ShowExampleAppWindowTitles((value = show_app_window_titles.value) => show_app_window_titles.value = value);
if (show_app_custom_rendering.value)
ShowExampleAppCustomRendering((value = show_app_custom_rendering.value) => show_app_custom_rendering.value = value);
// Dear ImGui Apps (accessible from the "Help" menu)
/* static */ const show_app_style_editor = STATIC("show_app_style_editor", false);
/* static */ const show_app_metrics = STATIC("show_app_metrics", false);
/* static */ const show_app_about = STATIC("show_app_about", false);
if (show_app_metrics.value) {
ImGui.ShowMetricsWindow((value = show_app_metrics.value) => show_app_metrics.value = value);
}
if (show_app_style_editor.value) {
ImGui.Begin("Style Editor", (value = show_app_style_editor.value) => show_app_style_editor.value = value); /*ImGui.*/
ShowStyleEditor();
ImGui.End();
}
if (show_app_about.value) {
ImGui.Begin("About Dear ImGui", (value = show_app_about.value) => show_app_about.value = value, ImGui.WindowFlags.AlwaysAutoResize);
ImGui.Text(`Dear ImGui, ${ImGui.GetVersion()}`);
ImGui.Separator();
ImGui.Text("By Omar Cornut and all dear imgui contributors.");
ImGui.Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information.");
ImGui.End();
}
// Demonstrate the various window flags. Typically you would just use the default!
/* static */ const no_titlebar = STATIC("no_titlebar", false);
/* static */ const no_scrollbar = STATIC("no_scrollbar", false);
/* static */ const no_menu = STATIC("no_menu", false);
/* static */ const no_move = STATIC("no_move", false);
/* static */ const no_resize = STATIC("no_resize", false);
/* static */ const no_collapse = STATIC("no_collapse", false);
/* static */ const no_close = STATIC("no_close", false);
/* static */ const no_nav = STATIC("no_nav", false);
let window_flags = 0;
if (no_titlebar.value)
window_flags |= imgui_15.ImGuiWindowFlags.NoTitleBar;
if (no_scrollbar.value)
window_flags |= imgui_15.ImGuiWindowFlags.NoScrollbar;
if (!no_menu.value)
window_flags |= imgui_15.ImGuiWindowFlags.MenuBar;
if (no_move.value)
window_flags |= imgui_15.ImGuiWindowFlags.NoMove;
if (no_resize.value)
window_flags |= imgui_15.ImGuiWindowFlags.NoResize;
if (no_collapse.value)
window_flags |= imgui_15.ImGuiWindowFlags.NoCollapse;
if (no_nav.value)
window_flags |= imgui_15.ImGuiWindowFlags.NoNav;
if (no_close.value)
p_open = null; // Don't pass our bool* to Begin
// We specify a default position/size in case there's no data in the .ini file. Typically this isn't required! We only do it to make the Demo applications a little more welcoming.
ImGui.SetNextWindowPos(new imgui_18.ImVec2(650, 20), ImGui.Cond.FirstUseEver);
ImGui.SetNextWindowSize(new imgui_18.ImVec2(550, 680), imgui_7.ImGuiCond.FirstUseEver);
// Main body of the Demo window starts here.
if (!ImGui.Begin("ImGui Demo", p_open, window_flags)) {
// Early out if the window is collapsed, as an optimization.
ImGui.End();
return done;
}
ImGui.Text(`dear imgui says hello. (${imgui_1.IMGUI_VERSION})`);
// Most "big" widgets share a common width settings by default.
//ImGui.PushItemWidth(ImGui.GetWindowWidth() * 0.65); // Use 2/3 of the space for widgets and 1/3 for labels (default)
ImGui.PushItemWidth(ImGui.GetFontSize() * -12); // Use fixed width for labels (by passing a negative value), the rest goes to widgets. We choose a width proportional to our font size.
// Menu
if (ImGui.BeginMenuBar()) {
if (ImGui.BeginMenu("Menu")) {
ShowExampleMenuFile();
ImGui.EndMenu();
}
if (ImGui.BeginMenu("Examples")) {
ImGui.MenuItem("Main menu bar", null, (value = show_app_main_menu_bar.value) => show_app_main_menu_bar.value = value);
ImGui.MenuItem("Console", null, (value = show_app_console.value) => show_app_console.value = value);
ImGui.MenuItem("Log", null, (value = show_app_log.value) => show_app_log.value = value);
ImGui.MenuItem("Simple layout", null, (value = show_app_layout.value) => show_app_layout.value = value);
ImGui.MenuItem("Property editor", null, (value = show_app_property_editor.value) => show_app_property_editor.value = value);
ImGui.MenuItem("Long text display", null, (value = show_app_long_text.value) => show_app_long_text.value = value);
ImGui.MenuItem("Auto-resizing window", null, (value = show_app_auto_resize.value) => show_app_auto_resize.value = value);
ImGui.MenuItem("Constrained-resizing window", null, (value = show_app_constrained_resize.value) => show_app_constrained_resize.value = value);
ImGui.MenuItem("Simple overlay", null, (value = show_app_simple_overlay.value) => show_app_simple_overlay.value = value);
ImGui.MenuItem("Manipulating window titles", null, (value = show_app_window_titles.value) => show_app_window_titles.value = value);
ImGui.MenuItem("Custom rendering", null, (value = show_app_custom_rendering.value) => show_app_custom_rendering.value = value);
ImGui.EndMenu();
}
if (ImGui.BeginMenu("Help")) {
ImGui.MenuItem("Metrics", null, (value = show_app_metrics.value) => show_app_metrics.value = value);
ImGui.MenuItem("Style Editor", null, (value = show_app_style_editor.value) => show_app_style_editor.value = value);
ImGui.MenuItem("About Dear ImGui", null, (value = show_app_about.value) => show_app_about.value = value);
ImGui.EndMenu();
}
ImGui.EndMenuBar();
}
ImGui.Spacing();
if (ImGui.CollapsingHeader("Help")) {
ImGui.TextWrapped("This window is being created by the ShowDemoWindow() function. Please refer to the code in imgui_demo.ts for reference.\n\n");
ImGui.Text("USER GUIDE:");
/*ImGui.*/ ShowUserGuide();
}
if (ImGui.CollapsingHeader("Window options")) {
ImGui.Checkbox("No titlebar", (value = no_titlebar.value) => no_titlebar.value = value);
ImGui.SameLine(150);
ImGui.Checkbox("No scrollbar", (value = no_scrollbar.value) => no_scrollbar.value = value);
ImGui.SameLine(300);
ImGui.Checkbox("No menu", (value = no_menu.value) => no_menu.value = value);
ImGui.Checkbox("No move", (value = no_move.value) => no_move.value = value);
ImGui.SameLine(150);
ImGui.Checkbox("No resize", (value = no_resize.value) => no_resize.value = value);
ImGui.SameLine(300);
ImGui.Checkbox("No collapse", (value = no_collapse.value) => no_collapse.value = value);
ImGui.Checkbox("No close", (value = no_close.value) => no_close.value = value);
ImGui.SameLine(150);
ImGui.Checkbox("No nav", (value = no_nav.value) => no_nav.value = value);
if (ImGui.TreeNode("Style")) {
/*ImGui.*/ ShowStyleEditor();
ImGui.TreePop();
}
if (ImGui.TreeNode("Capture/Logging")) {
ImGui.TextWrapped("The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded. You can also call ImGui.LogText() to output directly to the log without a visual output.");
ImGui.LogButtons();
ImGui.TreePop();
}
}
if (ImGui.CollapsingHeader("Widgets")) {
if (ImGui.TreeNode("Basic")) {
/* static */ const clicked = STATIC("clicked", 0);
if (ImGui.Button("Button"))
clicked.value++;
if (clicked.value & 1) {
ImGui.SameLine();
ImGui.Text("Thanks for clicking me!");
}
/* static */ const check = STATIC("check", true);
ImGui.Checkbox("checkbox", (value = check.value) => check.value = value);
/* static */ const e = STATIC("e", 0);
ImGui.RadioButton("radio a", (value = e.value) => e.value = value, 0);
ImGui.SameLine();
ImGui.RadioButton("radio b", (value = e.value) => e.value = value, 1);
ImGui.SameLine();
ImGui.RadioButton("radio c", (value = e.value) => e.value = value, 2);
// Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style.
for (let i = 0; i < 7; i++) {
if (i > 0)
ImGui.SameLine();
ImGui.PushID(i);
ImGui.PushStyleColor(imgui_5.ImGuiCol.Button, imgui_21.ImColor.HSV(i / 7.0, 0.6, 0.6));
ImGui.PushStyleColor(imgui_5.ImGuiCol.ButtonHovered, imgui_21.ImColor.HSV(i / 7.0, 0.7, 0.7));
ImGui.PushStyleColor(imgui_5.ImGuiCol.ButtonActive, imgui_21.ImColor.HSV(i / 7.0, 0.8, 0.8));
ImGui.Button("Click");
ImGui.PopStyleColor(3);
ImGui.PopID();
}
// Arrow buttons
/* static */ const counter = STATIC("counter", 0);
const spacing = ImGui.GetStyle().ItemInnerSpacing.x;
ImGui.PushButtonRepeat(true);
if (ImGui.ArrowButton("##left", imgui_26.ImGuiDir.Left)) {
counter.value--;
}
ImGui.SameLine(0.0, spacing);
if (ImGui.ArrowButton("##right", imgui_26.ImGuiDir.Right)) {
counter.value++;
}
ImGui.PopButtonRepeat();
ImGui.SameLine();
ImGui.Text(`${counter.value}`);
ImGui.Text("Hover over me");
if (ImGui.IsItemHovered())
ImGui.SetTooltip("I am a tooltip");
ImGui.SameLine();
ImGui.Text("- or me");
if (ImGui.IsItemHovered()) {
ImGui.BeginTooltip();
ImGui.Text("I am a fancy tooltip");
/* static */ const arr = STATIC("arr_", [0.6, 0.1, 1.0, 0.5, 0.92, 0.1, 0.2]);
// ImGui.PlotLines("Curve", arr, IM_ARRAYSIZE(arr));
ImGui.PlotLines("Curve", arr.value, imgui_3.IM_ARRAYSIZE(arr.value));
ImGui.EndTooltip();
}
ImGui.Separator();
ImGui.LabelText("label", "Value");
{
// Using the _simplified_ one-liner Combo() api here
// See "Combo" section for examples of how to use the more complete BeginCombo()/EndCombo() api.
const items = ["AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO"];
/* static */ const item_current = STATIC("item_current#389", 0);
ImGui.Combo("combo", (value = item_current.value) => item_current.value = value, items, imgui_3.IM_ARRAYSIZE(items));
ImGui.SameLine();
ShowHelpMarker("USER:\nHold SHIFT or use mouse to select text.\nCTRL+Left/Right to word jump.\nCTRL+A or double-click to select all.\nCTRL+X,CTRL+C,CTRL+V clipboard.\nCTRL+Z,CTRL+Y undo/redo.\nESCAPE to revert.\n\nPROGRAMMER:\nYou can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() to a dynamic string type. See misc/stl/imgui_stl.h for an example (this is not demonstrated in imgui_demo.cpp).");
}
{
/* static */ const str0 = STATIC("str0", new imgui_4.ImStringBuffer(128, "Hello, world!"));
/* static */ const i0 = STATIC("i0", 123);
ImGui.InputText("input text", str0.value, imgui_3.IM_ARRAYSIZE(str0.value));
ImGui.SameLine();
ShowHelpMarker("Hold SHIFT or use mouse to select text.\n" + "CTRL+Left/Right to word jump.\n" + "CTRL+A or double-click to select all.\n" + "CTRL+X,CTRL+C,CTRL+V clipboard.\n" + "CTRL+Z,CTRL+Y undo/redo.\n" + "ESCAPE to revert.\n");
ImGui.InputInt("input int", (value = i0.value) => i0.value = value);
ImGui.SameLine();
ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n");
/* static */ const f0 = STATIC("f0#400", 0.001);
ImGui.InputFloat("input float", (value = f0.value) => f0.value = value, 0.01, 1.0);
// NB: You can use the %e notation as well.
/* static */ const d0 = STATIC("d0", 999999.000001);
ImGui.InputDouble("input double", (value = d0.value) => d0.value = value, 0.01, 1.0, "%.8f");
// static float f1 = 1.e10f;
/* static */ const f1 = STATIC("f1#403", 1.e10);
ImGui.InputFloat("input scientific", (value = f1.value) => f1.value = value, 0.0, 0.0, "%e");
ImGui.SameLine();
ShowHelpMarker("You can input value using the scientific notation,\n e.g. \"1e+8\" becomes \"100000000\".\n");
/* static */ const vec4a = STATIC("vec4a", [0.10, 0.20, 0.30, 0.44]);
ImGui.InputFloat3("input float3", vec4a.value);
}
{
/* static */ const i1 = STATIC("i1#415", 50), i2 = STATIC("i2#415", 42);
ImGui.DragInt("drag int", (value = i1.value) => i1.value = value, 1);
ImGui.SameLine();
ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value.");
ImGui.DragInt("drag int 0..100", (value = i2.value) => i2.value = value, 1, 0, 100, "%d%%");
/* static */ const f1 = STATIC("f1#421", 1.00), f2 = STATIC("f2#421", 0.0067);
ImGui.DragFloat("drag float", (value = f1.value) => f1.value = value, 0.005);
ImGui.DragFloat("drag small float", (value = f2.value) => f2.value = value, 0.0001, 0.0, 0.0, "%.06f ns");
}
{
/* static */ const i1 = STATIC("i1#427", 0);
ImGui.SliderInt("slider int", (value = i1.value) => i1.value = value, -1, 3);
ImGui.SameLine();
ShowHelpMarker("CTRL+click to input value.");
/* static */ const f1 = STATIC("f1#427", 0.123), f2 = STATIC("f2#427", 0.0);
ImGui.SliderFloat("slider float", (value = f1.value) => f1.value = value, 0.0, 1.0, "ratio = %.3f");
ImGui.SliderFloat("slider float (curve)", (value = f2.value) => f2.value = value, -10.0, 10.0, "%.4f", 2.0);
/* static */ const angle = STATIC("angle", 0.0);
ImGui.SliderAngle("slider angle", (value = angle.value) => angle.value = value);
/* static */ const angle3 = STATIC("angle3", [0.0, 0.0, 0.0]);
ImGui.SliderAngle3("slider angle3", angle3.value);
}
{
/* static */ const col1 = STATIC("col1", [1.0, 0.0, 0.2]);
/* static */ const col2 = STATIC("col2", [0.4, 0.7, 0.0, 0.5]);
ImGui.ColorEdit3("color 1", col1.value);
ImGui.SameLine();
ShowHelpMarker("Click on the colored square to open a color picker.\nClick and hold to use drag and drop.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n");
ImGui.ColorEdit4("color 2", col2.value);
}
{
// List box
const listbox_items = ["Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon"];
/* static */ const listbox_item_current = STATIC("listbox_item_current", 1);
ImGui.ListBox("listbox\n(single select)", (value = listbox_item_current.value) => listbox_item_current.value = value, listbox_items, imgui_3.IM_ARRAYSIZE(listbox_items), 4);
// /* static */ const listbox_item_current2: Static<number> = STATIC("listbox_item_current2", 2);
// ImGui.PushItemWidth(-1);
// ImGui.ListBox("##listbox2", (value = listbox_item_current2.value) => listbox_item_current2.value = value, listbox_items, IM_ARRAYSIZE(listbox_items), 4);
// ImGui.PopItemWidth();
}
ImGui.TreePop();
}
// Testing ImGuiOnceUponAFrame helper.
//static ImGuiOnceUponAFrame once;
//for (let i = 0; i < 5; i++)
// if (once)
// ImGui.Text("This will be displayed only once.");
if (ImGui.TreeNode("Trees")) {
if (ImGui.TreeNode("Basic trees")) {
for (let i = 0; i < 5; i++)
if (ImGui.TreeNode(i.toString(), `Child ${i}`)) {
ImGui.Text("blah blah");
ImGui.SameLine();
if (ImGui.SmallButton("button")) { }
ImGui.TreePop();
}
ImGui.TreePop();
}
if (ImGui.TreeNode("Advanced, with Selectable nodes")) {
ShowHelpMarker("This is a more standard looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open.");
/* static */ const align_label_with_current_x_position = STATIC("align_label_with_current_x_position", false);
ImGui.Checkbox("Align label with current X position)", (value = align_label_with_current_x_position.value) => align_label_with_current_x_position.value = value);
ImGui.Text("Hello!");
if (align_label_with_current_x_position.value)
ImGui.Unindent(ImGui.GetTreeNodeToLabelSpacing());
/* static */ const selection_mask = STATIC("selection_mask", (1 << 2)); // Dumb representation of what may be user-side selection state. You may carry selection state inside or outside your objects in whatever format you see fit.
let node_clicked = -1; // Temporary storage of what node we have clicked to process selection at the end of the loop. May be a pointer to your own node type, etc.
ImGui.PushStyleVar(imgui_13.ImGuiStyleVar.IndentSpacing, ImGui.GetFontSize() * 3); // Increase spacing to differentiate leaves from expanded contents.
for (let i = 0; i < 6; i++) {
// Disable the default open on single-click behavior and pass in Selected flag according to our selection state.
let node_flags = imgui_14.ImGuiTreeNodeFlags.OpenOnArrow | imgui_14.ImGuiTreeNodeFlags.OpenOnDoubleClick | ((selection_mask.value & (1 << i)) ? imgui_14.ImGuiTreeNodeFlags.Selected : 0);
if (i < 3) {
// Node
const node_open = ImGui.TreeNodeEx(i, node_flags, `Selectable Node ${i}`);
if (ImGui.IsItemClicked())
node_clicked = i;
if (node_open) {
ImGui.Text("Blah blah\nBlah Blah");
ImGui.TreePop();
}
}
else {
// Leaf: The only reason we have a TreeNode at all is to allow selection of the leaf. Otherwise we can use BulletText() or TreeAdvanceToLabelPos()+Text().
node_flags |= imgui_14.ImGuiTreeNodeFlags.Leaf | imgui_14.ImGuiTreeNodeFlags.NoTreePushOnOpen; // ImGuiTreeNodeFlags.Bullet
ImGui.TreeNodeEx(i, node_flags, `Selectable Leaf ${i}`);
if (ImGui.IsItemClicked())
node_clicked = i;
}
}
if (node_clicked !== -1) {
// Update selection state. Process outside of tree loop to avoid visual inconsistencies during the clicking-frame.
if (ImGui.GetIO().KeyCtrl)
selection_mask.value ^= (1 << node_clicked); // CTRL+click to toggle
else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, this commented bit preserve selection when clicking on item that is part of the selection
selection_mask.value = (1 << node_clicked); // Click to single-select
}
ImGui.PopStyleVar();
if (align_label_with_current_x_position.value)
ImGui.Indent(ImGui.GetTreeNodeToLabelSpacing());
ImGui.TreePop();
}
ImGui.TreePop();
}
if (ImGui.TreeNode("Collapsing Headers")) {
/* static */ const closable_group = STATIC("closable_group", true);
ImGui.Checkbox("Enable extra group", (value = closable_group.value) => closable_group.value = value);
if (ImGui.CollapsingHeader("Header")) {
ImGui.Text(`IsItemHovered: ${ImGui.IsItemHovered()}`);
for (let i = 0; i < 5; i++)
ImGui.Text(`Some content ${i}`);
}
if (ImGui.CollapsingHeader("Header with a close button", (value = closable_group.value) => closable_group.value = value)) {
ImGui.Text(`IsItemHovered: ${ImGui.IsItemHovered()}`);
for (let i = 0; i < 5; i++)
ImGui.Text(`More content ${i}`);
}
ImGui.TreePop();
}
if (ImGui.TreeNode("Bullets")) {
ImGui.BulletText("Bullet point 1");
ImGui.BulletText("Bullet point 2\nOn multiple lines");
ImGui.Bullet();
ImGui.Text("Bullet point 3 (two calls)");
ImGui.Bullet();
ImGui.SmallButton("Button");
ImGui.TreePop();
}
if (ImGui.TreeNode("Text")) {
if (ImGui.TreeNode("Colored Text")) {
// Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility.
ImGui.TextColored(new imgui_19.ImVec4(1.0, 0.0, 1.0, 1.0), "Pink");
ImGui.TextColored(new imgui_19.ImVec4(1.0, 1.0, 0.0, 1.0), "Yellow");
ImGui.TextDisabled("Disabled");
ImGui.SameLine();
ShowHelpMarker("The TextDisabled color is stored in ImGuiStyle.");
ImGui.TreePop();
}
if (ImGui.TreeNode("Word Wrapping")) {
// Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility.
ImGui.TextWrapped("This text should automatically wrap on the edge of the window. The current implementation for text wrapping follows simple rules suitable for English and possibly other languages.");
ImGui.Spacing();
/* static */ const wrap_width = STATIC("wrap_width", 200.0);
ImGui.SliderFloat("Wrap width", (value = wrap_width.value) => wrap_width.value = value, -20, 600, "%.0f");
ImGui.Text("Test paragraph 1:");
let pos = ImGui.GetCursorScreenPos();
ImGui.GetWindowDrawList().AddRectFilled(new imgui_18.ImVec2(pos.x + wrap_width.value, pos.y), new imgui_18.ImVec2(pos.x + wrap_width.value + 10, pos.y + ImGui.GetTextLineHeight()), imgui_20.IM_COL32(255, 0, 255, 255));
ImGui.PushTextWrapPos(ImGui.GetCursorPos().x + wrap_width.value);
ImGui.Text(`The lazy dog is a good dog. This paragraph is made to fit within ${wrap_width.value.toFixed(0)} pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.`);
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), imgui_20.IM_COL32(255, 255, 0, 255));
ImGui.PopTextWrapPos();
ImGui.Text("Test paragraph 2:");
pos = ImGui.GetCursorScreenPos();
ImGui.GetWindowDrawList().AddRectFilled(new imgui_18.ImVec2(pos.x + wrap_width.value, pos.y), new imgui_18.ImVec2(pos.x + wrap_width.value + 10, pos.y + ImGui.GetTextLineHeight()), imgui_20.IM_COL32(255, 0, 255, 255));
ImGui.PushTextWrapPos(ImGui.GetCursorPos().x + wrap_width.value);
ImGui.Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh");
ImGui.GetWindowDrawList().AddRect(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), imgui_20.IM_COL32(255, 255, 0, 255));
ImGui.PopTextWrapPos();
ImGui.TreePop();
}
if (ImGui.TreeNode("UTF-8 Text")) {
// UTF-8 test with Japanese characters
// (Needs a suitable font, try Noto, or Arial Unicode, or M+ fonts. Read misc/fonts/README.txt for details.)
// - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8
// - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. Visual Studio save your file as 'UTF-8 without signature')
// - FOR THIS DEMO FILE ONLY, BECAUSE WE WANT TO SUPPORT OLD COMPILERS, WE ARE *NOT* INCLUDING RAW UTF-8 CHARACTERS IN THIS SOURCE FILE.
// Instead we are encoding a few strings with hexadecimal constants. Don't do this in your application!
// Please use u8"text in any language" in your application!
// Note that characters values are preserved even by InputText() if the font cannot be displayed, so you can safely copy & paste garbled characters into another application.
ImGui.TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges. Read misc/fonts/README.txt for details.");
// か \xe3\x81\x8b U+304B か
// き \xe3\x81\x8d U+304D き
// く \xe3\x81\x8f U+304F く
// け \xe3\x81\x91 U+3051 け
// こ \xe3\x81\x93 U+3053 こ
// ImGui.Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); // Normally we would use u8"blah blah" with the proper characters directly in the string.
// ImGui.Text("Hiragana: \u304B\u304D\u304F\u3051\u3053 (kakikukeko)"); // Normally we would use u8"blah blah" with the proper characters directly in the string.
ImGui.Text("Hiragana: かきくけこ (kakikukeko)"); // Normally we would use u8"blah blah" with the proper characters directly in the string.
// 日 \xe6\x97\xa5 U+65E5 日
// 本 \xe6\x9c\xac U+672C 本
// 語 \xe8\xaa\x9e U+8A9E 語
// ImGui.Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
// ImGui.Text("Kanjis: \u65E5\u672C\u8A9E (nihongo)");
ImGui.Text("Kanjis: 日本語 (nihongo)");
// /* static */ const buf: Static<ImStringBuffer> = STATIC("buf", new ImStringBuffer(32, "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"));
// /* static */ const buf: Static<ImStringBuffer> = STATIC("buf", new ImStringBuffer(32, "\u65E5\u672C\u8A9E"));
/* static */ const buf = STATIC("buf", new imgui_4.ImStringBuffer(32, "日本語"));
//static char buf[32] = u8"NIHONGO"; // <- this is how you would write it with C++11, using real kanjis
ImGui.InputText("UTF-8 input", buf.value, imgui_3.IM_ARRAYSIZE(buf.value));
ImGui.TreePop();
}
ImGui.TreePop();
}
if (ImGui.TreeNode("Images")) {
const io = ImGui.GetIO();
ImGui.TextWrapped("Below we are displaying the font texture (which is the only texture we have access to in this demo). Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. Hover the texture for a zoomed view!");
// Here we are grabbing the font texture because that's the only one we have access to inside the demo code.
// Remember that ImTextureID is just storage for whatever you want it to be, it is essentially a value that will be passed to the render function inside the ImDrawCmd structure.
// If you use one of the default imgui_impl_XXXX.cpp renderer, they all have comments at the top of their file to specify what they expect to be stored in ImTextureID.
// (for example, the imgui_impl_dx11.cpp renderer expect a 'ID3D11ShaderResourceView*' pointer. The imgui_impl_glfw_gl3.cpp renderer expect a GLuint OpenGL texture identifier etc.)
// If you decided that ImTextureID = MyEngineTexture*, then you can pass your MyEngineTexture* pointers to ImGui.Image(), and gather width/height through your own functions, etc.
// Using ShowMetricsWindow() as a "debugger" to inspect the draw data that are being passed to your render will help you debug issues if you are confused about this.
// Consider using the lower-level ImDrawList::AddImage() API, via ImGui.GetWindowDrawList()->AddImage().
const my_tex_id = io.Fonts.TexID;
const my_tex_w = io.Fonts.TexWidth;
const my_tex_h = io.Fonts.TexHeight;
ImGui.Text(`${my_tex_w.toFixed(0)}x${my_tex_h.toFixed(0)}`);
const pos = ImGui.GetCursorScreenPos();
ImGui.Image(my_tex_id, new imgui_18.ImVec2(my_tex_w, my_tex_h), new imgui_18.ImVec2(0, 0), new imgui_18.ImVec2(1, 1), new imgui_19.ImVec4(1.0, 1.0, 1.0, 1.0), new imgui_19.ImVec4(1.0, 1.0, 1.0, 0.5));
if (ImGui.IsItemHovered()) {
ImGui.BeginTooltip();
const region_sz = 32.0;
let region_x = io.MousePos.x - pos.x - region_sz * 0.5;
if (region_x < 0.0)
region_x = 0.0;
else if (region_x > my_tex_w - region_sz)
region_x = my_tex_w - region_sz;
let region_y = io.MousePos.y - pos.y - region_sz * 0.5;
if (region_y < 0.0)
region_y = 0.0;
else if (region_y > my_tex_h - region_sz)
region_y = my_tex_h - region_sz;
let zoom = 4.0;
ImGui.Text(`Min: (${region_x.toFixed(2)}, ${region_y.toFixed(2)})`);
ImGui.Text(`Max: (${(region_x + region_sz).toFixed(2)}, ${(region_y + region_sz).toFixed(2)})`);
const uv0 = new imgui_18.ImVec2((region_x) / my_tex_w, (region_y) / my_tex_h);
const uv1 = new imgui_18.ImVec2((region_x + region_sz) / my_tex_w, (region_y + region_sz) / my_tex_h);
ImGui.Image(my_tex_id, new imgui_18.ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, new imgui_21.ImColor(255, 255, 255, 255).toImVec4(), new imgui_21.ImColor(255, 255, 255, 128).toImVec4());
ImGui.EndTooltip();
}
ImGui.TextWrapped("And now some textured buttons..");
/* static */ const pressed_count = STATIC("pressed_count", 0);
for (let i = 0; i < 8; i++) {
ImGui.PushID(i);
const frame_padding = -1 + i; // -1 = uses default padding
if (ImGui.ImageButton(my_tex_id, new imgui_18.ImVec2(32, 32), new imgui_18.ImVec2(0, 0), new imgui_18.ImVec2(32.0 / my_tex_w, 32 / my_tex_h), frame_padding, new imgui_19.ImVec4(0, 0, 0, 1)))
pressed_count.value += 1;
ImGui.PopID();
ImGui.SameLine();
}
ImGui.NewLine();
ImGui.Text(`Pressed ${pressed_count.value} times.`);
ImGui.TreePop();
}
if (ImGui.TreeNode("Combo")) {
// Expose flags as checkbox for the demo
/* static */ const flags = STATIC("flags#669", 0);
ImGui.CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", (value = flags.value) => flags.value = value, ImGui.ImGuiComboFlags.PopupAlignLeft);
if (ImGui.CheckboxFlags("ImGuiComboFlags_NoArrowButton", (value = flags.value) => flags.value = value, ImGui.ImGuiComboFlags.NoArrowButton))
flags.value &= ~ImGui.ImGuiComboFlags.NoPreview; // Clear the other flag, as we cannot combine both
if (ImGui.CheckboxFlags("ImGuiComboFlags_NoPreview", (value = flags.value) => flags.value = value, ImGui.ImGuiComboFlags.NoPreview))
flags.value &= ~ImGui.ImGuiComboFlags.NoArrowButton; // Clear the other flag, as we cannot combine both
// General BeginCombo() API, you have full control over your selection data and display type.
// (your selection data could be an index, a pointer to the object, an id for the object, a flag stored in the object itself, etc.)
const items = ["AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO"];
/* static */ const item_current = STATIC("item_current#692", items[0]); // Here our selection is a single pointer stored outside the object.
if (ImGui.BeginCombo("combo 1", item_current.value, flags.value)) // The second parameter is the label previewed before opening the combo.
{
for (let n = 0; n < imgui_3.IM_ARRAYSIZE(items); n++) {
// bool is_selected = (item_current == items[n]);
const is_selected = (item_current.value === items[n]);
// if (ImGui::Selectable(items[n], is_selected))
if (ImGui.Selectable(items[n], is_selected))
item_current.value = items[n];
if (is_selected)
ImGui.SetItemDefaultFocus(); // Set the initial focus when opening the combo (scrolling + for keyboard navigation support in the upcoming navigation branch)
}
ImGui.EndCombo();
}
// Simplified one-liner Combo() API, using values packed in a single constant string
/* static */ const item_current_2 = STATIC("item_current_2", 0);
ImGui.Combo("combo 2", (value = item_current_2.value) => item_current_2.value = value, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
// Simplified one-liner Combo() using an array of const char*
/* static */ const item_current_3 = STATIC("item_current_3", -1); // If the selection isn't within 0..count, Combo won't display a preview
ImGui.Combo("combo 3 (array)", (value = item_current_3.value) => item_current_3.value = value, items, imgui_3.IM_ARRAYSIZE(items));
// Simplified one-liner Combo() using an accessor function
// struct FuncHolder { static bool ItemGetter(void* data, int idx, const char** out_str) { *out_str = ((const char**)data)[idx]; return true; } };
class FuncHolder {
static ItemGetter(data, idx, out_str) { out_str[0] = data[idx]; return true; }
;
}
/* static */ const item_current_4 = STATIC("item_current_4", 0);
ImGui.Combo("combo 4 (function)", (value = item_current_4.value) => item_current_4.value = value, FuncHolder.ItemGetter, items, imgui_3.IM_ARRAYSIZE(items));
ImGui.TreePop();
}
if (ImGui.TreeNode("Selectables")) {
// Selectable() has 2 overloads:
// - The one taking "bool selected" as a read-only selection information. When Selectable() has been clicked is returns true and you can alter selection state accordingly.
// - The one taking "bool* p_selected" as a read-write selection information (convenient in some cases)
// The earlier is more flexible, as in real application your selection may be stored in a different manner (in flags within objects, as an external list, etc).
if (ImGui.TreeNode("Basic")) {
/* static */ const selection = STATIC("selection#695", [false, true, false, false, false]);
ImGui.Selectable("1. I am selectable", (value = selection.value[0]) => selection.value[0] = value);
ImGui.Selectable("2. I am selectable", (value = selection.value[1]) => selection.value[1] = value);
ImGui.Text("3. I am not selectable");
ImGui.Selectable("4. I am selectable", (value = selection.value[3]) => selection.value[2] = value);
if (ImGui.Selectable("5. I am double clickable", selection.value[4], imgui_12.ImGuiSelectableFlags.AllowDoubleClick))
if (ImGui.IsMouseDoubleClicked(0))
selection.value[4] = !selection.value[4];
ImGui.TreePop();
}
if (ImGui.TreeNode("Selection State: Single Selection")) {
/* static */ const selected = STATIC("selected#707", -1);
for (let n = 0; n < 5; n++) {
const buf = `Object ${n}`;
if (ImGui.Selectable(buf, selected.value === n))
selected.value = n;
}
ImGui.TreePop();
}
if (ImGui.TreeNode("Selection State: Multiple Selection")) {
ShowHelpMarker("Hold CTRL and click to select multiple items.");
/* static */ const selection = STATIC("selection#720", [false, false, false, false, false]);
for (let n = 0; n < 5; n++) {
const buf = `Object ${n}`;
if (ImGui.Selectable(buf, selection.value[n])) {
if (!ImGui.GetIO().KeyCtrl) // Clear selection when CTRL is not held
// memset(selection, 0, sizeof(selection));
selection.value.fill(false);
selection.value[n] = !selection.value[n];
}
}
ImGui.TreePop();
}
if (ImGui.TreeNode("Rendering more text into the same line")) {
// Using the Selectable() override that takes "bool* p_selected" parameter and toggle your booleans automatically.
/* static */ const selected = STATIC("selected#687", [false, false, false]);
ImGui.Selectable("main.c", (value = selected.value[0]) => selected.value[0] = value);
ImGui.SameLine(300);
ImGui.Text(" 2,345 bytes");
ImGui.Selectable("Hello.cpp", (value = selected.value[1]) => selected.value[1] = value);
ImGui.SameLine(300);
ImGui.Text("12,345 bytes");
ImGui.Selectable("Hello.h", (value = selected.value[2]) => selected.value[2] = value);
ImGui.SameLine(300);
ImGui.Text(" 2,345 bytes");
ImGui.TreePop();
}
if (ImGui.TreeNode("In columns")) {
ImGui.Columns(3, null, false);
/* static */ const selected = STATIC("selected#699", new Array(16).fill(false));
for (let i = 0; i < 16; i++) {
const label = `Item ${i}`;
if (ImGui.Selectable(label, (value = selected.value[i]) => selected.value[i] = value)) { }
ImGui.NextColumn();
}
ImGui.Columns(1);
ImGui.TreePop();
}
if (ImGui.TreeNode("Grid")) {
/* static */ const selected = STATIC("selected#712", [true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true]);
for (let i = 0; i < 16; i++) {
ImGui.PushID(i);
if (ImGui.Selectable("Sailor", (value = selected.value[i]) => selected.value[i] = value, 0, new imgui_18.ImVec2(50, 50))) {
const x = i % 4, y = i / 4;
if (x > 0)
selected.value[i - 1] = !selected.value[i - 1];
if (x < 3)
selected.value[i + 1] = !selected.value[i + 1];
if (y > 0)
selected.value[i - 4] = !selected.value[i - 4];
if (y < 3)
selected.value[i + 4] = !selected.value[i + 4];
}
if ((i % 4) < 3)
ImGui.SameLine();
ImGui.PopID();
}
ImGui.TreePop();
}
ImGui.TreePop();
}
if (ImGui.TreeNode("Filtered Text Input")) {
/* static */ const buf1 = STATIC("buf1", new imgui_4.ImStringBuffer(64, ""));
ImGui.InputText("default", buf1.value, imgui_3.IM_ARRAYSIZE(buf1.value));
/* static */ const buf2 = STATIC("buf2", new imgui_4.ImStringBuffer(64, ""));
ImGui.InputText("decimal", buf2.value, imgui_3.IM_ARRAYSIZE(buf2.value), imgui_10.ImGuiInputTextFlags.CharsDecimal);
/* static */ const buf3 = STATIC("buf3", new imgui_4.ImStringBuffer(64, ""));
ImGui.InputText("hexadecimal", buf3.value, imgui_3.IM_ARRAYSIZE(buf3.value), imgui_10.ImGuiInputTextFlags.CharsHexadecimal | imgui_10.ImGuiInputTextFlags.CharsUppercase);
/* static */ const buf4 = STATIC("buf4", new imgui_4.ImStringBuffer(64, ""));
ImGui.InputText("uppercase", buf4.value, imgui_3.IM_ARRAYSIZE(buf4.value), imgui_10.ImGuiInputTextFlags.CharsUppercase);
/* static */ const buf5 = STATIC("buf5", new imgui_4.ImStringBuffer(64, ""));
ImGui.InputText("no blank", buf5.value, imgui_3.IM_ARRAYSIZE(buf5.value), imgui_10.ImGuiInputTextFlags.CharsNoBlank);
class TextFilters {
static FilterImGuiLetters(data) { if (data.EventChar < 256 && /[imgui]/.test(String.fromCharCode(data.EventChar)))
return 0; return 1; }
}
/* static */ const buf6 = STATIC("buf6", new imgui_4.ImStringBuffer(64, ""));
ImGui.InputText("\"imgui\" letters", buf6.value, imgui_3.IM_ARRAYSIZE(buf6.value), imgui_10.ImGuiInputTextFlags.CallbackCharFilter, TextFilters.FilterImGuiLetters);
ImGui.Text("Password input");
/* static */ const bufpass = STATIC("bufpass", new imgui_4.ImStringBuffer(64, "password123"));
ImGui.InputText("password", bufpass.value, imgui_3.IM_ARRAYSIZE(bufpass.value), imgui_10.ImGuiInputTextFlags.Password | imgui_10.ImGuiInputTextFlags.CharsNoBlank);
ImGui.SameLine();
ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n");
ImGui.InputText("password (clear)", bufpass.value, imgui_3.IM_ARRAYSIZE(bufpass.value), imgui_10.ImGuiInputTextFlags.CharsNoBlank);
ImGui.TreePop();
}
if (ImGui.TreeNode("Multi-line Text Input")) {
/* static */ const read_only = STATIC("read_only", false);
/* static */ const text = STATIC("text", new imgui_4.ImStringBuffer(1024 * 16, "/*\n" +
" The Pentium F00F bug, shorthand for F0 0F C7 C8,\n" +
" the hexadecimal encoding of one offending instruction,\n" +
" more formally, the invalid operand with locked CMPXCHG8B\n" +
" instruction bug, is a design flaw in the majority of\n" +
" Intel Pentium, Pentium MMX, and Pentium OverDrive\n" +
" processors (all in the P5 microarchitecture).\n" +
"*/\n\n" +
"label:\n" +
"\tlock cmpxchg8b eax\n"));
ShowHelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/stl/imgui_stl.h for an example. (This is not demonstrated in imgui_demo.cpp)");
ImGui.Checkbox("Read-only", (value = read_only.value) => read_only.value = value);
const flags = imgui_10.ImGuiInputTextFlags.AllowTabInput | (read_only.value ? imgui_10.ImGuiInputTextFlags.ReadOnly : 0);
ImGui.InputTextMultiline("##source", text.value, imgui_3.IM_ARRAYSIZE(text.value), new imgui_18.ImVec2(-1.0, ImGui.GetTextLineHeight() * 16), flags);
ImGui.TreePop();
}
if (ImGui.TreeNode("Plots Widgets")) {
/* static */ const animate = STATIC("animate", true);
ImGui.Checkbox("Animate", (value = animate.value) => animate.value = value);
/* static */ const arr = STATIC("arr", [0.6, 0.1, 1.0, 0.5, 0.92, 0.1, 0.2]);
ImGui.PlotLines("Frame Times", arr.value, imgui_3.IM_ARRAYSIZE(arr.value));
// Create a dummy array of contiguous float values to plot
// Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float and the sizeof() of your structure in the Stride parameter.
/* static */ const values = STATIC("values#803", new Array(90).fill(0));
/* static */ const values_offset = STATIC("values_offset", 0);
/* static */ const refresh_time = STATIC("refresh_time", 0.0);
if (!animate.value || refresh_time.value === 0.0)
refresh_time.value = ImGui.GetTime();
while (refresh_time.value < ImGui.GetTime()) // Create dummy data at fixed 60 hz rate for the demo
{
/* static */ const phase = STATIC("phase", 0.0);
values.value[values_offset.value] = Math.cos(phase.value);
values_offset.value = (values_offset.value + 1) % imgui_3.IM_ARRAYSIZE(values.value);
phase.value += 0.10 * values_offset.value;
refresh_time.value += 1.0 / 60.0;
}
ImGui.PlotLines("Lines", values.value, imgui_3.IM_ARRAYSIZE(values.value), values_offset.value, "avg 0.0", -1.0, 1.0, new imgui_18.ImVec2(0, 80));
ImGui.PlotHistogram("Histogram", arr.value, imgui_3.IM_ARRAYSIZE(arr.value), 0, null, 0.0, 1.0, new imgui_18.ImVec2(0, 80));
// Use functions to generate output
// FIXME: This is rather awkward because current plot API only pass in indices. We probably want an API passing floats and user provide sample rate/count.
class Funcs {
static Sin(data, i) { return Math.sin(i * 0.1); }
static Saw(data, i) { return (i & 1) ? 1.0 : -1.0; }
}
/* static */ const func_type = STATIC("func_type", 0), display_count = STATIC("display_count", 70);
ImGui.Separator();
ImGui.PushItemWidth(100);
ImGui.Combo("func", (value = func_type.value) => func_type.value = value, "Sin\0Saw\0");
ImGui.PopItemWidth();
ImGui.SameLine();
ImGui.SliderInt("Sample count", (value = display_count.value) => display_count.value = value, 1, 400);
const func = (func_type.value === 0) ? Funcs.Sin : Funcs.Saw;
ImGui.PlotLines("Lines", func, null, display_count.value, 0, null, -1.0, 1.0, new imgui_18.ImVec2(0, 80));
ImGui.PlotHistogram("Histogram", func, null, display_count.value, 0, null, -1.0, 1.0, new imgui_18.ImVec2(0, 80));
ImGui.Separator();
// Animate a simple progress bar
/* static */ const progress = STATIC("progress", 0.0), progress_dir = STATIC("progress_dir", 1.0);
if (animate.value) {
progress.value += progress_dir.value * 0.4 * ImGui.GetIO().DeltaTime;
if (progress.value >= +1.1) {
progress.value = +1.1;
progress_dir.value *= -1.0;
}
if (progress.value <= -0.1) {
progress.value = -0.1;
progress_dir.value *= -1.0;
}
}
// Typically we would use ImVec2(-1.0f,0.0) to use all available width, or ImVec2(width,0.0) for a specified width. ImVec2(0.0,0.0) uses ItemWidth.
ImGui.ProgressBar(progress.value, new imgui_18.ImVec2(0.0, 0.0));
ImGui.SameLine(0.0, ImGui.GetStyle().ItemInnerSpacing.x);
ImGui.Text("Progress Bar");
const progress_saturated = (progress.value < 0.0) ? 0.0 : (progress.value > 1.0) ? 1.0 : progress.value;
const buf = `${(progress_saturated * 1753).toFixed(0)}/${1753}`;
ImGui.ProgressBar(progress.value, new imgui_18.ImVec2(0., 0.), buf);
ImGui.TreePop();
}
if (ImGui.TreeNode("Color/Picker Widgets")) {
/* static */ const color = STATIC("color#863", new imgui_21.ImColor(114, 144, 154, 200).toImVec4());
/* static */ const alpha_preview = STATIC("alpha_preview", true);
/* static */ const alpha_half_preview = STATIC("alpha_half_preview", false);
/* static */ const drag_and_drop = STATIC("drag_and_drop", true);
/* static */ const options_menu = STATIC("options_menu", true);
/* static */ const hdr = STATIC("hdr", false);
ImGui.Checkbox("With Alpha Preview", (value = alpha_preview.value) => alpha_preview.value = value);
ImGui.Checkbox("With Half Alpha Preview", (value = alpha_half_preview.value) => alpha_half_preview.value = value);
ImGui.Checkbox("With Drag and Drop", (value = drag_and_drop.value) => drag_and_drop.value = value);
ImGui.Checkbox("With Options Menu", (value = options_menu.value) => options_menu.value = value);
ImGui.SameLine();
ShowHelpMarker("Right-click on the individual color widget to show options.");
ImGui.Checkbox("With HDR", (value = hdr.value) => hdr.value = value);
ImGui.SameLine();
ShowHelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
const misc_flags = (hdr.value ? imgui_6.ImGuiColorEditFlags.HDR : 0) | (drag_and_drop.value ? 0 : imgui_6.ImGuiColorEditFlags.NoDragDrop) | (alpha_half_preview.value ? imgui_6.ImGuiColorEditFlags.AlphaPreviewHalf : (alpha_preview.value ? imgui_6.ImGuiColorEditFlags.AlphaPreview : 0)) | (options_menu.value ? 0 : imgui_6.ImGuiColorEditFlags.NoOptions);
ImGui.Text("Color widget:");
ImGui.SameLine();
ShowHelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n");
ImGui.ColorEdit3("MyColor##1", color.value, misc_flags);
ImGui.Text("Color widget HSV with Alpha:");
ImGui.ColorEdit4("MyColor##2", color.value, imgui_6.ImGuiColorEditFlags.HSV | misc_flags);
ImGui.Text("Color widget with Float Display:");
ImGui.ColorEdit4("MyColor##2f", color.value, imgui_6.ImGuiColorEditFlags.Float | misc_flags);
ImGui.Text("Color button with Picker:");
ImGui.SameLine();
ShowHelpMarker("With the ImGuiColorEditFlags.NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags.NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup.");
ImGui.ColorEdit4("MyColor##3", color.value, imgui_6.ImGuiColorEditFlags.NoInputs | imgui_6.ImGuiColorEditFlags.NoLabel | misc_flags);
ImGui.Text("Color button with Custom Picker Popup:");
// Generate a dummy palette
/* static */ const saved_palette_inited = STATIC("saved_palette_inited", false);
/* static */ const saved_palette = STATIC("saved_palette", []);
if (!saved_palette_inited.value)
for (let n = 0; n < 32; n++) {
saved_palette.value[n] = new imgui_19.ImVec4();
// ImGui.ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, saved_palette[n].x, saved_palette[n].y, saved_palette[n].z);
const r = [0.0];
const g = [0.0];
const b = [0.0];
ImGui.ColorConvertHSVtoRGB(n / 32.0, 0.8, 0.8, r, g, b);
saved_palette.value[n].x = r[0];
saved_palette.value[n].y = g[0];
saved_palette.value[n].z = b[0];
saved_palette.value[n].w = 1.0; // Alpha
}
saved_palette_inited.value = true;
/* static */ const backup_color = STATIC("backup_color", new imgui_19.ImVec4());
let open_popup = ImGui.ColorButton("MyColor##3b", color.value, misc_flags);
ImGui.SameLine();
open_popup = open_popup || ImGui.Button("Palette");
if (open_popup) {
ImGui.OpenPopup("mypicker");
backup_color.value.Copy(color.value);
}
if (ImGui.BeginPopup("mypicker")) {
// FIXME: Adding a drag and drop example here would be perfect!
ImGui.Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!");
ImGui.Separator();
ImGui.ColorPicker4("##picker", color.value, misc_flags | imgui_6.ImGuiColorEditFlags.NoSidePreview | imgui_6.ImGuiColorEditFlags.NoSmallPreview);
ImGui.SameLine();
ImGui.BeginGroup();
ImGui.Text("Current");
ImGui.ColorButton("##current", color.value, imgui_6.ImGuiColorEditFlags.NoPicker | imgui_6.ImGuiColorEditFlags.AlphaPreviewHalf, new imgui_18.ImVec2(60, 40));
ImGui.Text("Previous");
if (ImGui.ColorButton("##previous", backup_color.value, imgui_6.ImGuiColorEditFlags.NoPicker | imgui_6.ImGuiColorEditFlags.AlphaPreviewHalf, new imgui_18.ImVec2(60, 40)))
color.value.Copy(backup_color.value);
ImGui.Separator();
ImGui.Text("Palette");
for (let n = 0; n < imgui_3.IM_ARRAYSIZE(saved_palette.value); n++) {
ImGui.PushID(n);
if ((n % 8) !== 0)
ImGui.SameLine(0.0, ImGui.GetStyle().ItemSpacing.y);
if (ImGui.ColorButton("##palette", saved_palette.value[n], imgui_6.ImGuiColorEditFlags.NoAlpha | imgui_6.ImGuiColorEditFlags.NoPicker | imgui_6.ImGuiColorEditFlags.NoTooltip, new imgui_18.ImVec2(20, 20)))
color.value.Copy(new imgui_19.ImVec4(saved_palette.value[n].x, saved_palette.value[n].y, saved_palette.value[n].z, color.value.w)); // Preserve alpha!
if (ImGui.BeginDragDropTarget()) {
// if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
// memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3);
// if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
// memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4);
ImGui.EndDragDropTarget();
}
ImGui.PopID();
}
ImGui.EndGroup();
ImGui.EndPopup();
}
ImGui.Text("Color button only:");
ImGui.ColorButton("MyColor##3c", color.value, misc_flags, new imgui_18.ImVec2(80, 80));
ImGui.Text("Color picker:");
/* static */ const alpha = STATIC("alpha", true);
/* static */ const alpha_bar = STATIC("alpha_bar", true);
/* static */ const side_preview = STATIC("side_preview", true);
/* static */ const ref_color = STATIC("ref_color", false);
/* static */ const ref_color_v = STATIC("ref_color_v", new imgui_19.ImVec4(1.0, 0.0, 1.0, 0.5));
/* static */ const inputs_mode = STATIC("inputs_mode", 2);
/* static */ const picker_mode = STATIC("picker_mode", 0);
ImGui.Checkbox("With Alpha", (value = alpha.value) => alpha.value = value);
ImGui.Checkbox("With Alpha Bar", (value = alpha_bar.value) => alpha_bar.value = value);
ImGui.Checkbox("With Side Preview", (value = side_preview.value) => side_preview.value = value);
if (side_preview) {
ImGui.SameLine();
ImGui.Checkbox("With Ref Color", (value = ref_color.value) => ref_color.value = value);
if (ref_color.value) {
ImGui.SameLine();
ImGui.ColorEdit4("##RefColor", ref_color_v.value, imgui_6.ImGuiColorEditFlags.NoInputs | misc_flags);
}
}
ImGui.Combo("Inputs Mode", (value = inputs_mode.value) => inputs_mode.value = value, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0");
ImGui.Combo("Picker Mode", (value = picker_mode.value) => picker_mode.value = value, "Auto/Current\0Hue bar + SV rect\0Hue wheel + SV triangle\0");
ImGui.SameLine();
ShowHelpMarker("User can right-click the picker to change mode.");
let flags = misc_flags;
if (!alpha.value)
flags |= imgui_6.ImGuiColorEditFlags.NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4()
if (alpha_bar.value)
flags |= imgui_6.ImGuiColorEditFlags.AlphaBar;
if (!side_preview.value)
flags |= imgui_6.ImGuiColorEditFlags.NoSidePreview;
if (picker_mode.value === 1)
flags |= imgui_6.ImGuiColorEditFlags.PickerHueBar;
if (picker_mode.value === 2)
flags |= imgui_6.ImGuiColorEditFlags.PickerHueWheel;
if (inputs_mode.value === 1)
flags |= imgui_6.ImGuiColorEditFlags.NoInputs;
if (inputs_mode.value === 2)
flags |= imgui_6.ImGuiColorEditFlags.RGB;
if (inputs_mode.value === 3)
flags |= imgui_6.ImGuiColorEditFlags.HSV;
if (inputs_mode.value === 4)
flags |= imgui_6.ImGuiColorEditFlags.HEX;
ImGui.ColorPicker4("MyColor##4", color.value, flags, ref_color.value ? ref_color_v.value : null);
ImGui.Text("Programmatically set defaults:");
ImGui.SameLine();
ShowHelpMarker("SetColorEditOptions() is designed to allow you to set boot-time default.\nWe don't have Push/Pop functions because you can force options on a per-widget basis if needed, and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid encouraging you to persistently save values that aren't forward-compatible.");
if (ImGui.Button("Default: Uint8 + HSV + Hue Bar"))
ImGui.SetColorEditOptions(imgui_6.ImGuiColorEditFlags.Uint8 | imgui_6.ImGuiColorEditFlags.HSV | imgui_6.ImGuiColorEditFlags.PickerHueBar);
if (ImGui.Button("Default: Float + HDR + Hue Wheel"))
ImGui.SetColorEditOptions(imgui_6.ImGuiColorEditFlags.Float | imgui_6.ImGuiColorEditFlags.RGB | imgui_6.ImGuiColorEditFlags.PickerHueWheel);
ImGui.TreePop();
}
if (ImGui.TreeNode("Range Widgets")) {
/* static */ const begin = STATIC("begin", 10), end = STATIC("end", 90);
/* static */ const begin_i = STATIC("begin_i", 100), end_i = STATIC("end_i", 1000);
ImGui.DragFloatRange2("range", (value = begin.value) => begin.value = value, (value = end.value) => end.value = value, 0.25, 0.0, 100.0, "Min: %.1f %%", "Max: %.1f %%");
ImGui.DragIntRange2("range int (no bounds)", (value = begin_i.value) => begin_i.value = value, (value = end_i.value) => end_i.value = value, 5, 0, 0, "Min: %d units", "Max: %d units");
ImGui.TreePop();
}
if (ImGui.TreeNode("Data Types")) {
// The DragScalar/InputScalar/SliderScalar functions allow various data types: signed/unsigned int/long long and float/double
// To avoid polluting the public API with all possible combinations, we use the ImGuiDataType enum to pass the type,
// and passing all arguments by address.
// This is the reason the test code below creates local variables to hold "zero" "one" etc. for each types.
// In practice, if you frequently use a given type that is not covered by the normal API entry points, you can wrap it
// yourself inside a 1 line function which can take typed argument as value instead of void*, and then pass their address
// to the generic function. For example:
// bool MySliderU64(const char *label, u64* value, u64 min = 0, u64 max = 0, const char* format = "%lld")
// {
// return SliderScalar(label, ImGuiDataType_U64, value, &min, &max, format);
// }
// Limits (as helper variables that we can take the address of)
// Note that the SliderScalar function has a maximum usable range of half the natural type maximum, hence the /2 below.
const INT_MIN = -2147483648; // 0x80000000
const INT_MAX = +2147483647; // 0x7fffffff
const UINT_MAX = +4294967295; // 0xffffffff
// const LLONG_MIN = -9223372036854775808; // 0x8000000000000000
// const LLONG_MAX = +9223372036854775807; // 0x7fffffffffffffff
// const ULLONG_MAX = +18446744073709551615; // 0xffffffffffffffff
const s32_zero = 0, s32_one = 1, s32_fifty = 50, s32_min = INT_MIN / 2, s32_max = INT_MAX / 2, s32_hi_a = INT_MAX / 2 - 100, s32_hi_b = INT_MAX / 2;
const u32_zero = 0, u32_one = 1, u32_fifty = 50, u32_min = 0, u32_max = UINT_MAX / 2, u32_hi_a = UINT_MAX / 2 - 100, u32_hi_b = UINT_MAX / 2;
// const s64_zero = 0, s64_one = 1, s64_fifty = 50, s64_min = LLONG_MIN / 2, s64_max = LLONG_MAX / 2, s64_hi_a = LLONG_MAX / 2 - 100, s64_hi_b = LLONG_MAX / 2;
// const u64_zero = 0, u64_one = 1, u64_fifty = 50, u64_min = 0, u64_max = ULLONG_MAX / 2, u64_hi_a = ULLONG_MAX / 2 - 100, u64_hi_b = ULLONG_MAX / 2;
const f32_zero = 0.0, f32_one = 1.0, f32_lo_a = -10000000000.0, f32_hi_a = +10000000000.0;
const f64_zero = 0.0, f64_one = 1.0, f64_lo_a = -1000000000000000.0, f64_hi_a = +1000000000000000.0;
// State
// static ImS32 s32_v = -1;
// static ImU32 u32_v = (ImU32)-1;
// static ImS64 s64_v = -1;
// static ImU64 u64_v = (ImU64)-1;
// static float f32_v = 0.123f;
// static double f64_v = 90000.01234567890123456789;
/* static */ const s32_v = STATIC("s32_v", new Int32Array([-1]));
/* static */ const u32_v = STATIC("u32_v", new Uint32Array([-1]));
// /* static */ const s64_v = STATIC("s64_v", new Int64Array([-1]));
// /* static */ const u64_v = STATIC("u64_v", new Uint64Array([-1]));
/* static */ const f32_v = STATIC("f32_v", new Float32Array([0.123]));
/* static */ const f64_v = STATIC("f64_v", new Float64Array([90000.01234567890123456789]));
const drag_speed = 0.2;
/* static */ const drag_clamp = STATIC("drag_clamp", false);
ImGui.Text("Drags:");
ImGui.Checkbox("Clamp integers to 0..50", (value = drag_clamp.value) => drag_clamp.value = value);
ImGui.SameLine();
ShowHelpMarker("As with every widgets in dear imgui, we never modify values unless there is a user interaction.\nYou can override the clamping limits by using CTRL+Click to input a value.");
// ImGui.DragScalar("drag s32", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp.value ? &s32_zero : null, drag_clamp.value ? &s32_fifty : null);
// ImGui.DragScalar("drag u32", ImGuiDataType_U32, &u32_v, drag_speed, drag_clamp.value ? &u32_zero : null, drag_clamp.value ? &u32_fifty : null, "%u ms");