-
Notifications
You must be signed in to change notification settings - Fork 0
/
imgui_demo.cpp
3772 lines (3414 loc) · 188 KB
/
imgui_demo.cpp
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.66b
// (demo code)
// Message to the person tempted to delete this file when integrating Dear ImGui into their code base:
// Do NOT remove this file from your project! Think again! It is the most useful reference code that you and other coders
// will want to refer to and call. Have the ImGui::ShowDemoWindow() function wired in an always-available debug menu of
// your game/app! Removing this file from your project is hindering access to documentation for everyone in your team,
// likely leading you to poorer usage of the library.
// Everything in this file will be stripped out by the linker if you don't call ImGui::ShowDemoWindow().
// If you want to link core Dear ImGui in your shipped builds but want an easy guarantee that the demo will not be linked,
// you can setup your imconfig.h with #define IMGUI_DISABLE_DEMO_WINDOWS and those functions will be empty.
// In other situation, whenever you have Dear ImGui available you probably want this to be available for reference.
// Thank you,
// -Your beloved friend, imgui_demo.cpp (that you won't delete)
// Message to beginner C/C++ programmers about the meaning of the 'static' keyword:
// In this demo code, we frequently we use 'static' variables inside functions. A static variable persist across calls, so it is
// essentially like a global variable but declared inside the scope of the function. We do this as a way to gather code and data
// in the same place, to make the demo source code faster to read, faster to write, and smaller in size.
// It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be reentrant
// or used in threads. This might be a pattern you will want to use in your code, but most of the real data you would be editing is
// likely going to be stored outside your functions.
/*
Index of this file:
// [SECTION] Forward Declarations, Helpers
// [SECTION] Demo Window / ShowDemoWindow()
// [SECTION] About Window / ShowAboutWindow()
// [SECTION] Style Editor / ShowStyleEditor()
// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar()
// [SECTION] Example App: Debug Console / ShowExampleAppConsole()
// [SECTION] Example App: Debug Log / ShowExampleAppLog()
// [SECTION] Example App: Simple Layout / ShowExampleAppLayout()
// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor()
// [SECTION] Example App: Long Text / ShowExampleAppLongText()
// [SECTION] Example App: Auto Resize / ShowExampleAppAutoResize()
// [SECTION] Example App: Constrained Resize / ShowExampleAppConstrainedResize()
// [SECTION] Example App: Simple Overlay / ShowExampleAppSimpleOverlay()
// [SECTION] Example App: Manipulating Window Titles / ShowExampleAppWindowTitles()
// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering()
*/
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "imgui.h"
#include <ctype.h> // toupper, isprint
#include <limits.h> // INT_MIN, INT_MAX
#include <math.h> // sqrtf, powf, cosf, sinf, floorf, ceilf
#include <stdio.h> // vsnprintf, sscanf, printf
#include <stdlib.h> // NULL, malloc, free, atoi
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t
#endif
#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#define vsnprintf _vsnprintf
#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
// Play it nice with Windows users. Notepad in 2017 still doesn't display text data with Unix-style \n.
#ifdef _WIN32
#define IM_NEWLINE "\r\n"
#else
#define IM_NEWLINE "\n"
#endif
#define IM_MAX(_A,_B) (((_A) >= (_B)) ? (_A) : (_B))
//-----------------------------------------------------------------------------
// [SECTION] Forward Declarations, Helpers
//-----------------------------------------------------------------------------
#if !defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS) && defined(IMGUI_DISABLE_TEST_WINDOWS) && !defined(IMGUI_DISABLE_DEMO_WINDOWS) // Obsolete name since 1.53, TEST->DEMO
#define IMGUI_DISABLE_DEMO_WINDOWS
#endif
#if !defined(IMGUI_DISABLE_DEMO_WINDOWS)
// Forward Declarations
static void ShowExampleAppMainMenuBar();
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 ShowExampleMenuFile();
// Helper to display a little (?) mark which shows a tooltip when hovered.
static void ShowHelpMarker(const char* desc)
{
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(desc);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}
// Helper to display basic user controls.
void ImGui::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();
}
//-----------------------------------------------------------------------------
// [SECTION] Demo Window / ShowDemoWindow()
//-----------------------------------------------------------------------------
// We split the contents of the big ShowDemoWindow() function into smaller functions (because the link time of very large functions grow non-linearly)
static void ShowDemoWindowWidgets();
static void ShowDemoWindowLayout();
static void ShowDemoWindowPopups();
static void ShowDemoWindowColumns();
static void ShowDemoWindowMisc();
// 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.
void ImGui::ShowDemoWindow(bool* p_open)
{
// Examples Apps (accessible from the "Examples" menu)
static bool show_app_main_menu_bar = false;
static bool show_app_console = false;
static bool show_app_log = false;
static bool show_app_layout = false;
static bool show_app_property_editor = false;
static bool show_app_long_text = false;
static bool show_app_auto_resize = false;
static bool show_app_constrained_resize = false;
static bool show_app_simple_overlay = false;
static bool show_app_window_titles = false;
static bool show_app_custom_rendering = false;
if (show_app_main_menu_bar) ShowExampleAppMainMenuBar();
if (show_app_console) ShowExampleAppConsole(&show_app_console);
if (show_app_log) ShowExampleAppLog(&show_app_log);
if (show_app_layout) ShowExampleAppLayout(&show_app_layout);
if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor);
if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text);
if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize);
if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize);
if (show_app_simple_overlay) ShowExampleAppSimpleOverlay(&show_app_simple_overlay);
if (show_app_window_titles) ShowExampleAppWindowTitles(&show_app_window_titles);
if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering);
// Dear ImGui Apps (accessible from the "Help" menu)
static bool show_app_metrics = false;
static bool show_app_style_editor = false;
static bool show_app_about = false;
if (show_app_metrics) { ImGui::ShowMetricsWindow(&show_app_metrics); }
if (show_app_style_editor) { ImGui::Begin("Style Editor", &show_app_style_editor); ImGui::ShowStyleEditor(); ImGui::End(); }
if (show_app_about) { ShowAboutWindow(&show_app_about); }
// Demonstrate the various window flags. Typically you would just use the default!
static bool no_titlebar = false;
static bool no_scrollbar = false;
static bool no_menu = false;
static bool no_move = false;
static bool no_resize = false;
static bool no_collapse = false;
static bool no_close = false;
static bool no_nav = false;
static bool no_background = false;
static bool no_bring_to_front = false;
ImGuiWindowFlags window_flags = 0;
if (no_titlebar) window_flags |= ImGuiWindowFlags_NoTitleBar;
if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar;
if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar;
if (no_move) window_flags |= ImGuiWindowFlags_NoMove;
if (no_resize) window_flags |= ImGuiWindowFlags_NoResize;
if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse;
if (no_nav) window_flags |= ImGuiWindowFlags_NoNav;
if (no_background) window_flags |= ImGuiWindowFlags_NoBackground;
if (no_bring_to_front) window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus;
if (no_close) 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(ImVec2(650, 20), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(550, 680), 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;
}
ImGui::Text("dear imgui says hello. (%s)", IMGUI_VERSION);
// Most "big" widgets share a common width settings by default.
//ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f); // 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, &show_app_main_menu_bar);
ImGui::MenuItem("Console", NULL, &show_app_console);
ImGui::MenuItem("Log", NULL, &show_app_log);
ImGui::MenuItem("Simple layout", NULL, &show_app_layout);
ImGui::MenuItem("Property editor", NULL, &show_app_property_editor);
ImGui::MenuItem("Long text display", NULL, &show_app_long_text);
ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize);
ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize);
ImGui::MenuItem("Simple overlay", NULL, &show_app_simple_overlay);
ImGui::MenuItem("Manipulating window titles", NULL, &show_app_window_titles);
ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Help"))
{
ImGui::MenuItem("Metrics", NULL, &show_app_metrics);
ImGui::MenuItem("Style Editor", NULL, &show_app_style_editor);
ImGui::MenuItem("About Dear ImGui", NULL, &show_app_about);
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
ImGui::Spacing();
if (ImGui::CollapsingHeader("Help"))
{
ImGui::Text("PROGRAMMER GUIDE:");
ImGui::BulletText("Please see the ShowDemoWindow() code in imgui_demo.cpp. <- you are here!");
ImGui::BulletText("Please see the comments in imgui.cpp.");
ImGui::BulletText("Please see the examples/ in application.");
ImGui::BulletText("Enable 'io.ConfigFlags |= NavEnableKeyboard' for keyboard controls.");
ImGui::BulletText("Enable 'io.ConfigFlags |= NavEnableGamepad' for gamepad controls.");
ImGui::Separator();
ImGui::Text("USER GUIDE:");
ImGui::ShowUserGuide();
}
if (ImGui::CollapsingHeader("Configuration"))
{
ImGuiIO& io = ImGui::GetIO();
if (ImGui::TreeNode("Configuration##2"))
{
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
ImGui::SameLine(); ShowHelpMarker("Required back-end to feed in gamepad inputs in io.NavInputs[] and set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details.");
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos);
ImGui::SameLine(); ShowHelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos.");
ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouse);
if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) // Create a way to restore this flag otherwise we could be stuck completely!
{
if (fmodf((float)ImGui::GetTime(), 0.40f) < 0.20f)
{
ImGui::SameLine();
ImGui::Text("<<PRESS SPACE TO DISABLE>>");
}
if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Space)))
io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
}
ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
ImGui::SameLine(); ShowHelpMarker("Instruct back-end to not alter mouse cursor shape and visibility.");
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
ImGui::SameLine(); ShowHelpMarker("Set to false to disable blinking cursor, for users who consider it distracting");
ImGui::Checkbox("io.ConfigResizeWindowsFromEdges [beta]", &io.ConfigResizeWindowsFromEdges);
ImGui::SameLine(); ShowHelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback.");
ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor);
ImGui::SameLine(); ShowHelpMarker("Instruct Dear ImGui to render a mouse cursor for you. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something).");
ImGui::TreePop();
ImGui::Separator();
}
if (ImGui::TreeNode("Backend Flags"))
{
ImGuiBackendFlags backend_flags = io.BackendFlags; // Make a local copy to avoid modifying the back-end flags.
ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasGamepad);
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasMouseCursors);
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasSetMousePos);
ImGui::TreePop();
ImGui::Separator();
}
if (ImGui::TreeNode("Style"))
{
ImGui::ShowStyleEditor();
ImGui::TreePop();
ImGui::Separator();
}
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.");
ShowHelpMarker("Try opening any of the contents below in this window and then click one of the \"Log To\" button.");
ImGui::LogButtons();
ImGui::TextWrapped("You can also call ImGui::LogText() to output directly to the log without a visual output.");
if (ImGui::Button("Copy \"Hello, world!\" to clipboard"))
{
ImGui::LogToClipboard();
ImGui::LogText("Hello, world!");
ImGui::LogFinish();
}
ImGui::TreePop();
}
}
if (ImGui::CollapsingHeader("Window options"))
{
ImGui::Checkbox("No titlebar", &no_titlebar); ImGui::SameLine(150);
ImGui::Checkbox("No scrollbar", &no_scrollbar); ImGui::SameLine(300);
ImGui::Checkbox("No menu", &no_menu);
ImGui::Checkbox("No move", &no_move); ImGui::SameLine(150);
ImGui::Checkbox("No resize", &no_resize); ImGui::SameLine(300);
ImGui::Checkbox("No collapse", &no_collapse);
ImGui::Checkbox("No close", &no_close); ImGui::SameLine(150);
ImGui::Checkbox("No nav", &no_nav); ImGui::SameLine(300);
ImGui::Checkbox("No background", &no_background);
ImGui::Checkbox("No bring to front", &no_bring_to_front);
}
// All demo contents
ShowDemoWindowWidgets();
ShowDemoWindowLayout();
ShowDemoWindowPopups();
ShowDemoWindowColumns();
ShowDemoWindowMisc();
// End of ShowDemoWindow()
ImGui::End();
}
static void ShowDemoWindowWidgets()
{
if (!ImGui::CollapsingHeader("Widgets"))
return;
if (ImGui::TreeNode("Basic"))
{
static int clicked = 0;
if (ImGui::Button("Button"))
clicked++;
if (clicked & 1)
{
ImGui::SameLine();
ImGui::Text("Thanks for clicking me!");
}
static bool check = true;
ImGui::Checkbox("checkbox", &check);
static int e = 0;
ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine();
ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine();
ImGui::RadioButton("radio c", &e, 2);
// Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style.
for (int i = 0; i < 7; i++)
{
if (i > 0)
ImGui::SameLine();
ImGui::PushID(i);
ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(i/7.0f, 0.6f, 0.6f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(i/7.0f, 0.7f, 0.7f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(i/7.0f, 0.8f, 0.8f));
ImGui::Button("Click");
ImGui::PopStyleColor(3);
ImGui::PopID();
}
// Use AlignTextToFramePadding() to align text baseline to the baseline of framed elements (otherwise a Text+SameLine+Button sequence will have the text a little too high by default)
ImGui::AlignTextToFramePadding();
ImGui::Text("Hold to repeat:");
ImGui::SameLine();
// Arrow buttons with Repeater
static int counter = 0;
float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
ImGui::PushButtonRepeat(true);
if (ImGui::ArrowButton("##left", ImGuiDir_Left)) { counter--; }
ImGui::SameLine(0.0f, spacing);
if (ImGui::ArrowButton("##right", ImGuiDir_Right)) { counter++; }
ImGui::PopButtonRepeat();
ImGui::SameLine();
ImGui::Text("%d", counter);
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 float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr));
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 char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" };
static int item_current = 0;
ImGui::Combo("combo", &item_current, items, IM_ARRAYSIZE(items));
ImGui::SameLine(); ShowHelpMarker("Refer to the \"Combo\" section below for an explanation of the full BeginCombo/EndCombo API, and demonstration of various flags.\n");
}
{
static char str0[128] = "Hello, world!";
static int i0 = 123;
ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0));
ImGui::SameLine(); ShowHelpMarker("USER:\nHold 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\nPROGRAMMER:\nYou can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated in imgui_demo.cpp).");
ImGui::InputInt("input int", &i0);
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 float f0 = 0.001f;
ImGui::InputFloat("input float", &f0, 0.01f, 1.0f);
static double d0 = 999999.00000001;
ImGui::InputDouble("input double", &d0, 0.01f, 1.0f, "%.8f");
static float f1 = 1.e10f;
ImGui::InputFloat("input scientific", &f1, 0.0f, 0.0f, "%e");
ImGui::SameLine(); ShowHelpMarker("You can input value using the scientific notation,\n e.g. \"1e+8\" becomes \"100000000\".\n");
static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f };
ImGui::InputFloat3("input float3", vec4a);
}
{
static int i1 = 50, i2 = 42;
ImGui::DragInt("drag int", &i1, 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", &i2, 1, 0, 100, "%d%%");
static float f1=1.00f, f2=0.0067f;
ImGui::DragFloat("drag float", &f1, 0.005f);
ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns");
}
{
static int i1=0;
ImGui::SliderInt("slider int", &i1, -1, 3);
ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value.");
static float f1=0.123f, f2=0.0f;
ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f");
ImGui::SliderFloat("slider float (curve)", &f2, -10.0f, 10.0f, "%.4f", 2.0f);
static float angle = 0.0f;
ImGui::SliderAngle("slider angle", &angle);
}
{
static float col1[3] = { 1.0f,0.0f,0.2f };
static float col2[4] = { 0.4f,0.7f,0.0f,0.5f };
ImGui::ColorEdit3("color 1", col1);
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);
}
{
// List box
const char* listbox_items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" };
static int listbox_item_current = 1;
ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4);
//static int listbox_item_current2 = 2;
//ImGui::PushItemWidth(-1);
//ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4);
//ImGui::PopItemWidth();
}
ImGui::TreePop();
}
// Testing ImGuiOnceUponAFrame helper.
//static ImGuiOnceUponAFrame once;
//for (int 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 (int i = 0; i < 5; i++)
if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", 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 bool align_label_with_current_x_position = false;
ImGui::Checkbox("Align label with current X position)", &align_label_with_current_x_position);
ImGui::Text("Hello!");
if (align_label_with_current_x_position)
ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());
static int 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.
int 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(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize()*3); // Increase spacing to differentiate leaves from expanded contents.
for (int i = 0; i < 6; i++)
{
// Disable the default open on single-click behavior and pass in Selected flag according to our selection state.
ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0);
if (i < 3)
{
// Node
bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", 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 |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet
ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", 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 ^= (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 = (1 << node_clicked); // Click to single-select
}
ImGui::PopStyleVar();
if (align_label_with_current_x_position)
ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing());
ImGui::TreePop();
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Collapsing Headers"))
{
static bool closable_group = true;
ImGui::Checkbox("Enable extra group", &closable_group);
if (ImGui::CollapsingHeader("Header"))
{
ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
for (int i = 0; i < 5; i++)
ImGui::Text("Some content %d", i);
}
if (ImGui::CollapsingHeader("Header with a close button", &closable_group))
{
ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
for (int i = 0; i < 5; i++)
ImGui::Text("More content %d", 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(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink");
ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "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 float wrap_width = 200.0f;
ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f");
ImGui::Text("Test paragraph 1:");
ImVec2 pos = ImGui::GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255,0,255,255));
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width);
ImGui::Text("The lazy dog is a good dog. This paragraph is made to fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width);
ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255));
ImGui::PopTextWrapPos();
ImGui::Text("Test paragraph 2:");
pos = ImGui::GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255,0,255,255));
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width);
ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh");
ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 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->AddFontFromFileTTF() manually to load extra character ranges. Read misc/fonts/README.txt for details.");
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("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
//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, IM_ARRAYSIZE(buf));
ImGui::TreePop();
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Images"))
{
ImGuiIO& 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().
ImTextureID my_tex_id = io.Fonts->TexID;
float my_tex_w = (float)io.Fonts->TexWidth;
float my_tex_h = (float)io.Fonts->TexHeight;
ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h);
ImVec2 pos = ImGui::GetCursorScreenPos();
ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128));
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
float region_sz = 32.0f;
float region_x = io.MousePos.x - pos.x - region_sz * 0.5f; if (region_x < 0.0f) region_x = 0.0f; else if (region_x > my_tex_w - region_sz) region_x = my_tex_w - region_sz;
float region_y = io.MousePos.y - pos.y - region_sz * 0.5f; if (region_y < 0.0f) region_y = 0.0f; else if (region_y > my_tex_h - region_sz) region_y = my_tex_h - region_sz;
float zoom = 4.0f;
ImGui::Text("Min: (%.2f, %.2f)", region_x, region_y);
ImGui::Text("Max: (%.2f, %.2f)", region_x + region_sz, region_y + region_sz);
ImVec2 uv0 = ImVec2((region_x) / my_tex_w, (region_y) / my_tex_h);
ImVec2 uv1 = ImVec2((region_x + region_sz) / my_tex_w, (region_y + region_sz) / my_tex_h);
ImGui::Image(my_tex_id, ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, ImColor(255,255,255,255), ImColor(255,255,255,128));
ImGui::EndTooltip();
}
ImGui::TextWrapped("And now some textured buttons..");
static int pressed_count = 0;
for (int i = 0; i < 8; i++)
{
ImGui::PushID(i);
int frame_padding = -1 + i; // -1 = uses default padding
if (ImGui::ImageButton(my_tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/my_tex_w,32/my_tex_h), frame_padding, ImColor(0,0,0,255)))
pressed_count += 1;
ImGui::PopID();
ImGui::SameLine();
}
ImGui::NewLine();
ImGui::Text("Pressed %d times.", pressed_count);
ImGui::TreePop();
}
if (ImGui::TreeNode("Combo"))
{
// Expose flags as checkbox for the demo
static ImGuiComboFlags flags = 0;
ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", (unsigned int*)&flags, ImGuiComboFlags_PopupAlignLeft);
if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", (unsigned int*)&flags, ImGuiComboFlags_NoArrowButton))
flags &= ~ImGuiComboFlags_NoPreview; // Clear the other flag, as we cannot combine both
if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", (unsigned int*)&flags, ImGuiComboFlags_NoPreview))
flags &= ~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 char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" };
static const char* item_current = items[0]; // Here our selection is a single pointer stored outside the object.
if (ImGui::BeginCombo("combo 1", item_current, flags)) // The second parameter is the label previewed before opening the combo.
{
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
{
bool is_selected = (item_current == items[n]);
if (ImGui::Selectable(items[n], is_selected))
item_current = 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 int item_current_2 = 0;
ImGui::Combo("combo 2 (one-liner)", &item_current_2, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
// Simplified one-liner Combo() using an array of const char*
static int item_current_3 = -1; // If the selection isn't within 0..count, Combo won't display a preview
ImGui::Combo("combo 3 (array)", &item_current_3, items, 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; } };
static int item_current_4 = 0;
ImGui::Combo("combo 4 (function)", &item_current_4, &FuncHolder::ItemGetter, items, 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 bool selection[5] = { false, true, false, false, false };
ImGui::Selectable("1. I am selectable", &selection[0]);
ImGui::Selectable("2. I am selectable", &selection[1]);
ImGui::Text("3. I am not selectable");
ImGui::Selectable("4. I am selectable", &selection[3]);
if (ImGui::Selectable("5. I am double clickable", selection[4], ImGuiSelectableFlags_AllowDoubleClick))
if (ImGui::IsMouseDoubleClicked(0))
selection[4] = !selection[4];
ImGui::TreePop();
}
if (ImGui::TreeNode("Selection State: Single Selection"))
{
static int selected = -1;
for (int n = 0; n < 5; n++)
{
char buf[32];
sprintf(buf, "Object %d", n);
if (ImGui::Selectable(buf, selected == n))
selected = n;
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Selection State: Multiple Selection"))
{
ShowHelpMarker("Hold CTRL and click to select multiple items.");
static bool selection[5] = { false, false, false, false, false };
for (int n = 0; n < 5; n++)
{
char buf[32];
sprintf(buf, "Object %d", n);
if (ImGui::Selectable(buf, selection[n]))
{
if (!ImGui::GetIO().KeyCtrl) // Clear selection when CTRL is not held
memset(selection, 0, sizeof(selection));
selection[n] ^= 1;
}
}
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 bool selected[3] = { false, false, false };
ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes");
ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(300); ImGui::Text("12,345 bytes");
ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes");
ImGui::TreePop();
}
if (ImGui::TreeNode("In columns"))
{
ImGui::Columns(3, NULL, false);
static bool selected[16] = { 0 };
for (int i = 0; i < 16; i++)
{
char label[32]; sprintf(label, "Item %d", i);
if (ImGui::Selectable(label, &selected[i])) {}
ImGui::NextColumn();
}
ImGui::Columns(1);
ImGui::TreePop();
}
if (ImGui::TreeNode("Grid"))
{
static bool selected[16] = { true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true };
for (int i = 0; i < 16; i++)
{
ImGui::PushID(i);
if (ImGui::Selectable("Sailor", &selected[i], 0, ImVec2(50,50)))
{
int x = i % 4, y = i / 4;
if (x > 0) selected[i - 1] ^= 1;
if (x < 3) selected[i + 1] ^= 1;
if (y > 0) selected[i - 4] ^= 1;
if (y < 3) selected[i + 4] ^= 1;
}
if ((i % 4) < 3) ImGui::SameLine();
ImGui::PopID();
}
ImGui::TreePop();
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Filtered Text Input"))
{
static char buf1[64] = ""; ImGui::InputText("default", buf1, 64);
static char buf2[64] = ""; ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal);
static char buf3[64] = ""; ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase);
static char buf4[64] = ""; ImGui::InputText("uppercase", buf4, 64, ImGuiInputTextFlags_CharsUppercase);
static char buf5[64] = ""; ImGui::InputText("no blank", buf5, 64, ImGuiInputTextFlags_CharsNoBlank);
struct TextFilters { static int FilterImGuiLetters(ImGuiInputTextCallbackData* data) { if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) return 0; return 1; } };
static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters);
ImGui::Text("Password input");
static char bufpass[64] = "password123";
ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank);
ImGui::SameLine(); ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n");
ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank);
ImGui::TreePop();
}
if (ImGui::TreeNode("Multi-line Text Input"))
{
// Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize
// and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings.
static bool read_only = false;
static char text[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/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp)");
ImGui::Checkbox("Read-only", &read_only);
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput | (read_only ? ImGuiInputTextFlags_ReadOnly : 0);
ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-1.0f, ImGui::GetTextLineHeight() * 16), flags);
ImGui::TreePop();
}
if (ImGui::TreeNode("Plots Widgets"))
{
static bool animate = true;
ImGui::Checkbox("Animate", &animate);
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr));
// 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 float values[90] = { 0 };
static int values_offset = 0;
static double refresh_time = 0.0;
if (!animate || refresh_time == 0.0f)
refresh_time = ImGui::GetTime();
while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 hz rate for the demo
{
static float phase = 0.0f;
values[values_offset] = cosf(phase);
values_offset = (values_offset+1) % IM_ARRAYSIZE(values);
phase += 0.10f*values_offset;
refresh_time += 1.0f/60.0f;
}
ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80));
ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, 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.
struct Funcs
{
static float Sin(void*, int i) { return sinf(i * 0.1f); }
static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; }
};
static int func_type = 0, display_count = 70;
ImGui::Separator();
ImGui::PushItemWidth(100); ImGui::Combo("func", &func_type, "Sin\0Saw\0"); ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::SliderInt("Sample count", &display_count, 1, 400);
float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw;
ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80));
ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80));
ImGui::Separator();
// Animate a simple progress bar
static float progress = 0.0f, progress_dir = 1.0f;
if (animate)
{
progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime;
if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; }
if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; }
}
// Typically we would use ImVec2(-1.0f,0.0f) to use all available width, or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth.
ImGui::ProgressBar(progress, ImVec2(0.0f,0.0f));
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
ImGui::Text("Progress Bar");
float progress_saturated = (progress < 0.0f) ? 0.0f : (progress > 1.0f) ? 1.0f : progress;
char buf[32];
sprintf(buf, "%d/%d", (int)(progress_saturated*1753), 1753);
ImGui::ProgressBar(progress, ImVec2(0.f,0.f), buf);
ImGui::TreePop();
}
if (ImGui::TreeNode("Color/Picker Widgets"))
{
static ImVec4 color = ImColor(114, 144, 154, 200);
static bool alpha_preview = true;
static bool alpha_half_preview = false;
static bool drag_and_drop = true;
static bool options_menu = true;
static bool hdr = false;
ImGui::Checkbox("With Alpha Preview", &alpha_preview);