cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

imgui_demo.cpp (256268B)


      1// dear imgui, v1.76
      2// (demo code)
      3
      4// Help:
      5// - Read FAQ at http://dearimgui.org/faq
      6// - Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase.
      7// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. All applications in examples/ are doing that.
      8// Read imgui.cpp for more details, documentation and comments.
      9// Get latest version at https://github.com/ocornut/imgui
     10
     11// Message to the person tempted to delete this file when integrating Dear ImGui into their code base:
     12// Do NOT remove this file from your project! Think again! It is the most useful reference code that you and other coders
     13// will want to refer to and call. Have the ImGui::ShowDemoWindow() function wired in an always-available debug menu of
     14// your game/app! Removing this file from your project is hindering access to documentation for everyone in your team,
     15// likely leading you to poorer usage of the library.
     16// Everything in this file will be stripped out by the linker if you don't call ImGui::ShowDemoWindow().
     17// If you want to link core Dear ImGui in your shipped builds but want a thorough guarantee that the demo will not be linked,
     18// you can setup your imconfig.h with #define IMGUI_DISABLE_DEMO_WINDOWS and those functions will be empty.
     19// In other situation, whenever you have Dear ImGui available you probably want this to be available for reference.
     20// Thank you,
     21// -Your beloved friend, imgui_demo.cpp (which you won't delete)
     22
     23// Message to beginner C/C++ programmers about the meaning of the 'static' keyword:
     24// In this demo code, we frequently we use 'static' variables inside functions. A static variable persist across calls, so it is
     25// essentially like a global variable but declared inside the scope of the function. We do this as a way to gather code and data
     26// in the same place, to make the demo source code faster to read, faster to write, and smaller in size.
     27// It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be
     28// reentrant or used in multiple threads. This might be a pattern you will want to use in your code, but most of the real data
     29// you would be editing is likely going to be stored outside your functions.
     30
     31// The Demo code in this file is designed to be easy to copy-and-paste in into your application!
     32// Because of this:
     33// - We never omit the ImGui:: namespace when calling functions, even though most of our code is already in the same namespace.
     34// - We try to declare static variables in the local scope, as close as possible to the code using them.
     35// - We never use any of the helpers/facilities used internally by Dear ImGui, unless it has been exposed in the public API (imgui.h).
     36// - We never use maths operators on ImVec2/ImVec4. For other of our sources files, they are provided by imgui_internal.h w/ IMGUI_DEFINE_MATH_OPERATORS.
     37//   For your own sources file they are optional and require you either enable those, either provide your own via IM_VEC2_CLASS_EXTRA in imconfig.h.
     38//   Because we don't want to assume anything about your support of maths operators, we don't use them in imgui_demo.cpp.
     39
     40/*
     41
     42Index of this file:
     43
     44// [SECTION] Forward Declarations, Helpers
     45// [SECTION] Demo Window / ShowDemoWindow()
     46// [SECTION] About Window / ShowAboutWindow()
     47// [SECTION] Style Editor / ShowStyleEditor()
     48// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar()
     49// [SECTION] Example App: Debug Console / ShowExampleAppConsole()
     50// [SECTION] Example App: Debug Log / ShowExampleAppLog()
     51// [SECTION] Example App: Simple Layout / ShowExampleAppLayout()
     52// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor()
     53// [SECTION] Example App: Long Text / ShowExampleAppLongText()
     54// [SECTION] Example App: Auto Resize / ShowExampleAppAutoResize()
     55// [SECTION] Example App: Constrained Resize / ShowExampleAppConstrainedResize()
     56// [SECTION] Example App: Simple Overlay / ShowExampleAppSimpleOverlay()
     57// [SECTION] Example App: Manipulating Window Titles / ShowExampleAppWindowTitles()
     58// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering()
     59// [SECTION] Example App: Documents Handling / ShowExampleAppDocuments()
     60
     61*/
     62
     63#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
     64#define _CRT_SECURE_NO_WARNINGS
     65#endif
     66
     67#include "imgui.h"
     68#ifndef IMGUI_DISABLE
     69
     70#include <ctype.h>          // toupper
     71#include <limits.h>         // INT_MIN, INT_MAX
     72#include <math.h>           // sqrtf, powf, cosf, sinf, floorf, ceilf
     73#include <stdio.h>          // vsnprintf, sscanf, printf
     74#include <stdlib.h>         // NULL, malloc, free, atoi
     75#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
     76#include <stddef.h>         // intptr_t
     77#else
     78#include <stdint.h>         // intptr_t
     79#endif
     80
     81#ifdef _MSC_VER
     82#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
     83#endif
     84#if defined(__clang__)
     85#pragma clang diagnostic ignored "-Wold-style-cast"             // warning : use of old-style cast                              // yes, they are more terse.
     86#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)
     87#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"   // warning : cast to 'void *' from smaller integer type 'int'
     88#pragma clang diagnostic ignored "-Wformat-security"            // warning : warning: format string is not a string literal
     89#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.
     90#pragma clang diagnostic ignored "-Wunused-macros"              // warning : warning: macro is not used                         // we define snprintf/vsnprintf on Windows so they are available, but not always used.
     91#if __has_warning("-Wzero-as-null-pointer-constant")
     92#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"  // warning : zero as null pointer constant                  // some standard header variations use #define NULL 0
     93#endif
     94#if __has_warning("-Wdouble-promotion")
     95#pragma clang diagnostic ignored "-Wdouble-promotion"           // warning: implicit conversion from 'float' to 'double' when passing argument to function  // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
     96#endif
     97#if __has_warning("-Wreserved-id-macro")
     98#pragma clang diagnostic ignored "-Wreserved-id-macro"          // warning : macro name is a reserved identifier                //
     99#endif
    100#elif defined(__GNUC__)
    101#pragma GCC diagnostic ignored "-Wpragmas"                      // warning: unknown option after '#pragma GCC diagnostic' kind
    102#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"          // warning: cast to pointer from integer of different size
    103#pragma GCC diagnostic ignored "-Wformat-security"              // warning : format string is not a string literal (potentially insecure)
    104#pragma GCC diagnostic ignored "-Wdouble-promotion"             // warning: implicit conversion from 'float' to 'double' when passing argument to function
    105#pragma GCC diagnostic ignored "-Wconversion"                   // warning: conversion to 'xxxx' from 'xxxx' may alter its value
    106#pragma GCC diagnostic ignored "-Wmisleading-indentation"       // [__GNUC__ >= 6] warning: this 'if' clause does not guard this statement      // GCC 6.0+ only. See #883 on GitHub.
    107#endif
    108
    109// Play it nice with Windows users (Update: since 2018-05, Notepad finally appears to support Unix-style carriage returns!)
    110#ifdef _WIN32
    111#define IM_NEWLINE  "\r\n"
    112#else
    113#define IM_NEWLINE  "\n"
    114#endif
    115
    116#if defined(_MSC_VER) && !defined(snprintf)
    117#define snprintf    _snprintf
    118#endif
    119#if defined(_MSC_VER) && !defined(vsnprintf)
    120#define vsnprintf   _vsnprintf
    121#endif
    122
    123//-----------------------------------------------------------------------------
    124// [SECTION] Forward Declarations, Helpers
    125//-----------------------------------------------------------------------------
    126
    127#if !defined(IMGUI_DISABLE_DEMO_WINDOWS)
    128
    129// Forward Declarations
    130static void ShowExampleAppDocuments(bool* p_open);
    131static void ShowExampleAppMainMenuBar();
    132static void ShowExampleAppConsole(bool* p_open);
    133static void ShowExampleAppLog(bool* p_open);
    134static void ShowExampleAppLayout(bool* p_open);
    135static void ShowExampleAppPropertyEditor(bool* p_open);
    136static void ShowExampleAppLongText(bool* p_open);
    137static void ShowExampleAppAutoResize(bool* p_open);
    138static void ShowExampleAppConstrainedResize(bool* p_open);
    139static void ShowExampleAppSimpleOverlay(bool* p_open);
    140static void ShowExampleAppWindowTitles(bool* p_open);
    141static void ShowExampleAppCustomRendering(bool* p_open);
    142static void ShowExampleMenuFile();
    143
    144// Helper to display a little (?) mark which shows a tooltip when hovered.
    145// In your own code you may want to display an actual icon if you are using a merged icon fonts (see docs/FONTS.txt)
    146static void HelpMarker(const char* desc)
    147{
    148    ImGui::TextDisabled("(?)");
    149    if (ImGui::IsItemHovered())
    150    {
    151        ImGui::BeginTooltip();
    152        ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
    153        ImGui::TextUnformatted(desc);
    154        ImGui::PopTextWrapPos();
    155        ImGui::EndTooltip();
    156    }
    157}
    158
    159// Helper to display basic user controls.
    160void ImGui::ShowUserGuide()
    161{
    162    ImGuiIO& io = ImGui::GetIO();
    163    ImGui::BulletText("Double-click on title bar to collapse window.");
    164    ImGui::BulletText("Click and drag on lower corner to resize window\n(double-click to auto fit window to its contents).");
    165    ImGui::BulletText("CTRL+Click on a slider or drag box to input value as text.");
    166    ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields.");
    167    if (io.FontAllowUserScaling)
    168        ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents.");
    169    ImGui::BulletText("While inputing text:\n");
    170    ImGui::Indent();
    171    ImGui::BulletText("CTRL+Left/Right to word jump.");
    172    ImGui::BulletText("CTRL+A or double-click to select all.");
    173    ImGui::BulletText("CTRL+X/C/V to use clipboard cut/copy/paste.");
    174    ImGui::BulletText("CTRL+Z,CTRL+Y to undo/redo.");
    175    ImGui::BulletText("ESCAPE to revert.");
    176    ImGui::BulletText("You can apply arithmetic operators +,*,/ on numerical values.\nUse +- to subtract.");
    177    ImGui::Unindent();
    178    ImGui::BulletText("With keyboard navigation enabled:");
    179    ImGui::Indent();
    180    ImGui::BulletText("Arrow keys to navigate.");
    181    ImGui::BulletText("Space to activate a widget.");
    182    ImGui::BulletText("Return to input text into a widget.");
    183    ImGui::BulletText("Escape to deactivate a widget, close popup, exit child window.");
    184    ImGui::BulletText("Alt to jump to the menu layer of a window.");
    185    ImGui::BulletText("CTRL+Tab to select a window.");
    186    ImGui::Unindent();
    187}
    188
    189//-----------------------------------------------------------------------------
    190// [SECTION] Demo Window / ShowDemoWindow()
    191//-----------------------------------------------------------------------------
    192// - ShowDemoWindowWidgets()
    193// - ShowDemoWindowLayout()
    194// - ShowDemoWindowPopups()
    195// - ShowDemoWindowColumns()
    196// - ShowDemoWindowMisc()
    197//-----------------------------------------------------------------------------
    198
    199// We split the contents of the big ShowDemoWindow() function into smaller functions (because the link time of very large functions grow non-linearly)
    200static void ShowDemoWindowWidgets();
    201static void ShowDemoWindowLayout();
    202static void ShowDemoWindowPopups();
    203static void ShowDemoWindowColumns();
    204static void ShowDemoWindowMisc();
    205
    206// Demonstrate most Dear ImGui features (this is big function!)
    207// 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.
    208void ImGui::ShowDemoWindow(bool* p_open)
    209{
    210    IM_ASSERT(ImGui::GetCurrentContext() != NULL && "Missing dear imgui context. Refer to examples app!"); // Exceptionally add an extra assert here for people confused with initial dear imgui setup
    211
    212    // Examples Apps (accessible from the "Examples" menu)
    213    static bool show_app_documents = false;
    214    static bool show_app_main_menu_bar = false;
    215    static bool show_app_console = false;
    216    static bool show_app_log = false;
    217    static bool show_app_layout = false;
    218    static bool show_app_property_editor = false;
    219    static bool show_app_long_text = false;
    220    static bool show_app_auto_resize = false;
    221    static bool show_app_constrained_resize = false;
    222    static bool show_app_simple_overlay = false;
    223    static bool show_app_window_titles = false;
    224    static bool show_app_custom_rendering = false;
    225
    226    if (show_app_documents)           ShowExampleAppDocuments(&show_app_documents);
    227    if (show_app_main_menu_bar)       ShowExampleAppMainMenuBar();
    228    if (show_app_console)             ShowExampleAppConsole(&show_app_console);
    229    if (show_app_log)                 ShowExampleAppLog(&show_app_log);
    230    if (show_app_layout)              ShowExampleAppLayout(&show_app_layout);
    231    if (show_app_property_editor)     ShowExampleAppPropertyEditor(&show_app_property_editor);
    232    if (show_app_long_text)           ShowExampleAppLongText(&show_app_long_text);
    233    if (show_app_auto_resize)         ShowExampleAppAutoResize(&show_app_auto_resize);
    234    if (show_app_constrained_resize)  ShowExampleAppConstrainedResize(&show_app_constrained_resize);
    235    if (show_app_simple_overlay)      ShowExampleAppSimpleOverlay(&show_app_simple_overlay);
    236    if (show_app_window_titles)       ShowExampleAppWindowTitles(&show_app_window_titles);
    237    if (show_app_custom_rendering)    ShowExampleAppCustomRendering(&show_app_custom_rendering);
    238
    239    // Dear ImGui Apps (accessible from the "Tools" menu)
    240    static bool show_app_metrics = false;
    241    static bool show_app_style_editor = false;
    242    static bool show_app_about = false;
    243
    244    if (show_app_metrics)             { ImGui::ShowMetricsWindow(&show_app_metrics); }
    245    if (show_app_style_editor)        { ImGui::Begin("Style Editor", &show_app_style_editor); ImGui::ShowStyleEditor(); ImGui::End(); }
    246    if (show_app_about)               { ImGui::ShowAboutWindow(&show_app_about); }
    247
    248    // Demonstrate the various window flags. Typically you would just use the default!
    249    static bool no_titlebar = false;
    250    static bool no_scrollbar = false;
    251    static bool no_menu = false;
    252    static bool no_move = false;
    253    static bool no_resize = false;
    254    static bool no_collapse = false;
    255    static bool no_close = false;
    256    static bool no_nav = false;
    257    static bool no_background = false;
    258    static bool no_bring_to_front = false;
    259
    260    ImGuiWindowFlags window_flags = 0;
    261    if (no_titlebar)        window_flags |= ImGuiWindowFlags_NoTitleBar;
    262    if (no_scrollbar)       window_flags |= ImGuiWindowFlags_NoScrollbar;
    263    if (!no_menu)           window_flags |= ImGuiWindowFlags_MenuBar;
    264    if (no_move)            window_flags |= ImGuiWindowFlags_NoMove;
    265    if (no_resize)          window_flags |= ImGuiWindowFlags_NoResize;
    266    if (no_collapse)        window_flags |= ImGuiWindowFlags_NoCollapse;
    267    if (no_nav)             window_flags |= ImGuiWindowFlags_NoNav;
    268    if (no_background)      window_flags |= ImGuiWindowFlags_NoBackground;
    269    if (no_bring_to_front)  window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus;
    270    if (no_close)           p_open = NULL; // Don't pass our bool* to Begin
    271
    272    // 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.
    273    ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver);
    274    ImGui::SetNextWindowSize(ImVec2(550, 680), ImGuiCond_FirstUseEver);
    275
    276    // Main body of the Demo window starts here.
    277    if (!ImGui::Begin("Dear ImGui Demo", p_open, window_flags))
    278    {
    279        // Early out if the window is collapsed, as an optimization.
    280        ImGui::End();
    281        return;
    282    }
    283
    284    // Most "big" widgets share a common width settings by default.
    285    //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f);    // Use 2/3 of the space for widgets and 1/3 for labels (default)
    286    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.
    287
    288    // Menu Bar
    289    if (ImGui::BeginMenuBar())
    290    {
    291        if (ImGui::BeginMenu("Menu"))
    292        {
    293            ShowExampleMenuFile();
    294            ImGui::EndMenu();
    295        }
    296        if (ImGui::BeginMenu("Examples"))
    297        {
    298            ImGui::MenuItem("Main menu bar", NULL, &show_app_main_menu_bar);
    299            ImGui::MenuItem("Console", NULL, &show_app_console);
    300            ImGui::MenuItem("Log", NULL, &show_app_log);
    301            ImGui::MenuItem("Simple layout", NULL, &show_app_layout);
    302            ImGui::MenuItem("Property editor", NULL, &show_app_property_editor);
    303            ImGui::MenuItem("Long text display", NULL, &show_app_long_text);
    304            ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize);
    305            ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize);
    306            ImGui::MenuItem("Simple overlay", NULL, &show_app_simple_overlay);
    307            ImGui::MenuItem("Manipulating window titles", NULL, &show_app_window_titles);
    308            ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering);
    309            ImGui::MenuItem("Documents", NULL, &show_app_documents);
    310            ImGui::EndMenu();
    311        }
    312        if (ImGui::BeginMenu("Tools"))
    313        {
    314            ImGui::MenuItem("Metrics", NULL, &show_app_metrics);
    315            ImGui::MenuItem("Style Editor", NULL, &show_app_style_editor);
    316            ImGui::MenuItem("About Dear ImGui", NULL, &show_app_about);
    317            ImGui::EndMenu();
    318        }
    319        ImGui::EndMenuBar();
    320    }
    321
    322    ImGui::Text("dear imgui says hello. (%s)", IMGUI_VERSION);
    323    ImGui::Spacing();
    324
    325    if (ImGui::CollapsingHeader("Help"))
    326    {
    327        ImGui::Text("ABOUT THIS DEMO:");
    328        ImGui::BulletText("Sections below are demonstrating many aspects of the library.");
    329        ImGui::BulletText("The \"Examples\" menu above leads to more demo contents.");
    330        ImGui::BulletText("The \"Tools\" menu above gives access to: About Box, Style Editor,\n"
    331                          "and Metrics (general purpose Dear ImGui debugging tool).");
    332        ImGui::Separator();
    333
    334        ImGui::Text("PROGRAMMER GUIDE:");
    335        ImGui::BulletText("See the ShowDemoWindow() code in imgui_demo.cpp. <- you are here!");
    336        ImGui::BulletText("See comments in imgui.cpp.");
    337        ImGui::BulletText("See example applications in the examples/ folder.");
    338        ImGui::BulletText("Read the FAQ at http://www.dearimgui.org/faq/");
    339        ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableKeyboard' for keyboard controls.");
    340        ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableGamepad' for gamepad controls.");
    341        ImGui::Separator();
    342
    343        ImGui::Text("USER GUIDE:");
    344        ImGui::ShowUserGuide();
    345    }
    346
    347    if (ImGui::CollapsingHeader("Configuration"))
    348    {
    349        ImGuiIO& io = ImGui::GetIO();
    350
    351        if (ImGui::TreeNode("Configuration##2"))
    352        {
    353            ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
    354            ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
    355            ImGui::SameLine(); HelpMarker("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.");
    356            ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos);
    357            ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos.");
    358            ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouse);
    359            if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) // Create a way to restore this flag otherwise we could be stuck completely!
    360            {
    361                if (fmodf((float)ImGui::GetTime(), 0.40f) < 0.20f)
    362                {
    363                    ImGui::SameLine();
    364                    ImGui::Text("<<PRESS SPACE TO DISABLE>>");
    365                }
    366                if (ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Space)))
    367                    io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
    368            }
    369            ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
    370            ImGui::SameLine(); HelpMarker("Instruct back-end to not alter mouse cursor shape and visibility.");
    371            ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
    372            ImGui::SameLine(); HelpMarker("Set to false to disable blinking cursor, for users who consider it distracting");
    373            ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges);
    374            ImGui::SameLine(); HelpMarker("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.");
    375            ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
    376            ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor);
    377            ImGui::SameLine(); HelpMarker("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).");
    378            ImGui::TreePop();
    379            ImGui::Separator();
    380        }
    381
    382        if (ImGui::TreeNode("Backend Flags"))
    383        {
    384            HelpMarker("Those flags are set by the back-ends (imgui_impl_xxx files) to specify their capabilities.\nHere we expose then as read-only fields to avoid breaking interactions with your back-end.");
    385            ImGuiBackendFlags backend_flags = io.BackendFlags; // Make a local copy to avoid modifying actual back-end flags.
    386            ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasGamepad);
    387            ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasMouseCursors);
    388            ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasSetMousePos);
    389            ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", (unsigned int *)&backend_flags, ImGuiBackendFlags_RendererHasVtxOffset);
    390            ImGui::TreePop();
    391            ImGui::Separator();
    392        }
    393
    394        if (ImGui::TreeNode("Style"))
    395        {
    396            HelpMarker("The same contents can be accessed in 'Tools->Style Editor' or by calling the ShowStyleEditor() function.");
    397            ImGui::ShowStyleEditor();
    398            ImGui::TreePop();
    399            ImGui::Separator();
    400        }
    401
    402        if (ImGui::TreeNode("Capture/Logging"))
    403        {
    404            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.");
    405            HelpMarker("Try opening any of the contents below in this window and then click one of the \"Log To\" button.");
    406            ImGui::LogButtons();
    407            ImGui::TextWrapped("You can also call ImGui::LogText() to output directly to the log without a visual output.");
    408            if (ImGui::Button("Copy \"Hello, world!\" to clipboard"))
    409            {
    410                ImGui::LogToClipboard();
    411                ImGui::LogText("Hello, world!");
    412                ImGui::LogFinish();
    413            }
    414            ImGui::TreePop();
    415        }
    416    }
    417
    418    if (ImGui::CollapsingHeader("Window options"))
    419    {
    420        ImGui::Checkbox("No titlebar", &no_titlebar); ImGui::SameLine(150);
    421        ImGui::Checkbox("No scrollbar", &no_scrollbar); ImGui::SameLine(300);
    422        ImGui::Checkbox("No menu", &no_menu);
    423        ImGui::Checkbox("No move", &no_move); ImGui::SameLine(150);
    424        ImGui::Checkbox("No resize", &no_resize); ImGui::SameLine(300);
    425        ImGui::Checkbox("No collapse", &no_collapse);
    426        ImGui::Checkbox("No close", &no_close); ImGui::SameLine(150);
    427        ImGui::Checkbox("No nav", &no_nav); ImGui::SameLine(300);
    428        ImGui::Checkbox("No background", &no_background);
    429        ImGui::Checkbox("No bring to front", &no_bring_to_front);
    430    }
    431
    432    // All demo contents
    433    ShowDemoWindowWidgets();
    434    ShowDemoWindowLayout();
    435    ShowDemoWindowPopups();
    436    ShowDemoWindowColumns();
    437    ShowDemoWindowMisc();
    438
    439    // End of ShowDemoWindow()
    440    ImGui::End();
    441}
    442
    443static void ShowDemoWindowWidgets()
    444{
    445    if (!ImGui::CollapsingHeader("Widgets"))
    446        return;
    447
    448    if (ImGui::TreeNode("Basic"))
    449    {
    450        static int clicked = 0;
    451        if (ImGui::Button("Button"))
    452            clicked++;
    453        if (clicked & 1)
    454        {
    455            ImGui::SameLine();
    456            ImGui::Text("Thanks for clicking me!");
    457        }
    458
    459        static bool check = true;
    460        ImGui::Checkbox("checkbox", &check);
    461
    462        static int e = 0;
    463        ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine();
    464        ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine();
    465        ImGui::RadioButton("radio c", &e, 2);
    466
    467        // Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style.
    468        for (int i = 0; i < 7; i++)
    469        {
    470            if (i > 0)
    471                ImGui::SameLine();
    472            ImGui::PushID(i);
    473            ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(i/7.0f, 0.6f, 0.6f));
    474            ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(i/7.0f, 0.7f, 0.7f));
    475            ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(i/7.0f, 0.8f, 0.8f));
    476            ImGui::Button("Click");
    477            ImGui::PopStyleColor(3);
    478            ImGui::PopID();
    479        }
    480
    481        // 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)
    482        ImGui::AlignTextToFramePadding();
    483        ImGui::Text("Hold to repeat:");
    484        ImGui::SameLine();
    485
    486        // Arrow buttons with Repeater
    487        static int counter = 0;
    488        float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
    489        ImGui::PushButtonRepeat(true);
    490        if (ImGui::ArrowButton("##left", ImGuiDir_Left)) { counter--; }
    491        ImGui::SameLine(0.0f, spacing);
    492        if (ImGui::ArrowButton("##right", ImGuiDir_Right)) { counter++; }
    493        ImGui::PopButtonRepeat();
    494        ImGui::SameLine();
    495        ImGui::Text("%d", counter);
    496
    497        ImGui::Text("Hover over me");
    498        if (ImGui::IsItemHovered())
    499            ImGui::SetTooltip("I am a tooltip");
    500
    501        ImGui::SameLine();
    502        ImGui::Text("- or me");
    503        if (ImGui::IsItemHovered())
    504        {
    505            ImGui::BeginTooltip();
    506            ImGui::Text("I am a fancy tooltip");
    507            static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
    508            ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr));
    509            ImGui::EndTooltip();
    510        }
    511
    512        ImGui::Separator();
    513
    514        ImGui::LabelText("label", "Value");
    515
    516        {
    517            // Using the _simplified_ one-liner Combo() api here
    518            // See "Combo" section for examples of how to use the more complete BeginCombo()/EndCombo() api.
    519            const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" };
    520            static int item_current = 0;
    521            ImGui::Combo("combo", &item_current, items, IM_ARRAYSIZE(items));
    522            ImGui::SameLine(); HelpMarker("Refer to the \"Combo\" section below for an explanation of the full BeginCombo/EndCombo API, and demonstration of various flags.\n");
    523        }
    524
    525        {
    526            // To wire InputText() with std::string or any other custom string type,
    527            // see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file.
    528            static char str0[128] = "Hello, world!";
    529            ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0));
    530            ImGui::SameLine(); HelpMarker("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).");
    531
    532            static char str1[128] = "";
    533            ImGui::InputTextWithHint("input text (w/ hint)", "enter text here", str1, IM_ARRAYSIZE(str1));
    534
    535            static int i0 = 123;
    536            ImGui::InputInt("input int", &i0);
    537            ImGui::SameLine(); HelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n  e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n");
    538
    539            static float f0 = 0.001f;
    540            ImGui::InputFloat("input float", &f0, 0.01f, 1.0f, "%.3f");
    541
    542            static double d0 = 999999.00000001;
    543            ImGui::InputDouble("input double", &d0, 0.01f, 1.0f, "%.8f");
    544
    545            static float f1 = 1.e10f;
    546            ImGui::InputFloat("input scientific", &f1, 0.0f, 0.0f, "%e");
    547            ImGui::SameLine(); HelpMarker("You can input value using the scientific notation,\n  e.g. \"1e+8\" becomes \"100000000\".\n");
    548
    549            static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f };
    550            ImGui::InputFloat3("input float3", vec4a);
    551        }
    552
    553        {
    554            static int i1 = 50, i2 = 42;
    555            ImGui::DragInt("drag int", &i1, 1);
    556            ImGui::SameLine(); HelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value.");
    557
    558            ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%");
    559
    560            static float f1=1.00f, f2=0.0067f;
    561            ImGui::DragFloat("drag float", &f1, 0.005f);
    562            ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns");
    563        }
    564
    565        {
    566            static int i1=0;
    567            ImGui::SliderInt("slider int", &i1, -1, 3);
    568            ImGui::SameLine(); HelpMarker("CTRL+click to input value.");
    569
    570            static float f1=0.123f, f2=0.0f;
    571            ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f");
    572            ImGui::SliderFloat("slider float (curve)", &f2, -10.0f, 10.0f, "%.4f", 2.0f);
    573
    574            static float angle = 0.0f;
    575            ImGui::SliderAngle("slider angle", &angle);
    576
    577            // Using the format string to display a name instead of an integer.
    578            // Here we completely omit '%d' from the format string, so it'll only display a name.
    579            // This technique can also be used with DragInt().
    580            enum Element { Element_Fire, Element_Earth, Element_Air, Element_Water, Element_COUNT };
    581            const char* element_names[Element_COUNT] = { "Fire", "Earth", "Air", "Water" };
    582            static int current_element = Element_Fire;
    583            const char* current_element_name = (current_element >= 0 && current_element < Element_COUNT) ? element_names[current_element] : "Unknown";
    584            ImGui::SliderInt("slider enum", &current_element, 0, Element_COUNT - 1, current_element_name);
    585            ImGui::SameLine(); HelpMarker("Using the format string parameter to display a name instead of the underlying integer.");
    586        }
    587
    588        {
    589            static float col1[3] = { 1.0f,0.0f,0.2f };
    590            static float col2[4] = { 0.4f,0.7f,0.0f,0.5f };
    591            ImGui::ColorEdit3("color 1", col1);
    592            ImGui::SameLine(); HelpMarker("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");
    593
    594            ImGui::ColorEdit4("color 2", col2);
    595        }
    596
    597        {
    598            // List box
    599            const char* listbox_items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" };
    600            static int listbox_item_current = 1;
    601            ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4);
    602
    603            //static int listbox_item_current2 = 2;
    604            //ImGui::SetNextItemWidth(-1);
    605            //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4);
    606        }
    607
    608        ImGui::TreePop();
    609    }
    610
    611    // Testing ImGuiOnceUponAFrame helper.
    612    //static ImGuiOnceUponAFrame once;
    613    //for (int i = 0; i < 5; i++)
    614    //    if (once)
    615    //        ImGui::Text("This will be displayed only once.");
    616
    617    if (ImGui::TreeNode("Trees"))
    618    {
    619        if (ImGui::TreeNode("Basic trees"))
    620        {
    621            for (int i = 0; i < 5; i++)
    622            {
    623                // Use SetNextItemOpen() so set the default state of a node to be open.
    624                // We could also use TreeNodeEx() with the ImGuiTreeNodeFlags_DefaultOpen flag to achieve the same thing!
    625                if (i == 0)
    626                    ImGui::SetNextItemOpen(true, ImGuiCond_Once);
    627
    628                if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i))
    629                {
    630                    ImGui::Text("blah blah");
    631                    ImGui::SameLine();
    632                    if (ImGui::SmallButton("button")) {}
    633                    ImGui::TreePop();
    634                }
    635            }
    636            ImGui::TreePop();
    637        }
    638
    639        if (ImGui::TreeNode("Advanced, with Selectable nodes"))
    640        {
    641            HelpMarker("This is a more typical looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open.");
    642            static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
    643            static bool align_label_with_current_x_position = false;
    644            ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnArrow);
    645            ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
    646            ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be layed out after the node.");
    647            ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanFullWidth);
    648            ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position);
    649            ImGui::Text("Hello!");
    650            if (align_label_with_current_x_position)
    651                ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());
    652
    653            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.
    654            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.
    655            for (int i = 0; i < 6; i++)
    656            {
    657                // Disable the default open on single-click behavior and pass in Selected flag according to our selection state.
    658                ImGuiTreeNodeFlags node_flags = base_flags;
    659                const bool is_selected = (selection_mask & (1 << i)) != 0;
    660                if (is_selected)
    661                    node_flags |= ImGuiTreeNodeFlags_Selected;
    662                if (i < 3)
    663                {
    664                    // Items 0..2 are Tree Node
    665                    bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i);
    666                    if (ImGui::IsItemClicked())
    667                        node_clicked = i;
    668                    if (node_open)
    669                    {
    670                        ImGui::BulletText("Blah blah\nBlah Blah");
    671                        ImGui::TreePop();
    672                    }
    673                }
    674                else
    675                {
    676                    // Items 3..5 are Tree Leaves
    677                    // The only reason we use TreeNode at all is to allow selection of the leaf.
    678                    // Otherwise we can use BulletText() or advance the cursor by GetTreeNodeToLabelSpacing() and call Text().
    679                    node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet
    680                    ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i);
    681                    if (ImGui::IsItemClicked())
    682                        node_clicked = i;
    683                }
    684            }
    685            if (node_clicked != -1)
    686            {
    687                // Update selection state. Process outside of tree loop to avoid visual inconsistencies during the clicking-frame.
    688                if (ImGui::GetIO().KeyCtrl)
    689                    selection_mask ^= (1 << node_clicked);          // CTRL+click to toggle
    690                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
    691                    selection_mask = (1 << node_clicked);           // Click to single-select
    692            }
    693            if (align_label_with_current_x_position)
    694                ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing());
    695            ImGui::TreePop();
    696        }
    697        ImGui::TreePop();
    698    }
    699
    700    if (ImGui::TreeNode("Collapsing Headers"))
    701    {
    702        static bool closable_group = true;
    703        ImGui::Checkbox("Show 2nd header", &closable_group);
    704        if (ImGui::CollapsingHeader("Header", ImGuiTreeNodeFlags_None))
    705        {
    706            ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
    707            for (int i = 0; i < 5; i++)
    708                ImGui::Text("Some content %d", i);
    709        }
    710        if (ImGui::CollapsingHeader("Header with a close button", &closable_group))
    711        {
    712            ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
    713            for (int i = 0; i < 5; i++)
    714                ImGui::Text("More content %d", i);
    715        }
    716        /*
    717        if (ImGui::CollapsingHeader("Header with a bullet", ImGuiTreeNodeFlags_Bullet))
    718            ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
    719        */
    720        ImGui::TreePop();
    721    }
    722
    723    if (ImGui::TreeNode("Bullets"))
    724    {
    725        ImGui::BulletText("Bullet point 1");
    726        ImGui::BulletText("Bullet point 2\nOn multiple lines");
    727        if (ImGui::TreeNode("Tree node"))
    728        {
    729            ImGui::BulletText("Another bullet point");
    730            ImGui::TreePop();
    731        }
    732        ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)");
    733        ImGui::Bullet(); ImGui::SmallButton("Button");
    734        ImGui::TreePop();
    735    }
    736
    737    if (ImGui::TreeNode("Text"))
    738    {
    739        if (ImGui::TreeNode("Colored Text"))
    740        {
    741            // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility.
    742            ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink");
    743            ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow");
    744            ImGui::TextDisabled("Disabled");
    745            ImGui::SameLine(); HelpMarker("The TextDisabled color is stored in ImGuiStyle.");
    746            ImGui::TreePop();
    747        }
    748
    749        if (ImGui::TreeNode("Word Wrapping"))
    750        {
    751            // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility.
    752            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.");
    753            ImGui::Spacing();
    754
    755            static float wrap_width = 200.0f;
    756            ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f");
    757
    758            ImGui::Text("Test paragraph 1:");
    759            ImVec2 pos = ImGui::GetCursorScreenPos();
    760            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));
    761            ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width);
    762            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);
    763            ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255));
    764            ImGui::PopTextWrapPos();
    765
    766            ImGui::Text("Test paragraph 2:");
    767            pos = ImGui::GetCursorScreenPos();
    768            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));
    769            ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width);
    770            ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee   ffffffff. gggggggg!hhhhhhhh");
    771            ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255));
    772            ImGui::PopTextWrapPos();
    773
    774            ImGui::TreePop();
    775        }
    776
    777        if (ImGui::TreeNode("UTF-8 Text"))
    778        {
    779            // UTF-8 test with Japanese characters
    780            // (Needs a suitable font, try Noto, or Arial Unicode, or M+ fonts. Read docs/FONTS.txt for details.)
    781            // - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8
    782            // - 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')
    783            // - FOR THIS DEMO FILE ONLY, BECAUSE WE WANT TO SUPPORT OLD COMPILERS, WE ARE *NOT* INCLUDING RAW UTF-8 CHARACTERS IN THIS SOURCE FILE.
    784            //   Instead we are encoding a few strings with hexadecimal constants. Don't do this in your application!
    785            //   Please use u8"text in any language" in your application!
    786            // 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.
    787            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 docs/FONTS.txt for details.");
    788            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.
    789            ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
    790            static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
    791            //static char buf[32] = u8"NIHONGO"; // <- this is how you would write it with C++11, using real kanjis
    792            ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf));
    793            ImGui::TreePop();
    794        }
    795        ImGui::TreePop();
    796    }
    797
    798    if (ImGui::TreeNode("Images"))
    799    {
    800        ImGuiIO& io = ImGui::GetIO();
    801        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!");
    802
    803        // Here we are grabbing the font texture because that's the only one we have access to inside the demo code.
    804        // 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.
    805        // 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.
    806        // (for example, the imgui_impl_dx11.cpp renderer expect a 'ID3D11ShaderResourceView*' pointer. The imgui_impl_opengl3.cpp renderer expect a GLuint OpenGL texture identifier etc.)
    807        // 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.
    808        // 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.
    809        // Consider using the lower-level ImDrawList::AddImage() API, via ImGui::GetWindowDrawList()->AddImage().
    810        ImTextureID my_tex_id = io.Fonts->TexID;
    811        float my_tex_w = (float)io.Fonts->TexWidth;
    812        float my_tex_h = (float)io.Fonts->TexHeight;
    813
    814        ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h);
    815        ImVec2 pos = ImGui::GetCursorScreenPos();
    816        ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), ImVec2(0,0), ImVec2(1,1), ImVec4(1.0f,1.0f,1.0f,1.0f), ImVec4(1.0f,1.0f,1.0f,0.5f));
    817        if (ImGui::IsItemHovered())
    818        {
    819            ImGui::BeginTooltip();
    820            float region_sz = 32.0f;
    821            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;
    822            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;
    823            float zoom = 4.0f;
    824            ImGui::Text("Min: (%.2f, %.2f)", region_x, region_y);
    825            ImGui::Text("Max: (%.2f, %.2f)", region_x + region_sz, region_y + region_sz);
    826            ImVec2 uv0 = ImVec2((region_x) / my_tex_w, (region_y) / my_tex_h);
    827            ImVec2 uv1 = ImVec2((region_x + region_sz) / my_tex_w, (region_y + region_sz) / my_tex_h);
    828            ImGui::Image(my_tex_id, ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, ImVec4(1.0f, 1.0f, 1.0f, 1.0f), ImVec4(1.0f, 1.0f, 1.0f, 0.5f));
    829            ImGui::EndTooltip();
    830        }
    831        ImGui::TextWrapped("And now some textured buttons..");
    832        static int pressed_count = 0;
    833        for (int i = 0; i < 8; i++)
    834        {
    835            ImGui::PushID(i);
    836            int frame_padding = -1 + i;     // -1 = uses default padding
    837            if (ImGui::ImageButton(my_tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/my_tex_w,32/my_tex_h), frame_padding, ImVec4(0.0f,0.0f,0.0f,1.0f)))
    838                pressed_count += 1;
    839            ImGui::PopID();
    840            ImGui::SameLine();
    841        }
    842        ImGui::NewLine();
    843        ImGui::Text("Pressed %d times.", pressed_count);
    844        ImGui::TreePop();
    845    }
    846
    847    if (ImGui::TreeNode("Combo"))
    848    {
    849        // Expose flags as checkbox for the demo
    850        static ImGuiComboFlags flags = 0;
    851        ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", (unsigned int*)&flags, ImGuiComboFlags_PopupAlignLeft);
    852        ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo");
    853        if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", (unsigned int*)&flags, ImGuiComboFlags_NoArrowButton))
    854            flags &= ~ImGuiComboFlags_NoPreview;     // Clear the other flag, as we cannot combine both
    855        if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", (unsigned int*)&flags, ImGuiComboFlags_NoPreview))
    856            flags &= ~ImGuiComboFlags_NoArrowButton; // Clear the other flag, as we cannot combine both
    857
    858        // General BeginCombo() API, you have full control over your selection data and display type.
    859        // (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.)
    860        const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" };
    861        static const char* item_current = items[0];            // Here our selection is a single pointer stored outside the object.
    862        if (ImGui::BeginCombo("combo 1", item_current, flags)) // The second parameter is the label previewed before opening the combo.
    863        {
    864            for (int n = 0; n < IM_ARRAYSIZE(items); n++)
    865            {
    866                bool is_selected = (item_current == items[n]);
    867                if (ImGui::Selectable(items[n], is_selected))
    868                    item_current = items[n];
    869                if (is_selected)
    870                    ImGui::SetItemDefaultFocus();   // Set the initial focus when opening the combo (scrolling + for keyboard navigation support in the upcoming navigation branch)
    871            }
    872            ImGui::EndCombo();
    873        }
    874
    875        // Simplified one-liner Combo() API, using values packed in a single constant string
    876        static int item_current_2 = 0;
    877        ImGui::Combo("combo 2 (one-liner)", &item_current_2, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
    878
    879        // Simplified one-liner Combo() using an array of const char*
    880        static int item_current_3 = -1; // If the selection isn't within 0..count, Combo won't display a preview
    881        ImGui::Combo("combo 3 (array)", &item_current_3, items, IM_ARRAYSIZE(items));
    882
    883        // Simplified one-liner Combo() using an accessor function
    884        struct FuncHolder { static bool ItemGetter(void* data, int idx, const char** out_str) { *out_str = ((const char**)data)[idx]; return true; } };
    885        static int item_current_4 = 0;
    886        ImGui::Combo("combo 4 (function)", &item_current_4, &FuncHolder::ItemGetter, items, IM_ARRAYSIZE(items));
    887
    888        ImGui::TreePop();
    889    }
    890
    891    if (ImGui::TreeNode("Selectables"))
    892    {
    893        // Selectable() has 2 overloads:
    894        // - 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.
    895        // - The one taking "bool* p_selected" as a read-write selection information (convenient in some cases)
    896        // 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).
    897        if (ImGui::TreeNode("Basic"))
    898        {
    899            static bool selection[5] = { false, true, false, false, false };
    900            ImGui::Selectable("1. I am selectable", &selection[0]);
    901            ImGui::Selectable("2. I am selectable", &selection[1]);
    902            ImGui::Text("3. I am not selectable");
    903            ImGui::Selectable("4. I am selectable", &selection[3]);
    904            if (ImGui::Selectable("5. I am double clickable", selection[4], ImGuiSelectableFlags_AllowDoubleClick))
    905                if (ImGui::IsMouseDoubleClicked(0))
    906                    selection[4] = !selection[4];
    907            ImGui::TreePop();
    908        }
    909        if (ImGui::TreeNode("Selection State: Single Selection"))
    910        {
    911            static int selected = -1;
    912            for (int n = 0; n < 5; n++)
    913            {
    914                char buf[32];
    915                sprintf(buf, "Object %d", n);
    916                if (ImGui::Selectable(buf, selected == n))
    917                    selected = n;
    918            }
    919            ImGui::TreePop();
    920        }
    921        if (ImGui::TreeNode("Selection State: Multiple Selection"))
    922        {
    923            HelpMarker("Hold CTRL and click to select multiple items.");
    924            static bool selection[5] = { false, false, false, false, false };
    925            for (int n = 0; n < 5; n++)
    926            {
    927                char buf[32];
    928                sprintf(buf, "Object %d", n);
    929                if (ImGui::Selectable(buf, selection[n]))
    930                {
    931                    if (!ImGui::GetIO().KeyCtrl)    // Clear selection when CTRL is not held
    932                        memset(selection, 0, sizeof(selection));
    933                    selection[n] ^= 1;
    934                }
    935            }
    936            ImGui::TreePop();
    937        }
    938        if (ImGui::TreeNode("Rendering more text into the same line"))
    939        {
    940            // Using the Selectable() override that takes "bool* p_selected" parameter and toggle your booleans automatically.
    941            static bool selected[3] = { false, false, false };
    942            ImGui::Selectable("main.c",    &selected[0]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes");
    943            ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(300); ImGui::Text("12,345 bytes");
    944            ImGui::Selectable("Hello.h",   &selected[2]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes");
    945            ImGui::TreePop();
    946        }
    947        if (ImGui::TreeNode("In columns"))
    948        {
    949            ImGui::Columns(3, NULL, false);
    950            static bool selected[16] = {};
    951            for (int i = 0; i < 16; i++)
    952            {
    953                char label[32]; sprintf(label, "Item %d", i);
    954                if (ImGui::Selectable(label, &selected[i])) {}
    955                ImGui::NextColumn();
    956            }
    957            ImGui::Columns(1);
    958            ImGui::TreePop();
    959        }
    960        if (ImGui::TreeNode("Grid"))
    961        {
    962            static bool selected[4*4] = { true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true };
    963            for (int i = 0; i < 4*4; i++)
    964            {
    965                ImGui::PushID(i);
    966                if (ImGui::Selectable("Sailor", &selected[i], 0, ImVec2(50,50)))
    967                {
    968                    // Note: We _unnecessarily_ test for both x/y and i here only to silence some static analyzer. The second part of each test is unnecessary.
    969                    int x = i % 4;
    970                    int y = i / 4;
    971                    if (x > 0)           { selected[i - 1] ^= 1; }
    972                    if (x < 3 && i < 15) { selected[i + 1] ^= 1; }
    973                    if (y > 0 && i > 3)  { selected[i - 4] ^= 1; }
    974                    if (y < 3 && i < 12) { selected[i + 4] ^= 1; }
    975                }
    976                if ((i % 4) < 3) ImGui::SameLine();
    977                ImGui::PopID();
    978            }
    979            ImGui::TreePop();
    980        }
    981        if (ImGui::TreeNode("Alignment"))
    982        {
    983            HelpMarker("By default, Selectables uses style.SelectableTextAlign but it can be overriden on a per-item basis using PushStyleVar(). You'll probably want to always keep your default situation to left-align otherwise it becomes difficult to layout multiple items on a same line");
    984            static bool selected[3*3] = { true, false, true, false, true, false, true, false, true };
    985            for (int y = 0; y < 3; y++)
    986            {
    987                for (int x = 0; x < 3; x++)
    988                {
    989                    ImVec2 alignment = ImVec2((float)x / 2.0f, (float)y / 2.0f);
    990                    char name[32];
    991                    sprintf(name, "(%.1f,%.1f)", alignment.x, alignment.y);
    992                    if (x > 0) ImGui::SameLine();
    993                    ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, alignment);
    994                    ImGui::Selectable(name, &selected[3*y+x], ImGuiSelectableFlags_None, ImVec2(80,80));
    995                    ImGui::PopStyleVar();
    996                }
    997            }
    998            ImGui::TreePop();
    999        }
   1000        ImGui::TreePop();
   1001    }
   1002
   1003    // To wire InputText() with std::string or any other custom string type,
   1004    // see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file.
   1005    if (ImGui::TreeNode("Text Input"))
   1006    {
   1007        if (ImGui::TreeNode("Multi-line Text Input"))
   1008        {
   1009            // Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize
   1010            // and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings.
   1011            static char text[1024 * 16] =
   1012                "/*\n"
   1013                " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n"
   1014                " the hexadecimal encoding of one offending instruction,\n"
   1015                " more formally, the invalid operand with locked CMPXCHG8B\n"
   1016                " instruction bug, is a design flaw in the majority of\n"
   1017                " Intel Pentium, Pentium MMX, and Pentium OverDrive\n"
   1018                " processors (all in the P5 microarchitecture).\n"
   1019                "*/\n\n"
   1020                "label:\n"
   1021                "\tlock cmpxchg8b eax\n";
   1022
   1023            static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput;
   1024            HelpMarker("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 because we don't want to include <string> in here)");
   1025            ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", (unsigned int*)&flags, ImGuiInputTextFlags_ReadOnly);
   1026            ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", (unsigned int*)&flags, ImGuiInputTextFlags_AllowTabInput);
   1027            ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", (unsigned int*)&flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
   1028            ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags);
   1029            ImGui::TreePop();
   1030        }
   1031
   1032        if (ImGui::TreeNode("Filtered Text Input"))
   1033        {
   1034            static char buf1[64] = ""; ImGui::InputText("default", buf1, 64);
   1035            static char buf2[64] = ""; ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal);
   1036            static char buf3[64] = ""; ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase);
   1037            static char buf4[64] = ""; ImGui::InputText("uppercase", buf4, 64, ImGuiInputTextFlags_CharsUppercase);
   1038            static char buf5[64] = ""; ImGui::InputText("no blank", buf5, 64, ImGuiInputTextFlags_CharsNoBlank);
   1039            struct TextFilters { static int FilterImGuiLetters(ImGuiInputTextCallbackData* data) { if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) return 0; return 1; } };
   1040            static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters);
   1041
   1042            ImGui::Text("Password input");
   1043            static char password[64] = "password123";
   1044            ImGui::InputText("password", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password);
   1045            ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n");
   1046            ImGui::InputTextWithHint("password (w/ hint)", "<password>", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password);
   1047            ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password));
   1048            ImGui::TreePop();
   1049        }
   1050
   1051        if (ImGui::TreeNode("Resize Callback"))
   1052        {
   1053            // To wire InputText() with std::string or any other custom string type,
   1054            // you can use the ImGuiInputTextFlags_CallbackResize flag + create a custom ImGui::InputText() wrapper using your prefered type.
   1055            // See misc/cpp/imgui_stdlib.h for an implementation of this using std::string.
   1056            HelpMarker("Demonstrate using ImGuiInputTextFlags_CallbackResize to wire your resizable string type to InputText().\n\nSee misc/cpp/imgui_stdlib.h for an implementation of this for std::string.");
   1057            struct Funcs
   1058            {
   1059                static int MyResizeCallback(ImGuiInputTextCallbackData* data)
   1060                {
   1061                    if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
   1062                    {
   1063                        ImVector<char>* my_str = (ImVector<char>*)data->UserData;
   1064                        IM_ASSERT(my_str->begin() == data->Buf);
   1065                        my_str->resize(data->BufSize);  // NB: On resizing calls, generally data->BufSize == data->BufTextLen + 1
   1066                        data->Buf = my_str->begin();
   1067                    }
   1068                    return 0;
   1069                }
   1070
   1071                // Tip: Because ImGui:: is a namespace you would typicall add your own function into the namespace in your own source files.
   1072                // For example, you may add a function called ImGui::InputText(const char* label, MyString* my_str).
   1073                static bool MyInputTextMultiline(const char* label, ImVector<char>* my_str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0)
   1074                {
   1075                    IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
   1076                    return ImGui::InputTextMultiline(label, my_str->begin(), (size_t)my_str->size(), size, flags | ImGuiInputTextFlags_CallbackResize, Funcs::MyResizeCallback, (void*)my_str);
   1077                }
   1078            };
   1079
   1080            // For this demo we are using ImVector as a string container.
   1081            // Note that because we need to store a terminating zero character, our size/capacity are 1 more than usually reported by a typical string class.
   1082            static ImVector<char> my_str;
   1083            if (my_str.empty())
   1084                my_str.push_back(0);
   1085            Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16));
   1086            ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity());
   1087            ImGui::TreePop();
   1088        }
   1089
   1090        ImGui::TreePop();
   1091    }
   1092
   1093    // Plot/Graph widgets are currently fairly limited.
   1094    // Consider writing your own plotting widget, or using a third-party one (see "Wiki->Useful Widgets", or github.com/ocornut/imgui/issues/2747)
   1095    if (ImGui::TreeNode("Plots Widgets"))
   1096    {
   1097        static bool animate = true;
   1098        ImGui::Checkbox("Animate", &animate);
   1099
   1100        static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
   1101        ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr));
   1102
   1103        // Create a dummy array of contiguous float values to plot
   1104        // 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.
   1105        static float values[90] = {};
   1106        static int values_offset = 0;
   1107        static double refresh_time = 0.0;
   1108        if (!animate || refresh_time == 0.0)
   1109            refresh_time = ImGui::GetTime();
   1110        while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 hz rate for the demo
   1111        {
   1112            static float phase = 0.0f;
   1113            values[values_offset] = cosf(phase);
   1114            values_offset = (values_offset+1) % IM_ARRAYSIZE(values);
   1115            phase += 0.10f*values_offset;
   1116            refresh_time += 1.0f/60.0f;
   1117        }
   1118
   1119        // Plots can display overlay texts
   1120        // (in this example, we will display an average value)
   1121        {
   1122            float average = 0.0f;
   1123            for (int n = 0; n < IM_ARRAYSIZE(values); n++)
   1124                average += values[n];
   1125            average /= (float)IM_ARRAYSIZE(values);
   1126            char overlay[32];
   1127            sprintf(overlay, "avg %f", average);
   1128            ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, overlay, -1.0f, 1.0f, ImVec2(0,80));
   1129        }
   1130        ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80));
   1131
   1132        // Use functions to generate output
   1133        // 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.
   1134        struct Funcs
   1135        {
   1136            static float Sin(void*, int i) { return sinf(i * 0.1f); }
   1137            static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; }
   1138        };
   1139        static int func_type = 0, display_count = 70;
   1140        ImGui::Separator();
   1141        ImGui::SetNextItemWidth(100);
   1142        ImGui::Combo("func", &func_type, "Sin\0Saw\0");
   1143        ImGui::SameLine();
   1144        ImGui::SliderInt("Sample count", &display_count, 1, 400);
   1145        float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw;
   1146        ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80));
   1147        ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80));
   1148        ImGui::Separator();
   1149
   1150        // Animate a simple progress bar
   1151        static float progress = 0.0f, progress_dir = 1.0f;
   1152        if (animate)
   1153        {
   1154            progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime;
   1155            if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; }
   1156            if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; }
   1157        }
   1158
   1159        // Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width,
   1160        // or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth.
   1161        ImGui::ProgressBar(progress, ImVec2(0.0f,0.0f));
   1162        ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
   1163        ImGui::Text("Progress Bar");
   1164
   1165        float progress_saturated = (progress < 0.0f) ? 0.0f : (progress > 1.0f) ? 1.0f : progress;
   1166        char buf[32];
   1167        sprintf(buf, "%d/%d", (int)(progress_saturated*1753), 1753);
   1168        ImGui::ProgressBar(progress, ImVec2(0.f,0.f), buf);
   1169        ImGui::TreePop();
   1170    }
   1171
   1172    if (ImGui::TreeNode("Color/Picker Widgets"))
   1173    {
   1174        static ImVec4 color = ImVec4(114.0f/255.0f, 144.0f/255.0f, 154.0f/255.0f, 200.0f/255.0f);
   1175
   1176        static bool alpha_preview = true;
   1177        static bool alpha_half_preview = false;
   1178        static bool drag_and_drop = true;
   1179        static bool options_menu = true;
   1180        static bool hdr = false;
   1181        ImGui::Checkbox("With Alpha Preview", &alpha_preview);
   1182        ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview);
   1183        ImGui::Checkbox("With Drag and Drop", &drag_and_drop);
   1184        ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options.");
   1185        ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
   1186        ImGuiColorEditFlags misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (drag_and_drop ? 0 : ImGuiColorEditFlags_NoDragDrop) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions);
   1187
   1188        ImGui::Text("Color widget:");
   1189        ImGui::SameLine(); HelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n");
   1190        ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags);
   1191
   1192        ImGui::Text("Color widget HSV with Alpha:");
   1193        ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | misc_flags);
   1194
   1195        ImGui::Text("Color widget with Float Display:");
   1196        ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags);
   1197
   1198        ImGui::Text("Color button with Picker:");
   1199        ImGui::SameLine(); HelpMarker("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.");
   1200        ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags);
   1201
   1202        ImGui::Text("Color button with Custom Picker Popup:");
   1203
   1204        // Generate a dummy default palette. The palette will persist and can be edited.
   1205        static bool saved_palette_init = true;
   1206        static ImVec4 saved_palette[32] = {};
   1207        if (saved_palette_init)
   1208        {
   1209            for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++)
   1210            {
   1211                ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, saved_palette[n].x, saved_palette[n].y, saved_palette[n].z);
   1212                saved_palette[n].w = 1.0f; // Alpha
   1213            }
   1214            saved_palette_init = false;
   1215        }
   1216
   1217        static ImVec4 backup_color;
   1218        bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags);
   1219        ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
   1220        open_popup |= ImGui::Button("Palette");
   1221        if (open_popup)
   1222        {
   1223            ImGui::OpenPopup("mypicker");
   1224            backup_color = color;
   1225        }
   1226        if (ImGui::BeginPopup("mypicker"))
   1227        {
   1228            ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!");
   1229            ImGui::Separator();
   1230            ImGui::ColorPicker4("##picker", (float*)&color, misc_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview);
   1231            ImGui::SameLine();
   1232
   1233            ImGui::BeginGroup(); // Lock X position
   1234            ImGui::Text("Current");
   1235            ImGui::ColorButton("##current", color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60,40));
   1236            ImGui::Text("Previous");
   1237            if (ImGui::ColorButton("##previous", backup_color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60,40)))
   1238                color = backup_color;
   1239            ImGui::Separator();
   1240            ImGui::Text("Palette");
   1241            for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++)
   1242            {
   1243                ImGui::PushID(n);
   1244                if ((n % 8) != 0)
   1245                    ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
   1246                if (ImGui::ColorButton("##palette", saved_palette[n], ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip, ImVec2(20,20)))
   1247                    color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z, color.w); // Preserve alpha!
   1248
   1249                // Allow user to drop colors into each palette entry
   1250                // (Note that ColorButton is already a drag source by default, unless using ImGuiColorEditFlags_NoDragDrop)
   1251                if (ImGui::BeginDragDropTarget())
   1252                {
   1253                    if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
   1254                        memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3);
   1255                    if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
   1256                        memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4);
   1257                    ImGui::EndDragDropTarget();
   1258                }
   1259
   1260                ImGui::PopID();
   1261            }
   1262            ImGui::EndGroup();
   1263            ImGui::EndPopup();
   1264        }
   1265
   1266        ImGui::Text("Color button only:");
   1267        static bool no_border = false;
   1268        ImGui::Checkbox("ImGuiColorEditFlags_NoBorder", &no_border);
   1269        ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80,80));
   1270
   1271        ImGui::Text("Color picker:");
   1272        static bool alpha = true;
   1273        static bool alpha_bar = true;
   1274        static bool side_preview = true;
   1275        static bool ref_color = false;
   1276        static ImVec4 ref_color_v(1.0f,0.0f,1.0f,0.5f);
   1277        static int display_mode = 0;
   1278        static int picker_mode = 0;
   1279        ImGui::Checkbox("With Alpha", &alpha);
   1280        ImGui::Checkbox("With Alpha Bar", &alpha_bar);
   1281        ImGui::Checkbox("With Side Preview", &side_preview);
   1282        if (side_preview)
   1283        {
   1284            ImGui::SameLine();
   1285            ImGui::Checkbox("With Ref Color", &ref_color);
   1286            if (ref_color)
   1287            {
   1288                ImGui::SameLine();
   1289                ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags);
   1290            }
   1291        }
   1292        ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0None\0RGB Only\0HSV Only\0Hex Only\0");
   1293        ImGui::SameLine(); HelpMarker("ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, but the user can change it with a right-click.\n\nColorPicker defaults to displaying RGB+HSV+Hex if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions().");
   1294        ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0Hue bar + SV rect\0Hue wheel + SV triangle\0");
   1295        ImGui::SameLine(); HelpMarker("User can right-click the picker to change mode.");
   1296        ImGuiColorEditFlags flags = misc_flags;
   1297        if (!alpha)            flags |= ImGuiColorEditFlags_NoAlpha;        // This is by default if you call ColorPicker3() instead of ColorPicker4()
   1298        if (alpha_bar)         flags |= ImGuiColorEditFlags_AlphaBar;
   1299        if (!side_preview)     flags |= ImGuiColorEditFlags_NoSidePreview;
   1300        if (picker_mode == 1)  flags |= ImGuiColorEditFlags_PickerHueBar;
   1301        if (picker_mode == 2)  flags |= ImGuiColorEditFlags_PickerHueWheel;
   1302        if (display_mode == 1) flags |= ImGuiColorEditFlags_NoInputs;       // Disable all RGB/HSV/Hex displays
   1303        if (display_mode == 2) flags |= ImGuiColorEditFlags_DisplayRGB;     // Override display mode
   1304        if (display_mode == 3) flags |= ImGuiColorEditFlags_DisplayHSV;
   1305        if (display_mode == 4) flags |= ImGuiColorEditFlags_DisplayHex;
   1306        ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL);
   1307
   1308        ImGui::Text("Programmatically set defaults:");
   1309        ImGui::SameLine(); HelpMarker("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.");
   1310        if (ImGui::Button("Default: Uint8 + HSV + Hue Bar"))
   1311            ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_PickerHueBar);
   1312        if (ImGui::Button("Default: Float + HDR + Hue Wheel"))
   1313            ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_PickerHueWheel);
   1314
   1315        // HSV encoded support (to avoid RGB<>HSV round trips and singularities when S==0 or V==0)
   1316        static ImVec4 color_stored_as_hsv(0.23f, 1.0f, 1.0f, 1.0f);
   1317        ImGui::Spacing();
   1318        ImGui::Text("HSV encoded colors");
   1319        ImGui::SameLine(); HelpMarker("By default, colors are given to ColorEdit and ColorPicker in RGB, but ImGuiColorEditFlags_InputHSV allows you to store colors as HSV and pass them to ColorEdit and ColorPicker as HSV. This comes with the added benefit that you can manipulate hue values with the picker even when saturation or value are zero.");
   1320        ImGui::Text("Color widget with InputHSV:");
   1321        ImGui::ColorEdit4("HSV shown as RGB##1", (float*)&color_stored_as_hsv, ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float);
   1322        ImGui::ColorEdit4("HSV shown as HSV##1", (float*)&color_stored_as_hsv, ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float);
   1323        ImGui::DragFloat4("Raw HSV values", (float*)&color_stored_as_hsv, 0.01f, 0.0f, 1.0f);
   1324
   1325        ImGui::TreePop();
   1326    }
   1327
   1328    if (ImGui::TreeNode("Range Widgets"))
   1329    {
   1330        static float begin = 10, end = 90;
   1331        static int begin_i = 100, end_i = 1000;
   1332        ImGui::DragFloatRange2("range", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%");
   1333        ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %d units", "Max: %d units");
   1334        ImGui::TreePop();
   1335    }
   1336
   1337    if (ImGui::TreeNode("Data Types"))
   1338    {
   1339        // The DragScalar/InputScalar/SliderScalar functions allow various data types: signed/unsigned int/long long and float/double
   1340        // To avoid polluting the public API with all possible combinations, we use the ImGuiDataType enum to pass the type,
   1341        // and passing all arguments by address.
   1342        // This is the reason the test code below creates local variables to hold "zero" "one" etc. for each types.
   1343        // In practice, if you frequently use a given type that is not covered by the normal API entry points, you can wrap it
   1344        // yourself inside a 1 line function which can take typed argument as value instead of void*, and then pass their address
   1345        // to the generic function. For example:
   1346        //   bool MySliderU64(const char *label, u64* value, u64 min = 0, u64 max = 0, const char* format = "%lld")
   1347        //   {
   1348        //      return SliderScalar(label, ImGuiDataType_U64, value, &min, &max, format);
   1349        //   }
   1350
   1351        // Limits (as helper variables that we can take the address of)
   1352        // Note that the SliderScalar function has a maximum usable range of half the natural type maximum, hence the /2 below.
   1353        #ifndef LLONG_MIN
   1354        ImS64 LLONG_MIN = -9223372036854775807LL - 1;
   1355        ImS64 LLONG_MAX = 9223372036854775807LL;
   1356        ImU64 ULLONG_MAX = (2ULL * 9223372036854775807LL + 1);
   1357        #endif
   1358        const char    s8_zero  = 0,   s8_one  = 1,   s8_fifty  = 50, s8_min  = -128,        s8_max = 127;
   1359        const ImU8    u8_zero  = 0,   u8_one  = 1,   u8_fifty  = 50, u8_min  = 0,           u8_max = 255;
   1360        const short   s16_zero = 0,   s16_one = 1,   s16_fifty = 50, s16_min = -32768,      s16_max = 32767;
   1361        const ImU16   u16_zero = 0,   u16_one = 1,   u16_fifty = 50, u16_min = 0,           u16_max = 65535;
   1362        const ImS32   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;
   1363        const ImU32   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;
   1364        const ImS64   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;
   1365        const ImU64   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;
   1366        const float   f32_zero = 0.f, f32_one = 1.f, f32_lo_a = -10000000000.0f, f32_hi_a = +10000000000.0f;
   1367        const double  f64_zero = 0.,  f64_one = 1.,  f64_lo_a = -1000000000000000.0, f64_hi_a = +1000000000000000.0;
   1368
   1369        // State
   1370        static char   s8_v  = 127;
   1371        static ImU8   u8_v  = 255;
   1372        static short  s16_v = 32767;
   1373        static ImU16  u16_v = 65535;
   1374        static ImS32  s32_v = -1;
   1375        static ImU32  u32_v = (ImU32)-1;
   1376        static ImS64  s64_v = -1;
   1377        static ImU64  u64_v = (ImU64)-1;
   1378        static float  f32_v = 0.123f;
   1379        static double f64_v = 90000.01234567890123456789;
   1380
   1381        const float drag_speed = 0.2f;
   1382        static bool drag_clamp = false;
   1383        ImGui::Text("Drags:");
   1384        ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp); ImGui::SameLine(); HelpMarker("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.");
   1385        ImGui::DragScalar("drag s8",        ImGuiDataType_S8,     &s8_v,  drag_speed, drag_clamp ? &s8_zero  : NULL, drag_clamp ? &s8_fifty  : NULL);
   1386        ImGui::DragScalar("drag u8",        ImGuiDataType_U8,     &u8_v,  drag_speed, drag_clamp ? &u8_zero  : NULL, drag_clamp ? &u8_fifty  : NULL, "%u ms");
   1387        ImGui::DragScalar("drag s16",       ImGuiDataType_S16,    &s16_v, drag_speed, drag_clamp ? &s16_zero : NULL, drag_clamp ? &s16_fifty : NULL);
   1388        ImGui::DragScalar("drag u16",       ImGuiDataType_U16,    &u16_v, drag_speed, drag_clamp ? &u16_zero : NULL, drag_clamp ? &u16_fifty : NULL, "%u ms");
   1389        ImGui::DragScalar("drag s32",       ImGuiDataType_S32,    &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL);
   1390        ImGui::DragScalar("drag u32",       ImGuiDataType_U32,    &u32_v, drag_speed, drag_clamp ? &u32_zero : NULL, drag_clamp ? &u32_fifty : NULL, "%u ms");
   1391        ImGui::DragScalar("drag s64",       ImGuiDataType_S64,    &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL);
   1392        ImGui::DragScalar("drag u64",       ImGuiDataType_U64,    &u64_v, drag_speed, drag_clamp ? &u64_zero : NULL, drag_clamp ? &u64_fifty : NULL);
   1393        ImGui::DragScalar("drag float",     ImGuiDataType_Float,  &f32_v, 0.005f,  &f32_zero, &f32_one, "%f", 1.0f);
   1394        ImGui::DragScalar("drag float ^2",  ImGuiDataType_Float,  &f32_v, 0.005f,  &f32_zero, &f32_one, "%f", 2.0f); ImGui::SameLine(); HelpMarker("You can use the 'power' parameter to increase tweaking precision on one side of the range.");
   1395        ImGui::DragScalar("drag double",    ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, NULL,     "%.10f grams", 1.0f);
   1396        ImGui::DragScalar("drag double ^2", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", 2.0f);
   1397
   1398        ImGui::Text("Sliders");
   1399        ImGui::SliderScalar("slider s8 full",     ImGuiDataType_S8,     &s8_v,  &s8_min,   &s8_max,   "%d");
   1400        ImGui::SliderScalar("slider u8 full",     ImGuiDataType_U8,     &u8_v,  &u8_min,   &u8_max,   "%u");
   1401        ImGui::SliderScalar("slider s16 full",    ImGuiDataType_S16,    &s16_v, &s16_min,  &s16_max,  "%d");
   1402        ImGui::SliderScalar("slider u16 full",    ImGuiDataType_U16,    &u16_v, &u16_min,  &u16_max,  "%u");
   1403        ImGui::SliderScalar("slider s32 low",     ImGuiDataType_S32,    &s32_v, &s32_zero, &s32_fifty,"%d");
   1404        ImGui::SliderScalar("slider s32 high",    ImGuiDataType_S32,    &s32_v, &s32_hi_a, &s32_hi_b, "%d");
   1405        ImGui::SliderScalar("slider s32 full",    ImGuiDataType_S32,    &s32_v, &s32_min,  &s32_max,  "%d");
   1406        ImGui::SliderScalar("slider u32 low",     ImGuiDataType_U32,    &u32_v, &u32_zero, &u32_fifty,"%u");
   1407        ImGui::SliderScalar("slider u32 high",    ImGuiDataType_U32,    &u32_v, &u32_hi_a, &u32_hi_b, "%u");
   1408        ImGui::SliderScalar("slider u32 full",    ImGuiDataType_U32,    &u32_v, &u32_min,  &u32_max,  "%u");
   1409        ImGui::SliderScalar("slider s64 low",     ImGuiDataType_S64,    &s64_v, &s64_zero, &s64_fifty,"%I64d");
   1410        ImGui::SliderScalar("slider s64 high",    ImGuiDataType_S64,    &s64_v, &s64_hi_a, &s64_hi_b, "%I64d");
   1411        ImGui::SliderScalar("slider s64 full",    ImGuiDataType_S64,    &s64_v, &s64_min,  &s64_max,  "%I64d");
   1412        ImGui::SliderScalar("slider u64 low",     ImGuiDataType_U64,    &u64_v, &u64_zero, &u64_fifty,"%I64u ms");
   1413        ImGui::SliderScalar("slider u64 high",    ImGuiDataType_U64,    &u64_v, &u64_hi_a, &u64_hi_b, "%I64u ms");
   1414        ImGui::SliderScalar("slider u64 full",    ImGuiDataType_U64,    &u64_v, &u64_min,  &u64_max,  "%I64u ms");
   1415        ImGui::SliderScalar("slider float low",   ImGuiDataType_Float,  &f32_v, &f32_zero, &f32_one);
   1416        ImGui::SliderScalar("slider float low^2", ImGuiDataType_Float,  &f32_v, &f32_zero, &f32_one,  "%.10f", 2.0f);
   1417        ImGui::SliderScalar("slider float high",  ImGuiDataType_Float,  &f32_v, &f32_lo_a, &f32_hi_a, "%e");
   1418        ImGui::SliderScalar("slider double low",  ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one,  "%.10f grams", 1.0f);
   1419        ImGui::SliderScalar("slider double low^2",ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one,  "%.10f", 2.0f);
   1420        ImGui::SliderScalar("slider double high", ImGuiDataType_Double, &f64_v, &f64_lo_a, &f64_hi_a, "%e grams", 1.0f);
   1421
   1422        static bool inputs_step = true;
   1423        ImGui::Text("Inputs");
   1424        ImGui::Checkbox("Show step buttons", &inputs_step);
   1425        ImGui::InputScalar("input s8",      ImGuiDataType_S8,     &s8_v,  inputs_step ? &s8_one  : NULL, NULL, "%d");
   1426        ImGui::InputScalar("input u8",      ImGuiDataType_U8,     &u8_v,  inputs_step ? &u8_one  : NULL, NULL, "%u");
   1427        ImGui::InputScalar("input s16",     ImGuiDataType_S16,    &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d");
   1428        ImGui::InputScalar("input u16",     ImGuiDataType_U16,    &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u");
   1429        ImGui::InputScalar("input s32",     ImGuiDataType_S32,    &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d");
   1430        ImGui::InputScalar("input s32 hex", ImGuiDataType_S32,    &s32_v, inputs_step ? &s32_one : NULL, NULL, "%08X", ImGuiInputTextFlags_CharsHexadecimal);
   1431        ImGui::InputScalar("input u32",     ImGuiDataType_U32,    &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u");
   1432        ImGui::InputScalar("input u32 hex", ImGuiDataType_U32,    &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X", ImGuiInputTextFlags_CharsHexadecimal);
   1433        ImGui::InputScalar("input s64",     ImGuiDataType_S64,    &s64_v, inputs_step ? &s64_one : NULL);
   1434        ImGui::InputScalar("input u64",     ImGuiDataType_U64,    &u64_v, inputs_step ? &u64_one : NULL);
   1435        ImGui::InputScalar("input float",   ImGuiDataType_Float,  &f32_v, inputs_step ? &f32_one : NULL);
   1436        ImGui::InputScalar("input double",  ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL);
   1437
   1438        ImGui::TreePop();
   1439    }
   1440
   1441    if (ImGui::TreeNode("Multi-component Widgets"))
   1442    {
   1443        static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f };
   1444        static int vec4i[4] = { 1, 5, 100, 255 };
   1445
   1446        ImGui::InputFloat2("input float2", vec4f);
   1447        ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f);
   1448        ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f);
   1449        ImGui::InputInt2("input int2", vec4i);
   1450        ImGui::DragInt2("drag int2", vec4i, 1, 0, 255);
   1451        ImGui::SliderInt2("slider int2", vec4i, 0, 255);
   1452        ImGui::Spacing();
   1453
   1454        ImGui::InputFloat3("input float3", vec4f);
   1455        ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f);
   1456        ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f);
   1457        ImGui::InputInt3("input int3", vec4i);
   1458        ImGui::DragInt3("drag int3", vec4i, 1, 0, 255);
   1459        ImGui::SliderInt3("slider int3", vec4i, 0, 255);
   1460        ImGui::Spacing();
   1461
   1462        ImGui::InputFloat4("input float4", vec4f);
   1463        ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f);
   1464        ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f);
   1465        ImGui::InputInt4("input int4", vec4i);
   1466        ImGui::DragInt4("drag int4", vec4i, 1, 0, 255);
   1467        ImGui::SliderInt4("slider int4", vec4i, 0, 255);
   1468
   1469        ImGui::TreePop();
   1470    }
   1471
   1472    if (ImGui::TreeNode("Vertical Sliders"))
   1473    {
   1474        const float spacing = 4;
   1475        ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing));
   1476
   1477        static int int_value = 0;
   1478        ImGui::VSliderInt("##int", ImVec2(18,160), &int_value, 0, 5);
   1479        ImGui::SameLine();
   1480
   1481        static float values[7] = { 0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f };
   1482        ImGui::PushID("set1");
   1483        for (int i = 0; i < 7; i++)
   1484        {
   1485            if (i > 0) ImGui::SameLine();
   1486            ImGui::PushID(i);
   1487            ImGui::PushStyleColor(ImGuiCol_FrameBg, (ImVec4)ImColor::HSV(i/7.0f, 0.5f, 0.5f));
   1488            ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, (ImVec4)ImColor::HSV(i/7.0f, 0.6f, 0.5f));
   1489            ImGui::PushStyleColor(ImGuiCol_FrameBgActive, (ImVec4)ImColor::HSV(i/7.0f, 0.7f, 0.5f));
   1490            ImGui::PushStyleColor(ImGuiCol_SliderGrab, (ImVec4)ImColor::HSV(i/7.0f, 0.9f, 0.9f));
   1491            ImGui::VSliderFloat("##v", ImVec2(18,160), &values[i], 0.0f, 1.0f, "");
   1492            if (ImGui::IsItemActive() || ImGui::IsItemHovered())
   1493                ImGui::SetTooltip("%.3f", values[i]);
   1494            ImGui::PopStyleColor(4);
   1495            ImGui::PopID();
   1496        }
   1497        ImGui::PopID();
   1498
   1499        ImGui::SameLine();
   1500        ImGui::PushID("set2");
   1501        static float values2[4] = { 0.20f, 0.80f, 0.40f, 0.25f };
   1502        const int rows = 3;
   1503        const ImVec2 small_slider_size(18, (float)(int)((160.0f - (rows - 1) * spacing) / rows));
   1504        for (int nx = 0; nx < 4; nx++)
   1505        {
   1506            if (nx > 0) ImGui::SameLine();
   1507            ImGui::BeginGroup();
   1508            for (int ny = 0; ny < rows; ny++)
   1509            {
   1510                ImGui::PushID(nx*rows+ny);
   1511                ImGui::VSliderFloat("##v", small_slider_size, &values2[nx], 0.0f, 1.0f, "");
   1512                if (ImGui::IsItemActive() || ImGui::IsItemHovered())
   1513                    ImGui::SetTooltip("%.3f", values2[nx]);
   1514                ImGui::PopID();
   1515            }
   1516            ImGui::EndGroup();
   1517        }
   1518        ImGui::PopID();
   1519
   1520        ImGui::SameLine();
   1521        ImGui::PushID("set3");
   1522        for (int i = 0; i < 4; i++)
   1523        {
   1524            if (i > 0) ImGui::SameLine();
   1525            ImGui::PushID(i);
   1526            ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40);
   1527            ImGui::VSliderFloat("##v", ImVec2(40,160), &values[i], 0.0f, 1.0f, "%.2f\nsec");
   1528            ImGui::PopStyleVar();
   1529            ImGui::PopID();
   1530        }
   1531        ImGui::PopID();
   1532        ImGui::PopStyleVar();
   1533        ImGui::TreePop();
   1534    }
   1535
   1536    if (ImGui::TreeNode("Drag and Drop"))
   1537    {
   1538        if (ImGui::TreeNode("Drag and drop in standard widgets"))
   1539        {
   1540            // ColorEdit widgets automatically act as drag source and drag target.
   1541            // They are using standardized payload strings IMGUI_PAYLOAD_TYPE_COLOR_3F and IMGUI_PAYLOAD_TYPE_COLOR_4F to allow your own widgets
   1542            // to use colors in their drag and drop interaction. Also see the demo in Color Picker -> Palette demo.
   1543            HelpMarker("You can drag from the colored squares.");
   1544            static float col1[3] = { 1.0f, 0.0f, 0.2f };
   1545            static float col2[4] = { 0.4f, 0.7f, 0.0f, 0.5f };
   1546            ImGui::ColorEdit3("color 1", col1);
   1547            ImGui::ColorEdit4("color 2", col2);
   1548            ImGui::TreePop();
   1549        }
   1550
   1551        if (ImGui::TreeNode("Drag and drop to copy/swap items"))
   1552        {
   1553            enum Mode
   1554            {
   1555                Mode_Copy,
   1556                Mode_Move,
   1557                Mode_Swap
   1558            };
   1559            static int mode = 0;
   1560            if (ImGui::RadioButton("Copy", mode == Mode_Copy)) { mode = Mode_Copy; } ImGui::SameLine();
   1561            if (ImGui::RadioButton("Move", mode == Mode_Move)) { mode = Mode_Move; } ImGui::SameLine();
   1562            if (ImGui::RadioButton("Swap", mode == Mode_Swap)) { mode = Mode_Swap; }
   1563            static const char* names[9] = { "Bobby", "Beatrice", "Betty", "Brianna", "Barry", "Bernard", "Bibi", "Blaine", "Bryn" };
   1564            for (int n = 0; n < IM_ARRAYSIZE(names); n++)
   1565            {
   1566                ImGui::PushID(n);
   1567                if ((n % 3) != 0)
   1568                    ImGui::SameLine();
   1569                ImGui::Button(names[n], ImVec2(60,60));
   1570
   1571                // Our buttons are both drag sources and drag targets here!
   1572                if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None))
   1573                {
   1574                    ImGui::SetDragDropPayload("DND_DEMO_CELL", &n, sizeof(int));    // Set payload to carry the index of our item (could be anything)
   1575                    if (mode == Mode_Copy) { ImGui::Text("Copy %s", names[n]); }    // Display preview (could be anything, e.g. when dragging an image we could decide to display the filename and a small preview of the image, etc.)
   1576                    if (mode == Mode_Move) { ImGui::Text("Move %s", names[n]); }
   1577                    if (mode == Mode_Swap) { ImGui::Text("Swap %s", names[n]); }
   1578                    ImGui::EndDragDropSource();
   1579                }
   1580                if (ImGui::BeginDragDropTarget())
   1581                {
   1582                    if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_DEMO_CELL"))
   1583                    {
   1584                        IM_ASSERT(payload->DataSize == sizeof(int));
   1585                        int payload_n = *(const int*)payload->Data;
   1586                        if (mode == Mode_Copy)
   1587                        {
   1588                            names[n] = names[payload_n];
   1589                        }
   1590                        if (mode == Mode_Move)
   1591                        {
   1592                            names[n] = names[payload_n];
   1593                            names[payload_n] = "";
   1594                        }
   1595                        if (mode == Mode_Swap)
   1596                        {
   1597                            const char* tmp = names[n];
   1598                            names[n] = names[payload_n];
   1599                            names[payload_n] = tmp;
   1600                        }
   1601                    }
   1602                    ImGui::EndDragDropTarget();
   1603                }
   1604                ImGui::PopID();
   1605            }
   1606            ImGui::TreePop();
   1607        }
   1608
   1609        if (ImGui::TreeNode("Drag to reorder items (simple)"))
   1610        {
   1611            // Simple reordering
   1612            HelpMarker("We don't use the drag and drop api at all here! Instead we query when the item is held but not hovered, and order items accordingly.");
   1613            static const char* item_names[] = { "Item One", "Item Two", "Item Three", "Item Four", "Item Five" };
   1614            for (int n = 0; n < IM_ARRAYSIZE(item_names); n++)
   1615            {
   1616                const char* item = item_names[n];
   1617                ImGui::Selectable(item);
   1618
   1619                if (ImGui::IsItemActive() && !ImGui::IsItemHovered())
   1620                {
   1621                    int n_next = n + (ImGui::GetMouseDragDelta(0).y < 0.f ? -1 : 1);
   1622                    if (n_next >= 0 && n_next < IM_ARRAYSIZE(item_names))
   1623                    {
   1624                        item_names[n] = item_names[n_next];
   1625                        item_names[n_next] = item;
   1626                        ImGui::ResetMouseDragDelta();
   1627                    }
   1628                }
   1629            }
   1630            ImGui::TreePop();
   1631        }
   1632
   1633        ImGui::TreePop();
   1634    }
   1635
   1636    if (ImGui::TreeNode("Querying Status (Active/Focused/Hovered etc.)"))
   1637    {
   1638        // Submit an item (various types available) so we can query their status in the following block.
   1639        static int item_type = 1;
   1640        ImGui::Combo("Item Type", &item_type, "Text\0Button\0Button (w/ repeat)\0Checkbox\0SliderFloat\0InputText\0InputFloat\0InputFloat3\0ColorEdit4\0MenuItem\0TreeNode\0TreeNode (w/ double-click)\0ListBox\0", 20);
   1641        ImGui::SameLine();
   1642        HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions.");
   1643        bool ret = false;
   1644        static bool b = false;
   1645        static float col4f[4] = { 1.0f, 0.5, 0.0f, 1.0f };
   1646        static char str[16] = {};
   1647        if (item_type == 0) { ImGui::Text("ITEM: Text"); }                                              // Testing text items with no identifier/interaction
   1648        if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); }                                    // Testing button
   1649        if (item_type == 2) { ImGui::PushButtonRepeat(true); ret = ImGui::Button("ITEM: Button"); ImGui::PopButtonRepeat(); } // Testing button (with repeater)
   1650        if (item_type == 3) { ret = ImGui::Checkbox("ITEM: Checkbox", &b); }                            // Testing checkbox
   1651        if (item_type == 4) { ret = ImGui::SliderFloat("ITEM: SliderFloat", &col4f[0], 0.0f, 1.0f); }   // Testing basic item
   1652        if (item_type == 5) { ret = ImGui::InputText("ITEM: InputText", &str[0], IM_ARRAYSIZE(str)); }  // Testing input text (which handles tabbing)
   1653        if (item_type == 6) { ret = ImGui::InputFloat("ITEM: InputFloat", col4f, 1.0f); }               // Testing +/- buttons on scalar input
   1654        if (item_type == 7) { ret = ImGui::InputFloat3("ITEM: InputFloat3", col4f); }                   // Testing multi-component items (IsItemXXX flags are reported merged)
   1655        if (item_type == 8) { ret = ImGui::ColorEdit4("ITEM: ColorEdit4", col4f); }                     // Testing multi-component items (IsItemXXX flags are reported merged)
   1656        if (item_type == 9) { ret = ImGui::MenuItem("ITEM: MenuItem"); }                                // Testing menu item (they use ImGuiButtonFlags_PressedOnRelease button policy)
   1657        if (item_type == 10){ ret = ImGui::TreeNode("ITEM: TreeNode"); if (ret) ImGui::TreePop(); }     // Testing tree node
   1658        if (item_type == 11){ ret = ImGui::TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_NoTreePushOnOpen); } // Testing tree node with ImGuiButtonFlags_PressedOnDoubleClick button policy.
   1659        if (item_type == 12){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", &current, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); }
   1660
   1661        // Display the value of IsItemHovered() and other common item state functions.
   1662        // Note that the ImGuiHoveredFlags_XXX flags can be combined.
   1663        // Because BulletText is an item itself and that would affect the output of IsItemXXX functions,
   1664        // we query every state in a single call to avoid storing them and to simplify the code
   1665        ImGui::BulletText(
   1666            "Return value = %d\n"
   1667            "IsItemFocused() = %d\n"
   1668            "IsItemHovered() = %d\n"
   1669            "IsItemHovered(_AllowWhenBlockedByPopup) = %d\n"
   1670            "IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n"
   1671            "IsItemHovered(_AllowWhenOverlapped) = %d\n"
   1672            "IsItemHovered(_RectOnly) = %d\n"
   1673            "IsItemActive() = %d\n"
   1674            "IsItemEdited() = %d\n"
   1675            "IsItemActivated() = %d\n"
   1676            "IsItemDeactivated() = %d\n"
   1677            "IsItemDeactivatedAfterEdit() = %d\n"
   1678            "IsItemVisible() = %d\n"
   1679            "IsItemClicked() = %d\n"
   1680            "IsItemToggledOpen() = %d\n"
   1681            "GetItemRectMin() = (%.1f, %.1f)\n"
   1682            "GetItemRectMax() = (%.1f, %.1f)\n"
   1683            "GetItemRectSize() = (%.1f, %.1f)",
   1684            ret,
   1685            ImGui::IsItemFocused(),
   1686            ImGui::IsItemHovered(),
   1687            ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
   1688            ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
   1689            ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped),
   1690            ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly),
   1691            ImGui::IsItemActive(),
   1692            ImGui::IsItemEdited(),
   1693            ImGui::IsItemActivated(),
   1694            ImGui::IsItemDeactivated(),
   1695            ImGui::IsItemDeactivatedAfterEdit(),
   1696            ImGui::IsItemVisible(),
   1697            ImGui::IsItemClicked(),
   1698            ImGui::IsItemToggledOpen(),
   1699            ImGui::GetItemRectMin().x, ImGui::GetItemRectMin().y,
   1700            ImGui::GetItemRectMax().x, ImGui::GetItemRectMax().y,
   1701            ImGui::GetItemRectSize().x, ImGui::GetItemRectSize().y
   1702        );
   1703
   1704        static bool embed_all_inside_a_child_window = false;
   1705        ImGui::Checkbox("Embed everything inside a child window (for additional testing)", &embed_all_inside_a_child_window);
   1706        if (embed_all_inside_a_child_window)
   1707            ImGui::BeginChild("outer_child", ImVec2(0, ImGui::GetFontSize() * 20), true);
   1708
   1709        // Testing IsWindowFocused() function with its various flags.
   1710        // Note that the ImGuiFocusedFlags_XXX flags can be combined.
   1711        ImGui::BulletText(
   1712            "IsWindowFocused() = %d\n"
   1713            "IsWindowFocused(_ChildWindows) = %d\n"
   1714            "IsWindowFocused(_ChildWindows|_RootWindow) = %d\n"
   1715            "IsWindowFocused(_RootWindow) = %d\n"
   1716            "IsWindowFocused(_AnyWindow) = %d\n",
   1717            ImGui::IsWindowFocused(),
   1718            ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows),
   1719            ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow),
   1720            ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow),
   1721            ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow));
   1722
   1723        // Testing IsWindowHovered() function with its various flags.
   1724        // Note that the ImGuiHoveredFlags_XXX flags can be combined.
   1725        ImGui::BulletText(
   1726            "IsWindowHovered() = %d\n"
   1727            "IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n"
   1728            "IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n"
   1729            "IsWindowHovered(_ChildWindows) = %d\n"
   1730            "IsWindowHovered(_ChildWindows|_RootWindow) = %d\n"
   1731            "IsWindowHovered(_ChildWindows|_AllowWhenBlockedByPopup) = %d\n"
   1732            "IsWindowHovered(_RootWindow) = %d\n"
   1733            "IsWindowHovered(_AnyWindow) = %d\n",
   1734            ImGui::IsWindowHovered(),
   1735            ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
   1736            ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
   1737            ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows),
   1738            ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow),
   1739            ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByPopup),
   1740            ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow),
   1741            ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow));
   1742
   1743        ImGui::BeginChild("child", ImVec2(0, 50), true);
   1744        ImGui::Text("This is another child window for testing the _ChildWindows flag.");
   1745        ImGui::EndChild();
   1746        if (embed_all_inside_a_child_window)
   1747            ImGui::EndChild();
   1748
   1749        static char dummy_str[] = "This is a dummy field to be able to tab-out of the widgets above.";
   1750        ImGui::InputText("dummy", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly);
   1751
   1752        // Calling IsItemHovered() after begin returns the hovered status of the title bar.
   1753        // This is useful in particular if you want to create a context menu (with BeginPopupContextItem) associated to the title bar of a window.
   1754        static bool test_window = false;
   1755        ImGui::Checkbox("Hovered/Active tests after Begin() for title bar testing", &test_window);
   1756        if (test_window)
   1757        {
   1758            ImGui::Begin("Title bar Hovered/Active tests", &test_window);
   1759            if (ImGui::BeginPopupContextItem()) // <-- This is using IsItemHovered()
   1760            {
   1761                if (ImGui::MenuItem("Close")) { test_window = false; }
   1762                ImGui::EndPopup();
   1763            }
   1764            ImGui::Text(
   1765                "IsItemHovered() after begin = %d (== is title bar hovered)\n"
   1766                "IsItemActive() after begin = %d (== is window being clicked/moved)\n",
   1767                ImGui::IsItemHovered(), ImGui::IsItemActive());
   1768            ImGui::End();
   1769        }
   1770
   1771        ImGui::TreePop();
   1772    }
   1773}
   1774
   1775static void ShowDemoWindowLayout()
   1776{
   1777    if (!ImGui::CollapsingHeader("Layout"))
   1778        return;
   1779
   1780    if (ImGui::TreeNode("Child windows"))
   1781    {
   1782        HelpMarker("Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window.");
   1783        static bool disable_mouse_wheel = false;
   1784        static bool disable_menu = false;
   1785        ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel);
   1786        ImGui::Checkbox("Disable Menu", &disable_menu);
   1787
   1788        static int line = 50;
   1789        bool goto_line = ImGui::Button("Goto");
   1790        ImGui::SameLine();
   1791        ImGui::SetNextItemWidth(100);
   1792        goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue);
   1793
   1794        // Child 1: no border, enable horizontal scrollbar
   1795        {
   1796            ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar | (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0);
   1797            ImGui::BeginChild("ChildL", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 260), false, window_flags);
   1798            for (int i = 0; i < 100; i++)
   1799            {
   1800                ImGui::Text("%04d: scrollable region", i);
   1801                if (goto_line && line == i)
   1802                    ImGui::SetScrollHereY();
   1803            }
   1804            if (goto_line && line >= 100)
   1805                ImGui::SetScrollHereY();
   1806            ImGui::EndChild();
   1807        }
   1808
   1809        ImGui::SameLine();
   1810
   1811        // Child 2: rounded border
   1812        {
   1813            ImGuiWindowFlags window_flags = (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0) | (disable_menu ? 0 : ImGuiWindowFlags_MenuBar);
   1814            ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f);
   1815            ImGui::BeginChild("ChildR", ImVec2(0, 260), true, window_flags);
   1816            if (!disable_menu && ImGui::BeginMenuBar())
   1817            {
   1818                if (ImGui::BeginMenu("Menu"))
   1819                {
   1820                    ShowExampleMenuFile();
   1821                    ImGui::EndMenu();
   1822                }
   1823                ImGui::EndMenuBar();
   1824            }
   1825            ImGui::Columns(2);
   1826            for (int i = 0; i < 100; i++)
   1827            {
   1828                char buf[32];
   1829                sprintf(buf, "%03d", i);
   1830                ImGui::Button(buf, ImVec2(-FLT_MIN, 0.0f));
   1831                ImGui::NextColumn();
   1832            }
   1833            ImGui::EndChild();
   1834            ImGui::PopStyleVar();
   1835        }
   1836
   1837        ImGui::Separator();
   1838
   1839        // Demonstrate a few extra things
   1840        // - Changing ImGuiCol_ChildBg (which is transparent black in default styles)
   1841        // - Using SetCursorPos() to position the child window (because the child window is an item from the POV of the parent window)
   1842        //   You can also call SetNextWindowPos() to position the child window. The parent window will effectively layout from this position.
   1843        // - Using ImGui::GetItemRectMin/Max() to query the "item" state (because the child window is an item from the POV of the parent window)
   1844        //   See "Widgets" -> "Querying Status (Active/Focused/Hovered etc.)" section for more details about this.
   1845        {
   1846            ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 10);
   1847            ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(255, 0, 0, 100));
   1848            ImGui::BeginChild("Red", ImVec2(200, 100), true, ImGuiWindowFlags_None);
   1849            for (int n = 0; n < 50; n++)
   1850                ImGui::Text("Some test %d", n);
   1851            ImGui::EndChild();
   1852            ImVec2 child_rect_min = ImGui::GetItemRectMin();
   1853            ImVec2 child_rect_max = ImGui::GetItemRectMax();
   1854            ImGui::PopStyleColor();
   1855            ImGui::Text("Rect of child window is: (%.0f,%.0f) (%.0f,%.0f)", child_rect_min.x, child_rect_min.y, child_rect_max.x, child_rect_max.y);
   1856        }
   1857
   1858        ImGui::TreePop();
   1859    }
   1860
   1861    if (ImGui::TreeNode("Widgets Width"))
   1862    {
   1863        // Use SetNextItemWidth() to set the width of a single upcoming item.
   1864        // Use PushItemWidth()/PopItemWidth() to set the width of a group of items.
   1865        static float f = 0.0f;
   1866        ImGui::Text("SetNextItemWidth/PushItemWidth(100)");
   1867        ImGui::SameLine(); HelpMarker("Fixed width.");
   1868        ImGui::SetNextItemWidth(100);
   1869        ImGui::DragFloat("float##1", &f);
   1870
   1871        ImGui::Text("SetNextItemWidth/PushItemWidth(GetWindowWidth() * 0.5f)");
   1872        ImGui::SameLine(); HelpMarker("Half of window width.");
   1873        ImGui::SetNextItemWidth(ImGui::GetWindowWidth() * 0.5f);
   1874        ImGui::DragFloat("float##2", &f);
   1875
   1876        ImGui::Text("SetNextItemWidth/PushItemWidth(GetContentRegionAvail().x * 0.5f)");
   1877        ImGui::SameLine(); HelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)");
   1878        ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x * 0.5f);
   1879        ImGui::DragFloat("float##3", &f);
   1880
   1881        ImGui::Text("SetNextItemWidth/PushItemWidth(-100)");
   1882        ImGui::SameLine(); HelpMarker("Align to right edge minus 100");
   1883        ImGui::SetNextItemWidth(-100);
   1884        ImGui::DragFloat("float##4", &f);
   1885
   1886        // Demonstrate using PushItemWidth to surround three items. Calling SetNextItemWidth() before each of them would have the same effect.
   1887        ImGui::Text("SetNextItemWidth/PushItemWidth(-1)");
   1888        ImGui::SameLine(); HelpMarker("Align to right edge");
   1889        ImGui::PushItemWidth(-1);
   1890        ImGui::DragFloat("##float5a", &f);
   1891        ImGui::DragFloat("##float5b", &f);
   1892        ImGui::DragFloat("##float5c", &f);
   1893        ImGui::PopItemWidth();
   1894
   1895        ImGui::TreePop();
   1896    }
   1897
   1898    if (ImGui::TreeNode("Basic Horizontal Layout"))
   1899    {
   1900        ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceding item)");
   1901
   1902        // Text
   1903        ImGui::Text("Two items: Hello"); ImGui::SameLine();
   1904        ImGui::TextColored(ImVec4(1,1,0,1), "Sailor");
   1905
   1906        // Adjust spacing
   1907        ImGui::Text("More spacing: Hello"); ImGui::SameLine(0, 20);
   1908        ImGui::TextColored(ImVec4(1,1,0,1), "Sailor");
   1909
   1910        // Button
   1911        ImGui::AlignTextToFramePadding();
   1912        ImGui::Text("Normal buttons"); ImGui::SameLine();
   1913        ImGui::Button("Banana"); ImGui::SameLine();
   1914        ImGui::Button("Apple"); ImGui::SameLine();
   1915        ImGui::Button("Corniflower");
   1916
   1917        // Button
   1918        ImGui::Text("Small buttons"); ImGui::SameLine();
   1919        ImGui::SmallButton("Like this one"); ImGui::SameLine();
   1920        ImGui::Text("can fit within a text block.");
   1921
   1922        // Aligned to arbitrary position. Easy/cheap column.
   1923        ImGui::Text("Aligned");
   1924        ImGui::SameLine(150); ImGui::Text("x=150");
   1925        ImGui::SameLine(300); ImGui::Text("x=300");
   1926        ImGui::Text("Aligned");
   1927        ImGui::SameLine(150); ImGui::SmallButton("x=150");
   1928        ImGui::SameLine(300); ImGui::SmallButton("x=300");
   1929
   1930        // Checkbox
   1931        static bool c1 = false, c2 = false, c3 = false, c4 = false;
   1932        ImGui::Checkbox("My", &c1); ImGui::SameLine();
   1933        ImGui::Checkbox("Tailor", &c2); ImGui::SameLine();
   1934        ImGui::Checkbox("Is", &c3); ImGui::SameLine();
   1935        ImGui::Checkbox("Rich", &c4);
   1936
   1937        // Various
   1938        static float f0 = 1.0f, f1 = 2.0f, f2 = 3.0f;
   1939        ImGui::PushItemWidth(80);
   1940        const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD" };
   1941        static int item = -1;
   1942        ImGui::Combo("Combo", &item, items, IM_ARRAYSIZE(items)); ImGui::SameLine();
   1943        ImGui::SliderFloat("X", &f0, 0.0f, 5.0f); ImGui::SameLine();
   1944        ImGui::SliderFloat("Y", &f1, 0.0f, 5.0f); ImGui::SameLine();
   1945        ImGui::SliderFloat("Z", &f2, 0.0f, 5.0f);
   1946        ImGui::PopItemWidth();
   1947
   1948        ImGui::PushItemWidth(80);
   1949        ImGui::Text("Lists:");
   1950        static int selection[4] = { 0, 1, 2, 3 };
   1951        for (int i = 0; i < 4; i++)
   1952        {
   1953            if (i > 0) ImGui::SameLine();
   1954            ImGui::PushID(i);
   1955            ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items));
   1956            ImGui::PopID();
   1957            //if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i);
   1958        }
   1959        ImGui::PopItemWidth();
   1960
   1961        // Dummy
   1962        ImVec2 button_sz(40, 40);
   1963        ImGui::Button("A", button_sz); ImGui::SameLine();
   1964        ImGui::Dummy(button_sz); ImGui::SameLine();
   1965        ImGui::Button("B", button_sz);
   1966
   1967        // Manually wrapping (we should eventually provide this as an automatic layout feature, but for now you can do it manually)
   1968        ImGui::Text("Manually wrapping:");
   1969        ImGuiStyle& style = ImGui::GetStyle();
   1970        int buttons_count = 20;
   1971        float window_visible_x2 = ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x;
   1972        for (int n = 0; n < buttons_count; n++)
   1973        {
   1974            ImGui::PushID(n);
   1975            ImGui::Button("Box", button_sz);
   1976            float last_button_x2 = ImGui::GetItemRectMax().x;
   1977            float next_button_x2 = last_button_x2 + style.ItemSpacing.x + button_sz.x; // Expected position if next button was on same line
   1978            if (n + 1 < buttons_count && next_button_x2 < window_visible_x2)
   1979                ImGui::SameLine();
   1980            ImGui::PopID();
   1981        }
   1982
   1983        ImGui::TreePop();
   1984    }
   1985
   1986    if (ImGui::TreeNode("Tabs"))
   1987    {
   1988        if (ImGui::TreeNode("Basic"))
   1989        {
   1990            ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
   1991            if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
   1992            {
   1993                if (ImGui::BeginTabItem("Avocado"))
   1994                {
   1995                    ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah");
   1996                    ImGui::EndTabItem();
   1997                }
   1998                if (ImGui::BeginTabItem("Broccoli"))
   1999                {
   2000                    ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah");
   2001                    ImGui::EndTabItem();
   2002                }
   2003                if (ImGui::BeginTabItem("Cucumber"))
   2004                {
   2005                    ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah");
   2006                    ImGui::EndTabItem();
   2007                }
   2008                ImGui::EndTabBar();
   2009            }
   2010            ImGui::Separator();
   2011            ImGui::TreePop();
   2012        }
   2013
   2014        if (ImGui::TreeNode("Advanced & Close Button"))
   2015        {
   2016            // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0).
   2017            static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable;
   2018            ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_Reorderable);
   2019            ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs);
   2020            ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
   2021            ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
   2022            if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0)
   2023                tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_;
   2024            if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
   2025                tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
   2026            if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
   2027                tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
   2028
   2029            // Tab Bar
   2030            const char* names[4] = { "Artichoke", "Beetroot", "Celery", "Daikon" };
   2031            static bool opened[4] = { true, true, true, true }; // Persistent user state
   2032            for (int n = 0; n < IM_ARRAYSIZE(opened); n++)
   2033            {
   2034                if (n > 0) { ImGui::SameLine(); }
   2035                ImGui::Checkbox(names[n], &opened[n]);
   2036            }
   2037
   2038            // Passing a bool* to BeginTabItem() is similar to passing one to Begin(): the underlying bool will be set to false when the tab is closed.
   2039            if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
   2040            {
   2041                for (int n = 0; n < IM_ARRAYSIZE(opened); n++)
   2042                    if (opened[n] && ImGui::BeginTabItem(names[n], &opened[n], ImGuiTabItemFlags_None))
   2043                    {
   2044                        ImGui::Text("This is the %s tab!", names[n]);
   2045                        if (n & 1)
   2046                            ImGui::Text("I am an odd tab.");
   2047                        ImGui::EndTabItem();
   2048                    }
   2049                ImGui::EndTabBar();
   2050            }
   2051            ImGui::Separator();
   2052            ImGui::TreePop();
   2053        }
   2054        ImGui::TreePop();
   2055    }
   2056
   2057    if (ImGui::TreeNode("Groups"))
   2058    {
   2059        HelpMarker("BeginGroup() basically locks the horizontal position for new line. EndGroup() bundles the whole group so that you can use \"item\" functions such as IsItemHovered()/IsItemActive() or SameLine() etc. on the whole group.");
   2060        ImGui::BeginGroup();
   2061        {
   2062            ImGui::BeginGroup();
   2063            ImGui::Button("AAA");
   2064            ImGui::SameLine();
   2065            ImGui::Button("BBB");
   2066            ImGui::SameLine();
   2067            ImGui::BeginGroup();
   2068            ImGui::Button("CCC");
   2069            ImGui::Button("DDD");
   2070            ImGui::EndGroup();
   2071            ImGui::SameLine();
   2072            ImGui::Button("EEE");
   2073            ImGui::EndGroup();
   2074            if (ImGui::IsItemHovered())
   2075                ImGui::SetTooltip("First group hovered");
   2076        }
   2077        // Capture the group size and create widgets using the same size
   2078        ImVec2 size = ImGui::GetItemRectSize();
   2079        const float values[5] = { 0.5f, 0.20f, 0.80f, 0.60f, 0.25f };
   2080        ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size);
   2081
   2082        ImGui::Button("ACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f, size.y));
   2083        ImGui::SameLine();
   2084        ImGui::Button("REACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f, size.y));
   2085        ImGui::EndGroup();
   2086        ImGui::SameLine();
   2087
   2088        ImGui::Button("LEVERAGE\nBUZZWORD", size);
   2089        ImGui::SameLine();
   2090
   2091        if (ImGui::ListBoxHeader("List", size))
   2092        {
   2093            ImGui::Selectable("Selected", true);
   2094            ImGui::Selectable("Not Selected", false);
   2095            ImGui::ListBoxFooter();
   2096        }
   2097
   2098        ImGui::TreePop();
   2099    }
   2100
   2101    if (ImGui::TreeNode("Text Baseline Alignment"))
   2102    {
   2103        {
   2104            ImGui::BulletText("Text baseline:");
   2105            ImGui::SameLine();
   2106            HelpMarker("This is testing the vertical alignment that gets applied on text to keep it aligned with widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets.");
   2107            ImGui::Indent();
   2108
   2109            ImGui::Text("KO Blahblah"); ImGui::SameLine();
   2110            ImGui::Button("Some framed item"); ImGui::SameLine();
   2111            HelpMarker("Baseline of button will look misaligned with text..");
   2112
   2113            // If your line starts with text, call AlignTextToFramePadding() to align text to upcoming widgets.
   2114            // Because we don't know what's coming after the Text() statement, we need to move the text baseline down by FramePadding.y
   2115            ImGui::AlignTextToFramePadding();
   2116            ImGui::Text("OK Blahblah"); ImGui::SameLine();
   2117            ImGui::Button("Some framed item"); ImGui::SameLine();
   2118            HelpMarker("We call AlignTextToFramePadding() to vertically align the text baseline by +FramePadding.y");
   2119
   2120            // SmallButton() uses the same vertical padding as Text
   2121            ImGui::Button("TEST##1"); ImGui::SameLine();
   2122            ImGui::Text("TEST"); ImGui::SameLine();
   2123            ImGui::SmallButton("TEST##2");
   2124
   2125            // If your line starts with text, call AlignTextToFramePadding() to align text to upcoming widgets.
   2126            ImGui::AlignTextToFramePadding();
   2127            ImGui::Text("Text aligned to framed item"); ImGui::SameLine();
   2128            ImGui::Button("Item##1"); ImGui::SameLine();
   2129            ImGui::Text("Item"); ImGui::SameLine();
   2130            ImGui::SmallButton("Item##2"); ImGui::SameLine();
   2131            ImGui::Button("Item##3");
   2132
   2133            ImGui::Unindent();
   2134        }
   2135
   2136        ImGui::Spacing();
   2137
   2138        {
   2139            ImGui::BulletText("Multi-line text:");
   2140            ImGui::Indent();
   2141            ImGui::Text("One\nTwo\nThree"); ImGui::SameLine();
   2142            ImGui::Text("Hello\nWorld"); ImGui::SameLine();
   2143            ImGui::Text("Banana");
   2144
   2145            ImGui::Text("Banana"); ImGui::SameLine();
   2146            ImGui::Text("Hello\nWorld"); ImGui::SameLine();
   2147            ImGui::Text("One\nTwo\nThree");
   2148
   2149            ImGui::Button("HOP##1"); ImGui::SameLine();
   2150            ImGui::Text("Banana"); ImGui::SameLine();
   2151            ImGui::Text("Hello\nWorld"); ImGui::SameLine();
   2152            ImGui::Text("Banana");
   2153
   2154            ImGui::Button("HOP##2"); ImGui::SameLine();
   2155            ImGui::Text("Hello\nWorld"); ImGui::SameLine();
   2156            ImGui::Text("Banana");
   2157            ImGui::Unindent();
   2158        }
   2159
   2160        ImGui::Spacing();
   2161
   2162        {
   2163            ImGui::BulletText("Misc items:");
   2164            ImGui::Indent();
   2165
   2166            // SmallButton() sets FramePadding to zero. Text baseline is aligned to match baseline of previous Button
   2167            ImGui::Button("80x80", ImVec2(80, 80));
   2168            ImGui::SameLine();
   2169            ImGui::Button("50x50", ImVec2(50, 50));
   2170            ImGui::SameLine();
   2171            ImGui::Button("Button()");
   2172            ImGui::SameLine();
   2173            ImGui::SmallButton("SmallButton()");
   2174
   2175            // Tree
   2176            const float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
   2177            ImGui::Button("Button##1");
   2178            ImGui::SameLine(0.0f, spacing);
   2179            if (ImGui::TreeNode("Node##1")) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); }    // Dummy tree data
   2180
   2181            ImGui::AlignTextToFramePadding();           // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit).
   2182            bool node_open = ImGui::TreeNode("Node##2");// Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add child content.
   2183            ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2");
   2184            if (node_open) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); }   // Dummy tree data
   2185
   2186            // Bullet
   2187            ImGui::Button("Button##3");
   2188            ImGui::SameLine(0.0f, spacing);
   2189            ImGui::BulletText("Bullet text");
   2190
   2191            ImGui::AlignTextToFramePadding();
   2192            ImGui::BulletText("Node");
   2193            ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##4");
   2194            ImGui::Unindent();
   2195        }
   2196
   2197        ImGui::TreePop();
   2198    }
   2199
   2200    if (ImGui::TreeNode("Scrolling"))
   2201    {
   2202        // Vertical scroll functions
   2203        HelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given vertical position.");
   2204
   2205        static int track_item = 50;
   2206        static bool enable_track = true;
   2207        static bool enable_extra_decorations = false;
   2208        static float scroll_to_off_px = 0.0f;
   2209        static float scroll_to_pos_px = 200.0f;
   2210
   2211        ImGui::Checkbox("Decoration", &enable_extra_decorations);
   2212        ImGui::SameLine();
   2213        HelpMarker("We expose this for testing because scrolling sometimes had issues with window decoration such as menu-bars.");
   2214
   2215        ImGui::Checkbox("Track", &enable_track);
   2216        ImGui::PushItemWidth(100);
   2217        ImGui::SameLine(140); enable_track |= ImGui::DragInt("##item", &track_item, 0.25f, 0, 99, "Item = %d");
   2218
   2219        bool scroll_to_off = ImGui::Button("Scroll Offset");
   2220        ImGui::SameLine(140); scroll_to_off |= ImGui::DragFloat("##off", &scroll_to_off_px, 1.00f, 0, FLT_MAX, "+%.0f px");
   2221
   2222        bool scroll_to_pos = ImGui::Button("Scroll To Pos");
   2223        ImGui::SameLine(140); scroll_to_pos |= ImGui::DragFloat("##pos", &scroll_to_pos_px, 1.00f, -10, FLT_MAX, "X/Y = %.0f px");
   2224        ImGui::PopItemWidth();
   2225
   2226        if (scroll_to_off || scroll_to_pos)
   2227            enable_track = false;
   2228
   2229        ImGuiStyle& style = ImGui::GetStyle();
   2230        float child_w = (ImGui::GetContentRegionAvail().x - 4 * style.ItemSpacing.x) / 5;
   2231        if (child_w < 1.0f)
   2232            child_w = 1.0f;
   2233        ImGui::PushID("##VerticalScrolling");
   2234        for (int i = 0; i < 5; i++)
   2235        {
   2236            if (i > 0) ImGui::SameLine();
   2237            ImGui::BeginGroup();
   2238            const char* names[] = { "Top", "25%", "Center", "75%", "Bottom" };
   2239            ImGui::TextUnformatted(names[i]);
   2240
   2241            ImGuiWindowFlags child_flags = enable_extra_decorations ? ImGuiWindowFlags_MenuBar : 0;
   2242            bool window_visible = ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(child_w, 200.0f), true, child_flags);
   2243            if (ImGui::BeginMenuBar())
   2244            {
   2245                ImGui::TextUnformatted("abc");
   2246                ImGui::EndMenuBar();
   2247            }
   2248            if (scroll_to_off)
   2249                ImGui::SetScrollY(scroll_to_off_px);
   2250            if (scroll_to_pos)
   2251                ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_pos_px, i * 0.25f);
   2252            if (window_visible) // Avoid calling SetScrollHereY when running with culled items
   2253            {
   2254                for (int item = 0; item < 100; item++)
   2255                {
   2256                    if (enable_track && item == track_item)
   2257                    {
   2258                        ImGui::TextColored(ImVec4(1, 1, 0, 1), "Item %d", item);
   2259                        ImGui::SetScrollHereY(i * 0.25f); // 0.0f:top, 0.5f:center, 1.0f:bottom
   2260                    }
   2261                    else
   2262                    {
   2263                        ImGui::Text("Item %d", item);
   2264                    }
   2265                }
   2266            }
   2267            float scroll_y = ImGui::GetScrollY();
   2268            float scroll_max_y = ImGui::GetScrollMaxY();
   2269            ImGui::EndChild();
   2270            ImGui::Text("%.0f/%.0f", scroll_y, scroll_max_y);
   2271            ImGui::EndGroup();
   2272        }
   2273        ImGui::PopID();
   2274
   2275        // Horizontal scroll functions
   2276        ImGui::Spacing();
   2277        HelpMarker("Use SetScrollHereX() or SetScrollFromPosX() to scroll to a given horizontal position.\n\nUsing the \"Scroll To Pos\" button above will make the discontinuity at edges visible: scrolling to the top/bottom/left/right-most item will add an additional WindowPadding to reflect on reaching the edge of the list.\n\nBecause the clipping rectangle of most window hides half worth of WindowPadding on the left/right, using SetScrollFromPosX(+1) will usually result in clipped text whereas the equivalent SetScrollFromPosY(+1) wouldn't.");
   2278        ImGui::PushID("##HorizontalScrolling");
   2279        for (int i = 0; i < 5; i++)
   2280        {
   2281            float child_height = ImGui::GetTextLineHeight() + style.ScrollbarSize + style.WindowPadding.y * 2.0f;
   2282            ImGuiWindowFlags child_flags = ImGuiWindowFlags_HorizontalScrollbar | (enable_extra_decorations ? ImGuiWindowFlags_AlwaysVerticalScrollbar : 0);
   2283            bool window_visible = ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(-100, child_height), true, child_flags);
   2284            if (scroll_to_off)
   2285                ImGui::SetScrollX(scroll_to_off_px);
   2286            if (scroll_to_pos)
   2287                ImGui::SetScrollFromPosX(ImGui::GetCursorStartPos().x + scroll_to_pos_px, i * 0.25f);
   2288            if (window_visible) // Avoid calling SetScrollHereY when running with culled items
   2289            {
   2290                for (int item = 0; item < 100; item++)
   2291                {
   2292                    if (enable_track && item == track_item)
   2293                    {
   2294                        ImGui::TextColored(ImVec4(1, 1, 0, 1), "Item %d", item);
   2295                        ImGui::SetScrollHereX(i * 0.25f); // 0.0f:left, 0.5f:center, 1.0f:right
   2296                    }
   2297                    else
   2298                    {
   2299                        ImGui::Text("Item %d", item);
   2300                    }
   2301                    ImGui::SameLine();
   2302                }
   2303            }
   2304            float scroll_x = ImGui::GetScrollX();
   2305            float scroll_max_x = ImGui::GetScrollMaxX();
   2306            ImGui::EndChild();
   2307            ImGui::SameLine();
   2308            const char* names[] = { "Left", "25%", "Center", "75%", "Right" };
   2309            ImGui::Text("%s\n%.0f/%.0f", names[i], scroll_x, scroll_max_x);
   2310            ImGui::Spacing();
   2311        }
   2312        ImGui::PopID();
   2313
   2314        // Miscellaneous Horizontal Scrolling Demo
   2315        HelpMarker("Horizontal scrolling for a window has to be enabled explicitly via the ImGuiWindowFlags_HorizontalScrollbar flag.\n\nYou may want to explicitly specify content width by calling SetNextWindowContentWidth() before Begin().");
   2316        static int lines = 7;
   2317        ImGui::SliderInt("Lines", &lines, 1, 15);
   2318        ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
   2319        ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 1.0f));
   2320        ImGui::BeginChild("scrolling", ImVec2(0, ImGui::GetFrameHeightWithSpacing() * 7 + 30), true, ImGuiWindowFlags_HorizontalScrollbar);
   2321        for (int line = 0; line < lines; line++)
   2322        {
   2323            // Display random stuff (for the sake of this trivial demo we are using basic Button+SameLine. If you want to create your own time line for a real application you may be better off
   2324            // manipulating the cursor position yourself, aka using SetCursorPos/SetCursorScreenPos to position the widgets yourself. You may also want to use the lower-level ImDrawList API)
   2325            int num_buttons = 10 + ((line & 1) ? line * 9 : line * 3);
   2326            for (int n = 0; n < num_buttons; n++)
   2327            {
   2328                if (n > 0) ImGui::SameLine();
   2329                ImGui::PushID(n + line * 1000);
   2330                char num_buf[16];
   2331                sprintf(num_buf, "%d", n);
   2332                const char* label = (!(n%15)) ? "FizzBuzz" : (!(n%3)) ? "Fizz" : (!(n%5)) ? "Buzz" : num_buf;
   2333                float hue = n*0.05f;
   2334                ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(hue, 0.6f, 0.6f));
   2335                ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(hue, 0.7f, 0.7f));
   2336                ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(hue, 0.8f, 0.8f));
   2337                ImGui::Button(label, ImVec2(40.0f + sinf((float)(line + n)) * 20.0f, 0.0f));
   2338                ImGui::PopStyleColor(3);
   2339                ImGui::PopID();
   2340            }
   2341        }
   2342        float scroll_x = ImGui::GetScrollX();
   2343        float scroll_max_x = ImGui::GetScrollMaxX();
   2344        ImGui::EndChild();
   2345        ImGui::PopStyleVar(2);
   2346        float scroll_x_delta = 0.0f;
   2347        ImGui::SmallButton("<<"); if (ImGui::IsItemActive()) { scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; } ImGui::SameLine();
   2348        ImGui::Text("Scroll from code"); ImGui::SameLine();
   2349        ImGui::SmallButton(">>"); if (ImGui::IsItemActive()) { scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; } ImGui::SameLine();
   2350        ImGui::Text("%.0f/%.0f", scroll_x, scroll_max_x);
   2351        if (scroll_x_delta != 0.0f)
   2352        {
   2353            ImGui::BeginChild("scrolling"); // Demonstrate a trick: you can use Begin to set yourself in the context of another window (here we are already out of your child window)
   2354            ImGui::SetScrollX(ImGui::GetScrollX() + scroll_x_delta);
   2355            ImGui::EndChild();
   2356        }
   2357        ImGui::Spacing();
   2358
   2359        static bool show_horizontal_contents_size_demo_window = false;
   2360        ImGui::Checkbox("Show Horizontal contents size demo window", &show_horizontal_contents_size_demo_window);
   2361
   2362        if (show_horizontal_contents_size_demo_window)
   2363        {
   2364            static bool show_h_scrollbar = true;
   2365            static bool show_button = true;
   2366            static bool show_tree_nodes = true;
   2367            static bool show_text_wrapped = false;
   2368            static bool show_columns = true;
   2369            static bool show_tab_bar = true;
   2370            static bool show_child = false;
   2371            static bool explicit_content_size = false;
   2372            static float contents_size_x = 300.0f;
   2373            if (explicit_content_size)
   2374                ImGui::SetNextWindowContentSize(ImVec2(contents_size_x, 0.0f));
   2375            ImGui::Begin("Horizontal contents size demo window", &show_horizontal_contents_size_demo_window, show_h_scrollbar ? ImGuiWindowFlags_HorizontalScrollbar : 0);
   2376            ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2, 0));
   2377            ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 0));
   2378            HelpMarker("Test of different widgets react and impact the work rectangle growing when horizontal scrolling is enabled.\n\nUse 'Metrics->Tools->Show windows rectangles' to visualize rectangles.");
   2379            ImGui::Checkbox("H-scrollbar", &show_h_scrollbar);
   2380            ImGui::Checkbox("Button", &show_button);            // Will grow contents size (unless explicitly overwritten)
   2381            ImGui::Checkbox("Tree nodes", &show_tree_nodes);    // Will grow contents size and display highlight over full width
   2382            ImGui::Checkbox("Text wrapped", &show_text_wrapped);// Will grow and use contents size
   2383            ImGui::Checkbox("Columns", &show_columns);          // Will use contents size
   2384            ImGui::Checkbox("Tab bar", &show_tab_bar);          // Will use contents size
   2385            ImGui::Checkbox("Child", &show_child);              // Will grow and use contents size
   2386            ImGui::Checkbox("Explicit content size", &explicit_content_size);
   2387            ImGui::Text("Scroll %.1f/%.1f %.1f/%.1f", ImGui::GetScrollX(), ImGui::GetScrollMaxX(), ImGui::GetScrollY(), ImGui::GetScrollMaxY());
   2388            if (explicit_content_size)
   2389            {
   2390                ImGui::SameLine();
   2391                ImGui::SetNextItemWidth(100);
   2392                ImGui::DragFloat("##csx", &contents_size_x);
   2393                ImVec2 p = ImGui::GetCursorScreenPos();
   2394                ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x + 10, p.y + 10), IM_COL32_WHITE);
   2395                ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(p.x + contents_size_x - 10, p.y), ImVec2(p.x + contents_size_x, p.y + 10), IM_COL32_WHITE);
   2396                ImGui::Dummy(ImVec2(0, 10));
   2397            }
   2398            ImGui::PopStyleVar(2);
   2399            ImGui::Separator();
   2400            if (show_button)
   2401            {
   2402                ImGui::Button("this is a 300-wide button", ImVec2(300, 0));
   2403            }
   2404            if (show_tree_nodes)
   2405            {
   2406                bool open = true;
   2407                if (ImGui::TreeNode("this is a tree node"))
   2408                {
   2409                    if (ImGui::TreeNode("another one of those tree node..."))
   2410                    {
   2411                        ImGui::Text("Some tree contents");
   2412                        ImGui::TreePop();
   2413                    }
   2414                    ImGui::TreePop();
   2415                }
   2416                ImGui::CollapsingHeader("CollapsingHeader", &open);
   2417            }
   2418            if (show_text_wrapped)
   2419            {
   2420                ImGui::TextWrapped("This text should automatically wrap on the edge of the work rectangle.");
   2421            }
   2422            if (show_columns)
   2423            {
   2424                ImGui::Columns(4);
   2425                for (int n = 0; n < 4; n++)
   2426                {
   2427                    ImGui::Text("Width %.2f", ImGui::GetColumnWidth());
   2428                    ImGui::NextColumn();
   2429                }
   2430                ImGui::Columns(1);
   2431            }
   2432            if (show_tab_bar && ImGui::BeginTabBar("Hello"))
   2433            {
   2434                if (ImGui::BeginTabItem("OneOneOne")) { ImGui::EndTabItem(); }
   2435                if (ImGui::BeginTabItem("TwoTwoTwo")) { ImGui::EndTabItem(); }
   2436                if (ImGui::BeginTabItem("ThreeThreeThree")) { ImGui::EndTabItem(); }
   2437                if (ImGui::BeginTabItem("FourFourFour")) { ImGui::EndTabItem(); }
   2438                ImGui::EndTabBar();
   2439            }
   2440            if (show_child)
   2441            {
   2442                ImGui::BeginChild("child", ImVec2(0,0), true);
   2443                ImGui::EndChild();
   2444            }
   2445            ImGui::End();
   2446        }
   2447
   2448        ImGui::TreePop();
   2449    }
   2450
   2451    if (ImGui::TreeNode("Clipping"))
   2452    {
   2453        static ImVec2 size(100, 100), offset(50, 20);
   2454        ImGui::TextWrapped("On a per-widget basis we are occasionally clipping text CPU-side if it won't fit in its frame. Otherwise we are doing coarser clipping + passing a scissor rectangle to the renderer. The system is designed to try minimizing both execution and CPU/GPU rendering cost.");
   2455        ImGui::DragFloat2("size", (float*)&size, 0.5f, 1.0f, 200.0f, "%.0f");
   2456        ImGui::TextWrapped("(Click and drag)");
   2457        ImVec2 pos = ImGui::GetCursorScreenPos();
   2458        ImVec4 clip_rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y);
   2459        ImGui::InvisibleButton("##dummy", size);
   2460        if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0)) { offset.x += ImGui::GetIO().MouseDelta.x; offset.y += ImGui::GetIO().MouseDelta.y; }
   2461        ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x + size.x, pos.y + size.y), IM_COL32(90, 90, 120, 255));
   2462        ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*2.0f, ImVec2(pos.x + offset.x, pos.y + offset.y), IM_COL32(255, 255, 255, 255), "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect);
   2463        ImGui::TreePop();
   2464    }
   2465}
   2466
   2467static void ShowDemoWindowPopups()
   2468{
   2469    if (!ImGui::CollapsingHeader("Popups & Modal windows"))
   2470        return;
   2471
   2472    // The properties of popups windows are:
   2473    // - They block normal mouse hovering detection outside them. (*)
   2474    // - Unless modal, they can be closed by clicking anywhere outside them, or by pressing ESCAPE.
   2475    // - Their visibility state (~bool) is held internally by Dear ImGui instead of being held by the programmer as we are used to with regular Begin() calls.
   2476    //   User can manipulate the visibility state by calling OpenPopup().
   2477    // (*) One can use IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup) to bypass it and detect hovering even when normally blocked by a popup.
   2478    // Those three properties are connected. The library needs to hold their visibility state because it can close popups at any time.
   2479
   2480    // Typical use for regular windows:
   2481    //   bool my_tool_is_active = false; if (ImGui::Button("Open")) my_tool_is_active = true; [...] if (my_tool_is_active) Begin("My Tool", &my_tool_is_active) { [...] } End();
   2482    // Typical use for popups:
   2483    //   if (ImGui::Button("Open")) ImGui::OpenPopup("MyPopup"); if (ImGui::BeginPopup("MyPopup") { [...] EndPopup(); }
   2484
   2485    // With popups we have to go through a library call (here OpenPopup) to manipulate the visibility state.
   2486    // This may be a bit confusing at first but it should quickly make sense. Follow on the examples below.
   2487
   2488    if (ImGui::TreeNode("Popups"))
   2489    {
   2490        ImGui::TextWrapped("When a popup is active, it inhibits interacting with windows that are behind the popup. Clicking outside the popup closes it.");
   2491
   2492        static int selected_fish = -1;
   2493        const char* names[] = { "Bream", "Haddock", "Mackerel", "Pollock", "Tilefish" };
   2494        static bool toggles[] = { true, false, false, false, false };
   2495
   2496        // Simple selection popup
   2497        // (If you want to show the current selection inside the Button itself, you may want to build a string using the "###" operator to preserve a constant ID with a variable label)
   2498        if (ImGui::Button("Select.."))
   2499            ImGui::OpenPopup("my_select_popup");
   2500        ImGui::SameLine();
   2501        ImGui::TextUnformatted(selected_fish == -1 ? "<None>" : names[selected_fish]);
   2502        if (ImGui::BeginPopup("my_select_popup"))
   2503        {
   2504            ImGui::Text("Aquarium");
   2505            ImGui::Separator();
   2506            for (int i = 0; i < IM_ARRAYSIZE(names); i++)
   2507                if (ImGui::Selectable(names[i]))
   2508                    selected_fish = i;
   2509            ImGui::EndPopup();
   2510        }
   2511
   2512        // Showing a menu with toggles
   2513        if (ImGui::Button("Toggle.."))
   2514            ImGui::OpenPopup("my_toggle_popup");
   2515        if (ImGui::BeginPopup("my_toggle_popup"))
   2516        {
   2517            for (int i = 0; i < IM_ARRAYSIZE(names); i++)
   2518                ImGui::MenuItem(names[i], "", &toggles[i]);
   2519            if (ImGui::BeginMenu("Sub-menu"))
   2520            {
   2521                ImGui::MenuItem("Click me");
   2522                ImGui::EndMenu();
   2523            }
   2524
   2525            ImGui::Separator();
   2526            ImGui::Text("Tooltip here");
   2527            if (ImGui::IsItemHovered())
   2528                ImGui::SetTooltip("I am a tooltip over a popup");
   2529
   2530            if (ImGui::Button("Stacked Popup"))
   2531                ImGui::OpenPopup("another popup");
   2532            if (ImGui::BeginPopup("another popup"))
   2533            {
   2534                for (int i = 0; i < IM_ARRAYSIZE(names); i++)
   2535                    ImGui::MenuItem(names[i], "", &toggles[i]);
   2536                if (ImGui::BeginMenu("Sub-menu"))
   2537                {
   2538                    ImGui::MenuItem("Click me");
   2539                    if (ImGui::Button("Stacked Popup"))
   2540                        ImGui::OpenPopup("another popup");
   2541                    if (ImGui::BeginPopup("another popup"))
   2542                    {
   2543                        ImGui::Text("I am the last one here.");
   2544                        ImGui::EndPopup();
   2545                    }
   2546                    ImGui::EndMenu();
   2547                }
   2548                ImGui::EndPopup();
   2549            }
   2550            ImGui::EndPopup();
   2551        }
   2552
   2553        // Call the more complete ShowExampleMenuFile which we use in various places of this demo
   2554        if (ImGui::Button("File Menu.."))
   2555            ImGui::OpenPopup("my_file_popup");
   2556        if (ImGui::BeginPopup("my_file_popup"))
   2557        {
   2558            ShowExampleMenuFile();
   2559            ImGui::EndPopup();
   2560        }
   2561
   2562        ImGui::TreePop();
   2563    }
   2564
   2565    if (ImGui::TreeNode("Context menus"))
   2566    {
   2567        // BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing:
   2568        //    if (IsItemHovered() && IsMouseReleased(0))
   2569        //       OpenPopup(id);
   2570        //    return BeginPopup(id);
   2571        // For more advanced uses you may want to replicate and cuztomize this code. This the comments inside BeginPopupContextItem() implementation.
   2572        static float value = 0.5f;
   2573        ImGui::Text("Value = %.3f (<-- right-click here)", value);
   2574        if (ImGui::BeginPopupContextItem("item context menu"))
   2575        {
   2576            if (ImGui::Selectable("Set to zero")) value = 0.0f;
   2577            if (ImGui::Selectable("Set to PI")) value = 3.1415f;
   2578            ImGui::SetNextItemWidth(-1);
   2579            ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f);
   2580            ImGui::EndPopup();
   2581        }
   2582
   2583        // We can also use OpenPopupOnItemClick() which is the same as BeginPopupContextItem() but without the Begin call.
   2584        // So here we will make it that clicking on the text field with the right mouse button (1) will toggle the visibility of the popup above.
   2585        ImGui::Text("(You can also right-click me to open the same popup as above.)");
   2586        ImGui::OpenPopupOnItemClick("item context menu", 1);
   2587
   2588        // When used after an item that has an ID (here the Button), we can skip providing an ID to BeginPopupContextItem().
   2589        // BeginPopupContextItem() will use the last item ID as the popup ID.
   2590        // In addition here, we want to include your editable label inside the button label. We use the ### operator to override the ID (read FAQ about ID for details)
   2591        static char name[32] = "Label1";
   2592        char buf[64]; sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label
   2593        ImGui::Button(buf);
   2594        if (ImGui::BeginPopupContextItem())
   2595        {
   2596            ImGui::Text("Edit name:");
   2597            ImGui::InputText("##edit", name, IM_ARRAYSIZE(name));
   2598            if (ImGui::Button("Close"))
   2599                ImGui::CloseCurrentPopup();
   2600            ImGui::EndPopup();
   2601        }
   2602        ImGui::SameLine(); ImGui::Text("(<-- right-click here)");
   2603
   2604        ImGui::TreePop();
   2605    }
   2606
   2607    if (ImGui::TreeNode("Modals"))
   2608    {
   2609        ImGui::TextWrapped("Modal windows are like popups but the user cannot close them by clicking outside the window.");
   2610
   2611        if (ImGui::Button("Delete.."))
   2612            ImGui::OpenPopup("Delete?");
   2613
   2614        if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize))
   2615        {
   2616            ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n");
   2617            ImGui::Separator();
   2618
   2619            //static int dummy_i = 0;
   2620            //ImGui::Combo("Combo", &dummy_i, "Delete\0Delete harder\0");
   2621
   2622            static bool dont_ask_me_next_time = false;
   2623            ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
   2624            ImGui::Checkbox("Don't ask me next time", &dont_ask_me_next_time);
   2625            ImGui::PopStyleVar();
   2626
   2627            if (ImGui::Button("OK", ImVec2(120, 0))) { ImGui::CloseCurrentPopup(); }
   2628            ImGui::SetItemDefaultFocus();
   2629            ImGui::SameLine();
   2630            if (ImGui::Button("Cancel", ImVec2(120, 0))) { ImGui::CloseCurrentPopup(); }
   2631            ImGui::EndPopup();
   2632        }
   2633
   2634        if (ImGui::Button("Stacked modals.."))
   2635            ImGui::OpenPopup("Stacked 1");
   2636        if (ImGui::BeginPopupModal("Stacked 1", NULL, ImGuiWindowFlags_MenuBar))
   2637        {
   2638            if (ImGui::BeginMenuBar())
   2639            {
   2640                if (ImGui::BeginMenu("File"))
   2641                {
   2642                    if (ImGui::MenuItem("Dummy menu item")) {}
   2643                    ImGui::EndMenu();
   2644                }
   2645                ImGui::EndMenuBar();
   2646            }
   2647            ImGui::Text("Hello from Stacked The First\nUsing style.Colors[ImGuiCol_ModalWindowDimBg] behind it.");
   2648
   2649            // Testing behavior of widgets stacking their own regular popups over the modal.
   2650            static int item = 1;
   2651            static float color[4] = { 0.4f,0.7f,0.0f,0.5f };
   2652            ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
   2653            ImGui::ColorEdit4("color", color);
   2654
   2655            if (ImGui::Button("Add another modal.."))
   2656                ImGui::OpenPopup("Stacked 2");
   2657
   2658            // Also demonstrate passing a bool* to BeginPopupModal(), this will create a regular close button which will close the popup.
   2659            // Note that the visibility state of popups is owned by imgui, so the input value of the bool actually doesn't matter here.
   2660            bool dummy_open = true;
   2661            if (ImGui::BeginPopupModal("Stacked 2", &dummy_open))
   2662            {
   2663                ImGui::Text("Hello from Stacked The Second!");
   2664                if (ImGui::Button("Close"))
   2665                    ImGui::CloseCurrentPopup();
   2666                ImGui::EndPopup();
   2667            }
   2668
   2669            if (ImGui::Button("Close"))
   2670                ImGui::CloseCurrentPopup();
   2671            ImGui::EndPopup();
   2672        }
   2673
   2674        ImGui::TreePop();
   2675    }
   2676
   2677    if (ImGui::TreeNode("Menus inside a regular window"))
   2678    {
   2679        ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!");
   2680        ImGui::Separator();
   2681        // NB: As a quirk in this very specific example, we want to differentiate the parent of this menu from the parent of the various popup menus above.
   2682        // To do so we are encloding the items in a PushID()/PopID() block to make them two different menusets. If we don't, opening any popup above and hovering our menu here
   2683        // would open it. This is because once a menu is active, we allow to switch to a sibling menu by just hovering on it, which is the desired behavior for regular menus.
   2684        ImGui::PushID("foo");
   2685        ImGui::MenuItem("Menu item", "CTRL+M");
   2686        if (ImGui::BeginMenu("Menu inside a regular window"))
   2687        {
   2688            ShowExampleMenuFile();
   2689            ImGui::EndMenu();
   2690        }
   2691        ImGui::PopID();
   2692        ImGui::Separator();
   2693        ImGui::TreePop();
   2694    }
   2695}
   2696
   2697static void ShowDemoWindowColumns()
   2698{
   2699    if (!ImGui::CollapsingHeader("Columns"))
   2700        return;
   2701
   2702    ImGui::PushID("Columns");
   2703
   2704    static bool disable_indent = false;
   2705    ImGui::Checkbox("Disable tree indentation", &disable_indent);
   2706    ImGui::SameLine();
   2707    HelpMarker("Disable the indenting of tree nodes so demo columns can use the full window width.");
   2708    if (disable_indent)
   2709        ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, 0.0f);
   2710
   2711    // Basic columns
   2712    if (ImGui::TreeNode("Basic"))
   2713    {
   2714        ImGui::Text("Without border:");
   2715        ImGui::Columns(3, "mycolumns3", false);  // 3-ways, no border
   2716        ImGui::Separator();
   2717        for (int n = 0; n < 14; n++)
   2718        {
   2719            char label[32];
   2720            sprintf(label, "Item %d", n);
   2721            if (ImGui::Selectable(label)) {}
   2722            //if (ImGui::Button(label, ImVec2(-FLT_MIN,0.0f))) {}
   2723            ImGui::NextColumn();
   2724        }
   2725        ImGui::Columns(1);
   2726        ImGui::Separator();
   2727
   2728        ImGui::Text("With border:");
   2729        ImGui::Columns(4, "mycolumns"); // 4-ways, with border
   2730        ImGui::Separator();
   2731        ImGui::Text("ID"); ImGui::NextColumn();
   2732        ImGui::Text("Name"); ImGui::NextColumn();
   2733        ImGui::Text("Path"); ImGui::NextColumn();
   2734        ImGui::Text("Hovered"); ImGui::NextColumn();
   2735        ImGui::Separator();
   2736        const char* names[3] = { "One", "Two", "Three" };
   2737        const char* paths[3] = { "/path/one", "/path/two", "/path/three" };
   2738        static int selected = -1;
   2739        for (int i = 0; i < 3; i++)
   2740        {
   2741            char label[32];
   2742            sprintf(label, "%04d", i);
   2743            if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns))
   2744                selected = i;
   2745            bool hovered = ImGui::IsItemHovered();
   2746            ImGui::NextColumn();
   2747            ImGui::Text(names[i]); ImGui::NextColumn();
   2748            ImGui::Text(paths[i]); ImGui::NextColumn();
   2749            ImGui::Text("%d", hovered); ImGui::NextColumn();
   2750        }
   2751        ImGui::Columns(1);
   2752        ImGui::Separator();
   2753        ImGui::TreePop();
   2754    }
   2755
   2756    if (ImGui::TreeNode("Borders"))
   2757    {
   2758        // NB: Future columns API should allow automatic horizontal borders.
   2759        static bool h_borders = true;
   2760        static bool v_borders = true;
   2761        static int columns_count = 4;
   2762        const int lines_count = 3;
   2763        ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
   2764        ImGui::DragInt("##columns_count", &columns_count, 0.1f, 2, 10, "%d columns");
   2765        if (columns_count < 2)
   2766            columns_count = 2;
   2767        ImGui::SameLine();
   2768        ImGui::Checkbox("horizontal", &h_borders);
   2769        ImGui::SameLine();
   2770        ImGui::Checkbox("vertical", &v_borders);
   2771        ImGui::Columns(columns_count, NULL, v_borders);
   2772        for (int i = 0; i < columns_count * lines_count; i++)
   2773        {
   2774            if (h_borders && ImGui::GetColumnIndex() == 0)
   2775                ImGui::Separator();
   2776            ImGui::Text("%c%c%c", 'a' + i, 'a' + i, 'a' + i);
   2777            ImGui::Text("Width %.2f", ImGui::GetColumnWidth());
   2778            ImGui::Text("Avail %.2f", ImGui::GetContentRegionAvail().x);
   2779            ImGui::Text("Offset %.2f", ImGui::GetColumnOffset());
   2780            ImGui::Text("Long text that is likely to clip");
   2781            ImGui::Button("Button", ImVec2(-FLT_MIN, 0.0f));
   2782            ImGui::NextColumn();
   2783        }
   2784        ImGui::Columns(1);
   2785        if (h_borders)
   2786            ImGui::Separator();
   2787        ImGui::TreePop();
   2788    }
   2789
   2790    // Create multiple items in a same cell before switching to next column
   2791    if (ImGui::TreeNode("Mixed items"))
   2792    {
   2793        ImGui::Columns(3, "mixed");
   2794        ImGui::Separator();
   2795
   2796        ImGui::Text("Hello");
   2797        ImGui::Button("Banana");
   2798        ImGui::NextColumn();
   2799
   2800        ImGui::Text("ImGui");
   2801        ImGui::Button("Apple");
   2802        static float foo = 1.0f;
   2803        ImGui::InputFloat("red", &foo, 0.05f, 0, "%.3f");
   2804        ImGui::Text("An extra line here.");
   2805        ImGui::NextColumn();
   2806
   2807        ImGui::Text("Sailor");
   2808        ImGui::Button("Corniflower");
   2809        static float bar = 1.0f;
   2810        ImGui::InputFloat("blue", &bar, 0.05f, 0, "%.3f");
   2811        ImGui::NextColumn();
   2812
   2813        if (ImGui::CollapsingHeader("Category A")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn();
   2814        if (ImGui::CollapsingHeader("Category B")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn();
   2815        if (ImGui::CollapsingHeader("Category C")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn();
   2816        ImGui::Columns(1);
   2817        ImGui::Separator();
   2818        ImGui::TreePop();
   2819    }
   2820
   2821    // Word wrapping
   2822    if (ImGui::TreeNode("Word-wrapping"))
   2823    {
   2824        ImGui::Columns(2, "word-wrapping");
   2825        ImGui::Separator();
   2826        ImGui::TextWrapped("The quick brown fox jumps over the lazy dog.");
   2827        ImGui::TextWrapped("Hello Left");
   2828        ImGui::NextColumn();
   2829        ImGui::TextWrapped("The quick brown fox jumps over the lazy dog.");
   2830        ImGui::TextWrapped("Hello Right");
   2831        ImGui::Columns(1);
   2832        ImGui::Separator();
   2833        ImGui::TreePop();
   2834    }
   2835
   2836    // Scrolling columns
   2837    /*
   2838    if (ImGui::TreeNode("Vertical Scrolling"))
   2839    {
   2840        ImGui::BeginChild("##header", ImVec2(0, ImGui::GetTextLineHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y));
   2841        ImGui::Columns(3);
   2842        ImGui::Text("ID"); ImGui::NextColumn();
   2843        ImGui::Text("Name"); ImGui::NextColumn();
   2844        ImGui::Text("Path"); ImGui::NextColumn();
   2845        ImGui::Columns(1);
   2846        ImGui::Separator();
   2847        ImGui::EndChild();
   2848        ImGui::BeginChild("##scrollingregion", ImVec2(0, 60));
   2849        ImGui::Columns(3);
   2850        for (int i = 0; i < 10; i++)
   2851        {
   2852            ImGui::Text("%04d", i); ImGui::NextColumn();
   2853            ImGui::Text("Foobar"); ImGui::NextColumn();
   2854            ImGui::Text("/path/foobar/%04d/", i); ImGui::NextColumn();
   2855        }
   2856        ImGui::Columns(1);
   2857        ImGui::EndChild();
   2858        ImGui::TreePop();
   2859    }
   2860    */
   2861
   2862    if (ImGui::TreeNode("Horizontal Scrolling"))
   2863    {
   2864        ImGui::SetNextWindowContentSize(ImVec2(1500.0f, 0.0f));
   2865        ImGui::BeginChild("##ScrollingRegion", ImVec2(0, ImGui::GetFontSize() * 20), false, ImGuiWindowFlags_HorizontalScrollbar);
   2866        ImGui::Columns(10);
   2867        int ITEMS_COUNT = 2000;
   2868        ImGuiListClipper clipper(ITEMS_COUNT);  // Also demonstrate using the clipper for large list
   2869        while (clipper.Step())
   2870        {
   2871            for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
   2872                for (int j = 0; j < 10; j++)
   2873                {
   2874                    ImGui::Text("Line %d Column %d...", i, j);
   2875                    ImGui::NextColumn();
   2876                }
   2877        }
   2878        ImGui::Columns(1);
   2879        ImGui::EndChild();
   2880        ImGui::TreePop();
   2881    }
   2882
   2883    if (ImGui::TreeNode("Tree"))
   2884    {
   2885        ImGui::Columns(2, "tree", true);
   2886        for (int x = 0; x < 3; x++)
   2887        {
   2888            bool open1 = ImGui::TreeNode((void*)(intptr_t)x, "Node%d", x);
   2889            ImGui::NextColumn();
   2890            ImGui::Text("Node contents");
   2891            ImGui::NextColumn();
   2892            if (open1)
   2893            {
   2894                for (int y = 0; y < 3; y++)
   2895                {
   2896                    bool open2 = ImGui::TreeNode((void*)(intptr_t)y, "Node%d.%d", x, y);
   2897                    ImGui::NextColumn();
   2898                    ImGui::Text("Node contents");
   2899                    if (open2)
   2900                    {
   2901                        ImGui::Text("Even more contents");
   2902                        if (ImGui::TreeNode("Tree in column"))
   2903                        {
   2904                            ImGui::Text("The quick brown fox jumps over the lazy dog");
   2905                            ImGui::TreePop();
   2906                        }
   2907                    }
   2908                    ImGui::NextColumn();
   2909                    if (open2)
   2910                        ImGui::TreePop();
   2911                }
   2912                ImGui::TreePop();
   2913            }
   2914        }
   2915        ImGui::Columns(1);
   2916        ImGui::TreePop();
   2917    }
   2918
   2919    if (disable_indent)
   2920        ImGui::PopStyleVar();
   2921    ImGui::PopID();
   2922}
   2923
   2924static void ShowDemoWindowMisc()
   2925{
   2926    if (ImGui::CollapsingHeader("Filtering"))
   2927    {
   2928        // Helper class to easy setup a text filter.
   2929        // You may want to implement a more feature-full filtering scheme in your own application.
   2930        static ImGuiTextFilter filter;
   2931        ImGui::Text("Filter usage:\n"
   2932                    "  \"\"         display all lines\n"
   2933                    "  \"xxx\"      display lines containing \"xxx\"\n"
   2934                    "  \"xxx,yyy\"  display lines containing \"xxx\" or \"yyy\"\n"
   2935                    "  \"-xxx\"     hide lines containing \"xxx\"");
   2936        filter.Draw();
   2937        const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" };
   2938        for (int i = 0; i < IM_ARRAYSIZE(lines); i++)
   2939            if (filter.PassFilter(lines[i]))
   2940                ImGui::BulletText("%s", lines[i]);
   2941    }
   2942
   2943    if (ImGui::CollapsingHeader("Inputs, Navigation & Focus"))
   2944    {
   2945        ImGuiIO& io = ImGui::GetIO();
   2946
   2947        // Display ImGuiIO output flags
   2948        ImGui::Text("WantCaptureMouse: %d", io.WantCaptureMouse);
   2949        ImGui::Text("WantCaptureKeyboard: %d", io.WantCaptureKeyboard);
   2950        ImGui::Text("WantTextInput: %d", io.WantTextInput);
   2951        ImGui::Text("WantSetMousePos: %d", io.WantSetMousePos);
   2952        ImGui::Text("NavActive: %d, NavVisible: %d", io.NavActive, io.NavVisible);
   2953
   2954        // Display Keyboard/Mouse state
   2955        if (ImGui::TreeNode("Keyboard, Mouse & Navigation State"))
   2956        {
   2957            if (ImGui::IsMousePosValid())
   2958                ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y);
   2959            else
   2960                ImGui::Text("Mouse pos: <INVALID>");
   2961            ImGui::Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y);
   2962            ImGui::Text("Mouse down:");     for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseDownDuration[i] >= 0.0f)   { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); }
   2963            ImGui::Text("Mouse clicked:");  for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseClicked(i))          { ImGui::SameLine(); ImGui::Text("b%d", i); }
   2964            ImGui::Text("Mouse dbl-clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); }
   2965            ImGui::Text("Mouse released:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseReleased(i))         { ImGui::SameLine(); ImGui::Text("b%d", i); }
   2966            ImGui::Text("Mouse wheel: %.1f", io.MouseWheel);
   2967
   2968            ImGui::Text("Keys down:");      for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (io.KeysDownDuration[i] >= 0.0f)     { ImGui::SameLine(); ImGui::Text("%d (0x%X) (%.02f secs)", i, i, io.KeysDownDuration[i]); }
   2969            ImGui::Text("Keys pressed:");   for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i))             { ImGui::SameLine(); ImGui::Text("%d (0x%X)", i, i); }
   2970            ImGui::Text("Keys release:");   for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i))            { ImGui::SameLine(); ImGui::Text("%d (0x%X)", i, i); }
   2971            ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : "");
   2972            ImGui::Text("Chars queue:");    for (int i = 0; i < io.InputQueueCharacters.Size; i++) { ImWchar c = io.InputQueueCharacters[i]; ImGui::SameLine();  ImGui::Text("\'%c\' (0x%04X)", (c > ' ' && c <= 255) ? (char)c : '?', c); } // FIXME: We should convert 'c' to UTF-8 here but the functions are not public.
   2973
   2974            ImGui::Text("NavInputs down:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputs[i] > 0.0f)                    { ImGui::SameLine(); ImGui::Text("[%d] %.2f", i, io.NavInputs[i]); }
   2975            ImGui::Text("NavInputs pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputsDownDuration[i] == 0.0f)    { ImGui::SameLine(); ImGui::Text("[%d]", i); }
   2976            ImGui::Text("NavInputs duration:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputsDownDuration[i] >= 0.0f)   { ImGui::SameLine(); ImGui::Text("[%d] %.2f", i, io.NavInputsDownDuration[i]); }
   2977
   2978            ImGui::Button("Hovering me sets the\nkeyboard capture flag");
   2979            if (ImGui::IsItemHovered())
   2980                ImGui::CaptureKeyboardFromApp(true);
   2981            ImGui::SameLine();
   2982            ImGui::Button("Holding me clears the\nthe keyboard capture flag");
   2983            if (ImGui::IsItemActive())
   2984                ImGui::CaptureKeyboardFromApp(false);
   2985
   2986            ImGui::TreePop();
   2987        }
   2988
   2989        if (ImGui::TreeNode("Tabbing"))
   2990        {
   2991            ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields.");
   2992            static char buf[32] = "dummy";
   2993            ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
   2994            ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
   2995            ImGui::InputText("3", buf, IM_ARRAYSIZE(buf));
   2996            ImGui::PushAllowKeyboardFocus(false);
   2997            ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf));
   2998            //ImGui::SameLine(); HelpMarker("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets.");
   2999            ImGui::PopAllowKeyboardFocus();
   3000            ImGui::InputText("5", buf, IM_ARRAYSIZE(buf));
   3001            ImGui::TreePop();
   3002        }
   3003
   3004        if (ImGui::TreeNode("Focus from code"))
   3005        {
   3006            bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine();
   3007            bool focus_2 = ImGui::Button("Focus on 2"); ImGui::SameLine();
   3008            bool focus_3 = ImGui::Button("Focus on 3");
   3009            int has_focus = 0;
   3010            static char buf[128] = "click on a button to set focus";
   3011
   3012            if (focus_1) ImGui::SetKeyboardFocusHere();
   3013            ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
   3014            if (ImGui::IsItemActive()) has_focus = 1;
   3015
   3016            if (focus_2) ImGui::SetKeyboardFocusHere();
   3017            ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
   3018            if (ImGui::IsItemActive()) has_focus = 2;
   3019
   3020            ImGui::PushAllowKeyboardFocus(false);
   3021            if (focus_3) ImGui::SetKeyboardFocusHere();
   3022            ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf));
   3023            if (ImGui::IsItemActive()) has_focus = 3;
   3024            ImGui::PopAllowKeyboardFocus();
   3025
   3026            if (has_focus)
   3027                ImGui::Text("Item with focus: %d", has_focus);
   3028            else
   3029                ImGui::Text("Item with focus: <none>");
   3030
   3031            // Use >= 0 parameter to SetKeyboardFocusHere() to focus an upcoming item
   3032            static float f3[3] = { 0.0f, 0.0f, 0.0f };
   3033            int focus_ahead = -1;
   3034            if (ImGui::Button("Focus on X")) { focus_ahead = 0; } ImGui::SameLine();
   3035            if (ImGui::Button("Focus on Y")) { focus_ahead = 1; } ImGui::SameLine();
   3036            if (ImGui::Button("Focus on Z")) { focus_ahead = 2; }
   3037            if (focus_ahead != -1) ImGui::SetKeyboardFocusHere(focus_ahead);
   3038            ImGui::SliderFloat3("Float3", &f3[0], 0.0f, 1.0f);
   3039
   3040            ImGui::TextWrapped("NB: Cursor & selection are preserved when refocusing last used item in code.");
   3041            ImGui::TreePop();
   3042        }
   3043
   3044        if (ImGui::TreeNode("Dragging"))
   3045        {
   3046            ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget.");
   3047            for (int button = 0; button < 3; button++)
   3048                ImGui::Text("IsMouseDragging(%d):\n  w/ default threshold: %d,\n  w/ zero threshold: %d\n  w/ large threshold: %d",
   3049                    button, ImGui::IsMouseDragging(button), ImGui::IsMouseDragging(button, 0.0f), ImGui::IsMouseDragging(button, 20.0f));
   3050
   3051            ImGui::Button("Drag Me");
   3052            if (ImGui::IsItemActive())
   3053                ImGui::GetForegroundDrawList()->AddLine(io.MouseClickedPos[0], io.MousePos, ImGui::GetColorU32(ImGuiCol_Button), 4.0f); // Draw a line between the button and the mouse cursor
   3054
   3055            // Drag operations gets "unlocked" when the mouse has moved past a certain threshold (the default threshold is stored in io.MouseDragThreshold)
   3056            // You can request a lower or higher threshold using the second parameter of IsMouseDragging() and GetMouseDragDelta()
   3057            ImVec2 value_raw = ImGui::GetMouseDragDelta(0, 0.0f);
   3058            ImVec2 value_with_lock_threshold = ImGui::GetMouseDragDelta(0);
   3059            ImVec2 mouse_delta = io.MouseDelta;
   3060            ImGui::Text("GetMouseDragDelta(0):\n  w/ default threshold: (%.1f, %.1f),\n  w/ zero threshold: (%.1f, %.1f)\nMouseDelta: (%.1f, %.1f)", value_with_lock_threshold.x, value_with_lock_threshold.y, value_raw.x, value_raw.y, mouse_delta.x, mouse_delta.y);
   3061            ImGui::TreePop();
   3062        }
   3063
   3064        if (ImGui::TreeNode("Mouse cursors"))
   3065        {
   3066            const char* mouse_cursors_names[] = { "Arrow", "TextInput", "ResizeAll", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE", "Hand", "NotAllowed" };
   3067            IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_COUNT);
   3068
   3069            ImGui::Text("Current mouse cursor = %d: %s", ImGui::GetMouseCursor(), mouse_cursors_names[ImGui::GetMouseCursor()]);
   3070            ImGui::Text("Hover to see mouse cursors:");
   3071            ImGui::SameLine(); HelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it.");
   3072            for (int i = 0; i < ImGuiMouseCursor_COUNT; i++)
   3073            {
   3074                char label[32];
   3075                sprintf(label, "Mouse cursor %d: %s", i, mouse_cursors_names[i]);
   3076                ImGui::Bullet(); ImGui::Selectable(label, false);
   3077                if (ImGui::IsItemHovered() || ImGui::IsItemFocused())
   3078                    ImGui::SetMouseCursor(i);
   3079            }
   3080            ImGui::TreePop();
   3081        }
   3082    }
   3083}
   3084
   3085//-----------------------------------------------------------------------------
   3086// [SECTION] About Window / ShowAboutWindow()
   3087// Access from Dear ImGui Demo -> Tools -> About
   3088//-----------------------------------------------------------------------------
   3089
   3090void ImGui::ShowAboutWindow(bool* p_open)
   3091{
   3092    if (!ImGui::Begin("About Dear ImGui", p_open, ImGuiWindowFlags_AlwaysAutoResize))
   3093    {
   3094        ImGui::End();
   3095        return;
   3096    }
   3097    ImGui::Text("Dear ImGui %s", ImGui::GetVersion());
   3098    ImGui::Separator();
   3099    ImGui::Text("By Omar Cornut and all Dear ImGui contributors.");
   3100    ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information.");
   3101
   3102    static bool show_config_info = false;
   3103    ImGui::Checkbox("Config/Build Information", &show_config_info);
   3104    if (show_config_info)
   3105    {
   3106        ImGuiIO& io = ImGui::GetIO();
   3107        ImGuiStyle& style = ImGui::GetStyle();
   3108
   3109        bool copy_to_clipboard = ImGui::Button("Copy to clipboard");
   3110        ImGui::BeginChildFrame(ImGui::GetID("cfginfos"), ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 18), ImGuiWindowFlags_NoMove);
   3111        if (copy_to_clipboard)
   3112        {
   3113            ImGui::LogToClipboard();
   3114            ImGui::LogText("```\n"); // Back quotes will make the text appears without formatting when pasting to GitHub
   3115        }
   3116
   3117        ImGui::Text("Dear ImGui %s (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM);
   3118        ImGui::Separator();
   3119        ImGui::Text("sizeof(size_t): %d, sizeof(ImDrawIdx): %d, sizeof(ImDrawVert): %d", (int)sizeof(size_t), (int)sizeof(ImDrawIdx), (int)sizeof(ImDrawVert));
   3120        ImGui::Text("define: __cplusplus=%d", (int)__cplusplus);
   3121#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
   3122        ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_FUNCTIONS");
   3123#endif
   3124#ifdef IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
   3125        ImGui::Text("define: IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS");
   3126#endif
   3127#ifdef IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
   3128        ImGui::Text("define: IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS");
   3129#endif
   3130#ifdef IMGUI_DISABLE_WIN32_FUNCTIONS
   3131        ImGui::Text("define: IMGUI_DISABLE_WIN32_FUNCTIONS");
   3132#endif
   3133#ifdef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
   3134        ImGui::Text("define: IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS");
   3135#endif
   3136#ifdef IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS
   3137        ImGui::Text("define: IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS");
   3138#endif
   3139#ifdef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
   3140        ImGui::Text("define: IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS");
   3141#endif
   3142#ifdef IMGUI_DISABLE_FILE_FUNCTIONS
   3143        ImGui::Text("define: IMGUI_DISABLE_FILE_FUNCTIONS");
   3144#endif
   3145#ifdef IMGUI_DISABLE_DEFAULT_ALLOCATORS
   3146        ImGui::Text("define: IMGUI_DISABLE_DEFAULT_ALLOCATORS");
   3147#endif
   3148#ifdef IMGUI_USE_BGRA_PACKED_COLOR
   3149        ImGui::Text("define: IMGUI_USE_BGRA_PACKED_COLOR");
   3150#endif
   3151#ifdef _WIN32
   3152        ImGui::Text("define: _WIN32");
   3153#endif
   3154#ifdef _WIN64
   3155        ImGui::Text("define: _WIN64");
   3156#endif
   3157#ifdef __linux__
   3158        ImGui::Text("define: __linux__");
   3159#endif
   3160#ifdef __APPLE__
   3161        ImGui::Text("define: __APPLE__");
   3162#endif
   3163#ifdef _MSC_VER
   3164        ImGui::Text("define: _MSC_VER=%d", _MSC_VER);
   3165#endif
   3166#ifdef __MINGW32__
   3167        ImGui::Text("define: __MINGW32__");
   3168#endif
   3169#ifdef __MINGW64__
   3170        ImGui::Text("define: __MINGW64__");
   3171#endif
   3172#ifdef __GNUC__
   3173        ImGui::Text("define: __GNUC__=%d", (int)__GNUC__);
   3174#endif
   3175#ifdef __clang_version__
   3176        ImGui::Text("define: __clang_version__=%s", __clang_version__);
   3177#endif
   3178        ImGui::Separator();
   3179        ImGui::Text("io.BackendPlatformName: %s", io.BackendPlatformName ? io.BackendPlatformName : "NULL");
   3180        ImGui::Text("io.BackendRendererName: %s", io.BackendRendererName ? io.BackendRendererName : "NULL");
   3181        ImGui::Text("io.ConfigFlags: 0x%08X", io.ConfigFlags);
   3182        if (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard)        ImGui::Text(" NavEnableKeyboard");
   3183        if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad)         ImGui::Text(" NavEnableGamepad");
   3184        if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos)     ImGui::Text(" NavEnableSetMousePos");
   3185        if (io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard)     ImGui::Text(" NavNoCaptureKeyboard");
   3186        if (io.ConfigFlags & ImGuiConfigFlags_NoMouse)                  ImGui::Text(" NoMouse");
   3187        if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)      ImGui::Text(" NoMouseCursorChange");
   3188        if (io.MouseDrawCursor)                                         ImGui::Text("io.MouseDrawCursor");
   3189        if (io.ConfigMacOSXBehaviors)                                   ImGui::Text("io.ConfigMacOSXBehaviors");
   3190        if (io.ConfigInputTextCursorBlink)                              ImGui::Text("io.ConfigInputTextCursorBlink");
   3191        if (io.ConfigWindowsResizeFromEdges)                            ImGui::Text("io.ConfigWindowsResizeFromEdges");
   3192        if (io.ConfigWindowsMoveFromTitleBarOnly)                       ImGui::Text("io.ConfigWindowsMoveFromTitleBarOnly");
   3193        if (io.ConfigWindowsMemoryCompactTimer >= 0.0f)                 ImGui::Text("io.ConfigWindowsMemoryCompactTimer = %.1ff", io.ConfigWindowsMemoryCompactTimer);
   3194        ImGui::Text("io.BackendFlags: 0x%08X", io.BackendFlags);
   3195        if (io.BackendFlags & ImGuiBackendFlags_HasGamepad)             ImGui::Text(" HasGamepad");
   3196        if (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors)        ImGui::Text(" HasMouseCursors");
   3197        if (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos)         ImGui::Text(" HasSetMousePos");
   3198        if (io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)   ImGui::Text(" RendererHasVtxOffset");
   3199        ImGui::Separator();
   3200        ImGui::Text("io.Fonts: %d fonts, Flags: 0x%08X, TexSize: %d,%d", io.Fonts->Fonts.Size, io.Fonts->Flags, io.Fonts->TexWidth, io.Fonts->TexHeight);
   3201        ImGui::Text("io.DisplaySize: %.2f,%.2f", io.DisplaySize.x, io.DisplaySize.y);
   3202        ImGui::Text("io.DisplayFramebufferScale: %.2f,%.2f", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
   3203        ImGui::Separator();
   3204        ImGui::Text("style.WindowPadding: %.2f,%.2f", style.WindowPadding.x, style.WindowPadding.y);
   3205        ImGui::Text("style.WindowBorderSize: %.2f", style.WindowBorderSize);
   3206        ImGui::Text("style.FramePadding: %.2f,%.2f", style.FramePadding.x, style.FramePadding.y);
   3207        ImGui::Text("style.FrameRounding: %.2f", style.FrameRounding);
   3208        ImGui::Text("style.FrameBorderSize: %.2f", style.FrameBorderSize);
   3209        ImGui::Text("style.ItemSpacing: %.2f,%.2f", style.ItemSpacing.x, style.ItemSpacing.y);
   3210        ImGui::Text("style.ItemInnerSpacing: %.2f,%.2f", style.ItemInnerSpacing.x, style.ItemInnerSpacing.y);
   3211
   3212        if (copy_to_clipboard)
   3213        {
   3214            ImGui::LogText("\n```\n");
   3215            ImGui::LogFinish();
   3216        }
   3217        ImGui::EndChildFrame();
   3218    }
   3219    ImGui::End();
   3220}
   3221
   3222//-----------------------------------------------------------------------------
   3223// [SECTION] Style Editor / ShowStyleEditor()
   3224//-----------------------------------------------------------------------------
   3225// - ShowStyleSelector()
   3226// - ShowFontSelector()
   3227// - ShowStyleEditor()
   3228//-----------------------------------------------------------------------------
   3229
   3230// Demo helper function to select among default colors. See ShowStyleEditor() for more advanced options.
   3231// Here we use the simplified Combo() api that packs items into a single literal string. Useful for quick combo boxes where the choices are known locally.
   3232bool ImGui::ShowStyleSelector(const char* label)
   3233{
   3234    static int style_idx = -1;
   3235    if (ImGui::Combo(label, &style_idx, "Classic\0Dark\0Light\0"))
   3236    {
   3237        switch (style_idx)
   3238        {
   3239        case 0: ImGui::StyleColorsClassic(); break;
   3240        case 1: ImGui::StyleColorsDark(); break;
   3241        case 2: ImGui::StyleColorsLight(); break;
   3242        }
   3243        return true;
   3244    }
   3245    return false;
   3246}
   3247
   3248// Demo helper function to select among loaded fonts.
   3249// Here we use the regular BeginCombo()/EndCombo() api which is more the more flexible one.
   3250void ImGui::ShowFontSelector(const char* label)
   3251{
   3252    ImGuiIO& io = ImGui::GetIO();
   3253    ImFont* font_current = ImGui::GetFont();
   3254    if (ImGui::BeginCombo(label, font_current->GetDebugName()))
   3255    {
   3256        for (int n = 0; n < io.Fonts->Fonts.Size; n++)
   3257        {
   3258            ImFont* font = io.Fonts->Fonts[n];
   3259            ImGui::PushID((void*)font);
   3260            if (ImGui::Selectable(font->GetDebugName(), font == font_current))
   3261                io.FontDefault = font;
   3262            ImGui::PopID();
   3263        }
   3264        ImGui::EndCombo();
   3265    }
   3266    ImGui::SameLine();
   3267    HelpMarker(
   3268        "- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n"
   3269        "- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n"
   3270        "- Read FAQ and docs/FONTS.txt for more details.\n"
   3271        "- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame().");
   3272}
   3273
   3274void ImGui::ShowStyleEditor(ImGuiStyle* ref)
   3275{
   3276    // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it compares to an internally stored reference)
   3277    ImGuiStyle& style = ImGui::GetStyle();
   3278    static ImGuiStyle ref_saved_style;
   3279
   3280    // Default to using internal storage as reference
   3281    static bool init = true;
   3282    if (init && ref == NULL)
   3283        ref_saved_style = style;
   3284    init = false;
   3285    if (ref == NULL)
   3286        ref = &ref_saved_style;
   3287
   3288    ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f);
   3289
   3290    if (ImGui::ShowStyleSelector("Colors##Selector"))
   3291        ref_saved_style = style;
   3292    ImGui::ShowFontSelector("Fonts##Selector");
   3293
   3294    // Simplified Settings
   3295    if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f"))
   3296        style.GrabRounding = style.FrameRounding; // Make GrabRounding always the same value as FrameRounding
   3297    { bool window_border = (style.WindowBorderSize > 0.0f); if (ImGui::Checkbox("WindowBorder", &window_border)) style.WindowBorderSize = window_border ? 1.0f : 0.0f; }
   3298    ImGui::SameLine();
   3299    { bool frame_border = (style.FrameBorderSize > 0.0f); if (ImGui::Checkbox("FrameBorder", &frame_border)) style.FrameBorderSize = frame_border ? 1.0f : 0.0f; }
   3300    ImGui::SameLine();
   3301    { bool popup_border = (style.PopupBorderSize > 0.0f); if (ImGui::Checkbox("PopupBorder", &popup_border)) style.PopupBorderSize = popup_border ? 1.0f : 0.0f; }
   3302
   3303    // Save/Revert button
   3304    if (ImGui::Button("Save Ref"))
   3305        *ref = ref_saved_style = style;
   3306    ImGui::SameLine();
   3307    if (ImGui::Button("Revert Ref"))
   3308        style = *ref;
   3309    ImGui::SameLine();
   3310    HelpMarker("Save/Revert in local non-persistent storage. Default Colors definition are not affected. Use \"Export\" below to save them somewhere.");
   3311
   3312    ImGui::Separator();
   3313
   3314    if (ImGui::BeginTabBar("##tabs", ImGuiTabBarFlags_None))
   3315    {
   3316        if (ImGui::BeginTabItem("Sizes"))
   3317        {
   3318            ImGui::Text("Main");
   3319            ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f");
   3320            ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f");
   3321            ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f");
   3322            ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f");
   3323            ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f");
   3324            ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f, "%.0f");
   3325            ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f");
   3326            ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f");
   3327            ImGui::Text("Borders");
   3328            ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f, 1.0f, "%.0f");
   3329            ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f");
   3330            ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f");
   3331            ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f");
   3332            ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f");
   3333            ImGui::Text("Rounding");
   3334            ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f, "%.0f");
   3335            ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f, "%.0f");
   3336            ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f");
   3337            ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f, "%.0f");
   3338            ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f");
   3339            ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f");
   3340            ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f");
   3341            ImGui::Text("Alignment");
   3342            ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
   3343            int window_menu_button_position = style.WindowMenuButtonPosition + 1;
   3344            if (ImGui::Combo("WindowMenuButtonPosition", (int*)&window_menu_button_position, "None\0Left\0Right\0"))
   3345                style.WindowMenuButtonPosition = window_menu_button_position - 1;
   3346            ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition, "Left\0Right\0");
   3347            ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content.");
   3348            ImGui::SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content.");
   3349            ImGui::Text("Safe Area Padding"); ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).");
   3350            ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f");
   3351            ImGui::EndTabItem();
   3352        }
   3353
   3354        if (ImGui::BeginTabItem("Colors"))
   3355        {
   3356            static int output_dest = 0;
   3357            static bool output_only_modified = true;
   3358            if (ImGui::Button("Export"))
   3359            {
   3360                if (output_dest == 0)
   3361                    ImGui::LogToClipboard();
   3362                else
   3363                    ImGui::LogToTTY();
   3364                ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE);
   3365                for (int i = 0; i < ImGuiCol_COUNT; i++)
   3366                {
   3367                    const ImVec4& col = style.Colors[i];
   3368                    const char* name = ImGui::GetStyleColorName(i);
   3369                    if (!output_only_modified || memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0)
   3370                        ImGui::LogText("colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 23 - (int)strlen(name), "", col.x, col.y, col.z, col.w);
   3371                }
   3372                ImGui::LogFinish();
   3373            }
   3374            ImGui::SameLine(); ImGui::SetNextItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0");
   3375            ImGui::SameLine(); ImGui::Checkbox("Only Modified Colors", &output_only_modified);
   3376
   3377            static ImGuiTextFilter filter;
   3378            filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
   3379
   3380            static ImGuiColorEditFlags alpha_flags = 0;
   3381            if (ImGui::RadioButton("Opaque", alpha_flags == 0))                                     { alpha_flags = 0; } ImGui::SameLine();
   3382            if (ImGui::RadioButton("Alpha",  alpha_flags == ImGuiColorEditFlags_AlphaPreview))      { alpha_flags = ImGuiColorEditFlags_AlphaPreview; } ImGui::SameLine();
   3383            if (ImGui::RadioButton("Both",   alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf))  { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
   3384            HelpMarker("In the color list:\nLeft-click on colored square to open color picker,\nRight-click to open edit options menu.");
   3385
   3386            ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened);
   3387            ImGui::PushItemWidth(-160);
   3388            for (int i = 0; i < ImGuiCol_COUNT; i++)
   3389            {
   3390                const char* name = ImGui::GetStyleColorName(i);
   3391                if (!filter.PassFilter(name))
   3392                    continue;
   3393                ImGui::PushID(i);
   3394                ImGui::ColorEdit4("##color", (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags);
   3395                if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0)
   3396                {
   3397                    // Tips: in a real user application, you may want to merge and use an icon font into the main font, so instead of "Save"/"Revert" you'd use icons.
   3398                    // Read the FAQ and docs/FONTS.txt about using icon fonts. It's really easy and super convenient!
   3399                    ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i];
   3400                    ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Revert")) style.Colors[i] = ref->Colors[i];
   3401                }
   3402                ImGui::SameLine(0.0f, style.ItemInnerSpacing.x);
   3403                ImGui::TextUnformatted(name);
   3404                ImGui::PopID();
   3405            }
   3406            ImGui::PopItemWidth();
   3407            ImGui::EndChild();
   3408
   3409            ImGui::EndTabItem();
   3410        }
   3411
   3412        if (ImGui::BeginTabItem("Fonts"))
   3413        {
   3414            ImGuiIO& io = ImGui::GetIO();
   3415            ImFontAtlas* atlas = io.Fonts;
   3416            HelpMarker("Read FAQ and docs/FONTS.txt for details on font loading.");
   3417            ImGui::PushItemWidth(120);
   3418            for (int i = 0; i < atlas->Fonts.Size; i++)
   3419            {
   3420                ImFont* font = atlas->Fonts[i];
   3421                ImGui::PushID(font);
   3422                bool font_details_opened = ImGui::TreeNode(font, "Font %d: \"%s\"\n%.2f px, %d glyphs, %d file(s)", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size, font->ConfigDataCount);
   3423                ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) { io.FontDefault = font; }
   3424                if (font_details_opened)
   3425                {
   3426                    ImGui::PushFont(font);
   3427                    ImGui::Text("The quick brown fox jumps over the lazy dog");
   3428                    ImGui::PopFont();
   3429                    ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f");   // Scale only this font
   3430                    ImGui::SameLine(); HelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)");
   3431                    ImGui::InputFloat("Font offset", &font->DisplayOffset.y, 1, 1, "%.0f");
   3432                    ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
   3433                    ImGui::Text("Fallback character: '%c' (U+%04X)", font->FallbackChar, font->FallbackChar);
   3434                    ImGui::Text("Ellipsis character: '%c' (U+%04X)", font->EllipsisChar, font->EllipsisChar);
   3435                    const float surface_sqrt = sqrtf((float)font->MetricsTotalSurface);
   3436                    ImGui::Text("Texture Area: about %d px ~%dx%d px", font->MetricsTotalSurface, (int)surface_sqrt, (int)surface_sqrt);
   3437                    for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
   3438                        if (font->ConfigData)
   3439                            if (const ImFontConfig* cfg = &font->ConfigData[config_i])
   3440                                ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH);
   3441                    if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
   3442                    {
   3443                        // Display all glyphs of the fonts in separate pages of 256 characters
   3444                        for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256)
   3445                        {
   3446                            // Skip ahead if a large bunch of glyphs are not present in the font (test in chunks of 4k)
   3447                            // This is only a small optimization to reduce the number of iterations when IM_UNICODE_MAX_CODEPOINT is large.
   3448                            // (if ImWchar==ImWchar32 we will do at least about 272 queries here)
   3449                            if (!(base & 4095) && font->IsGlyphRangeUnused(base, base + 4095))
   3450                            {
   3451                                base += 4096 - 256;
   3452                                continue;
   3453                            }
   3454
   3455                            int count = 0;
   3456                            for (unsigned int n = 0; n < 256; n++)
   3457                                count += font->FindGlyphNoFallback((ImWchar)(base + n)) ? 1 : 0;
   3458                            if (count > 0 && ImGui::TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base + 255, count, count > 1 ? "glyphs" : "glyph"))
   3459                            {
   3460                                float cell_size = font->FontSize * 1;
   3461                                float cell_spacing = style.ItemSpacing.y;
   3462                                ImVec2 base_pos = ImGui::GetCursorScreenPos();
   3463                                ImDrawList* draw_list = ImGui::GetWindowDrawList();
   3464                                for (unsigned int n = 0; n < 256; n++)
   3465                                {
   3466                                    ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size + cell_spacing), base_pos.y + (n / 16) * (cell_size + cell_spacing));
   3467                                    ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size);
   3468                                    const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base + n));
   3469                                    draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50));
   3470                                    if (glyph)
   3471                                        font->RenderChar(draw_list, cell_size, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base + n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string.
   3472                                    if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2))
   3473                                    {
   3474                                        ImGui::BeginTooltip();
   3475                                        ImGui::Text("Codepoint: U+%04X", base + n);
   3476                                        ImGui::Separator();
   3477                                        ImGui::Text("Visible: %d", glyph->Visible);
   3478                                        ImGui::Text("AdvanceX: %.1f", glyph->AdvanceX);
   3479                                        ImGui::Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1);
   3480                                        ImGui::Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1);
   3481                                        ImGui::EndTooltip();
   3482                                    }
   3483                                }
   3484                                ImGui::Dummy(ImVec2((cell_size + cell_spacing) * 16, (cell_size + cell_spacing) * 16));
   3485                                ImGui::TreePop();
   3486                            }
   3487                        }
   3488                        ImGui::TreePop();
   3489                    }
   3490                    ImGui::TreePop();
   3491                }
   3492                ImGui::PopID();
   3493            }
   3494            if (ImGui::TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight))
   3495            {
   3496                ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
   3497                ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f);
   3498                ImGui::Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0, 0), ImVec2(1, 1), tint_col, border_col);
   3499                ImGui::TreePop();
   3500            }
   3501
   3502            HelpMarker("Those are old settings provided for convenience.\nHowever, the _correct_ way of scaling your UI is currently to reload your font at the designed size, rebuild the font atlas, and call style.ScaleAllSizes() on a reference ImGuiStyle structure.");
   3503            static float window_scale = 1.0f;
   3504            if (ImGui::DragFloat("window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.2f"))   // scale only this window
   3505                ImGui::SetWindowFontScale(window_scale);
   3506            ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, 0.3f, 2.0f, "%.2f");      // scale everything
   3507            ImGui::PopItemWidth();
   3508
   3509            ImGui::EndTabItem();
   3510        }
   3511
   3512        if (ImGui::BeginTabItem("Rendering"))
   3513        {
   3514            ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well.");
   3515            ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
   3516            ImGui::PushItemWidth(100);
   3517            ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f");
   3518            if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f;
   3519            ImGui::DragFloat("Circle segment Max Error", &style.CircleSegmentMaxError, 0.01f, 0.10f, 10.0f, "%.2f");
   3520            ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
   3521            ImGui::PopItemWidth();
   3522
   3523            ImGui::EndTabItem();
   3524        }
   3525
   3526        ImGui::EndTabBar();
   3527    }
   3528
   3529    ImGui::PopItemWidth();
   3530}
   3531
   3532//-----------------------------------------------------------------------------
   3533// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar()
   3534//-----------------------------------------------------------------------------
   3535// - ShowExampleAppMainMenuBar()
   3536// - ShowExampleMenuFile()
   3537//-----------------------------------------------------------------------------
   3538
   3539// Demonstrate creating a "main" fullscreen menu bar and populating it.
   3540// Note the difference between BeginMainMenuBar() and BeginMenuBar():
   3541// - BeginMenuBar() = menu-bar inside current window we Begin()-ed into (the window needs the ImGuiWindowFlags_MenuBar flag)
   3542// - BeginMainMenuBar() = helper to create menu-bar-sized window at the top of the main viewport + call BeginMenuBar() into it.
   3543static void ShowExampleAppMainMenuBar()
   3544{
   3545    if (ImGui::BeginMainMenuBar())
   3546    {
   3547        if (ImGui::BeginMenu("File"))
   3548        {
   3549            ShowExampleMenuFile();
   3550            ImGui::EndMenu();
   3551        }
   3552        if (ImGui::BeginMenu("Edit"))
   3553        {
   3554            if (ImGui::MenuItem("Undo", "CTRL+Z")) {}
   3555            if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {}  // Disabled item
   3556            ImGui::Separator();
   3557            if (ImGui::MenuItem("Cut", "CTRL+X")) {}
   3558            if (ImGui::MenuItem("Copy", "CTRL+C")) {}
   3559            if (ImGui::MenuItem("Paste", "CTRL+V")) {}
   3560            ImGui::EndMenu();
   3561        }
   3562        ImGui::EndMainMenuBar();
   3563    }
   3564}
   3565
   3566// Note that shortcuts are currently provided for display only (future version will add flags to BeginMenu to process shortcuts)
   3567static void ShowExampleMenuFile()
   3568{
   3569    ImGui::MenuItem("(dummy menu)", NULL, false, false);
   3570    if (ImGui::MenuItem("New")) {}
   3571    if (ImGui::MenuItem("Open", "Ctrl+O")) {}
   3572    if (ImGui::BeginMenu("Open Recent"))
   3573    {
   3574        ImGui::MenuItem("fish_hat.c");
   3575        ImGui::MenuItem("fish_hat.inl");
   3576        ImGui::MenuItem("fish_hat.h");
   3577        if (ImGui::BeginMenu("More.."))
   3578        {
   3579            ImGui::MenuItem("Hello");
   3580            ImGui::MenuItem("Sailor");
   3581            if (ImGui::BeginMenu("Recurse.."))
   3582            {
   3583                ShowExampleMenuFile();
   3584                ImGui::EndMenu();
   3585            }
   3586            ImGui::EndMenu();
   3587        }
   3588        ImGui::EndMenu();
   3589    }
   3590    if (ImGui::MenuItem("Save", "Ctrl+S")) {}
   3591    if (ImGui::MenuItem("Save As..")) {}
   3592
   3593    ImGui::Separator();
   3594    if (ImGui::BeginMenu("Options"))
   3595    {
   3596        static bool enabled = true;
   3597        ImGui::MenuItem("Enabled", "", &enabled);
   3598        ImGui::BeginChild("child", ImVec2(0, 60), true);
   3599        for (int i = 0; i < 10; i++)
   3600            ImGui::Text("Scrolling Text %d", i);
   3601        ImGui::EndChild();
   3602        static float f = 0.5f;
   3603        static int n = 0;
   3604        ImGui::SliderFloat("Value", &f, 0.0f, 1.0f);
   3605        ImGui::InputFloat("Input", &f, 0.1f);
   3606        ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0");
   3607        ImGui::EndMenu();
   3608    }
   3609
   3610    if (ImGui::BeginMenu("Colors"))
   3611    {
   3612        float sz = ImGui::GetTextLineHeight();
   3613        for (int i = 0; i < ImGuiCol_COUNT; i++)
   3614        {
   3615            const char* name = ImGui::GetStyleColorName((ImGuiCol)i);
   3616            ImVec2 p = ImGui::GetCursorScreenPos();
   3617            ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x+sz, p.y+sz), ImGui::GetColorU32((ImGuiCol)i));
   3618            ImGui::Dummy(ImVec2(sz, sz));
   3619            ImGui::SameLine();
   3620            ImGui::MenuItem(name);
   3621        }
   3622        ImGui::EndMenu();
   3623    }
   3624
   3625    // Here we demonstrate appending again to the "Options" menu (which we already created above)
   3626    // Of course in this demo it is a little bit silly that this function calls BeginMenu("Options") twice.
   3627    // In a real code-base using it would make senses to use this feature from very different code locations.
   3628    if (ImGui::BeginMenu("Options")) // <-- Append!
   3629    {
   3630        static bool b = true;
   3631        ImGui::Checkbox("SomeOption", &b);
   3632        ImGui::EndMenu();
   3633    }
   3634
   3635    if (ImGui::BeginMenu("Disabled", false)) // Disabled
   3636    {
   3637        IM_ASSERT(0);
   3638    }
   3639    if (ImGui::MenuItem("Checked", NULL, true)) {}
   3640    if (ImGui::MenuItem("Quit", "Alt+F4")) {}
   3641}
   3642
   3643//-----------------------------------------------------------------------------
   3644// [SECTION] Example App: Debug Console / ShowExampleAppConsole()
   3645//-----------------------------------------------------------------------------
   3646
   3647// Demonstrate creating a simple console window, with scrolling, filtering, completion and history.
   3648// For the console example, here we are using a more C++ like approach of declaring a class to hold the data and the functions.
   3649struct ExampleAppConsole
   3650{
   3651    char                  InputBuf[256];
   3652    ImVector<char*>       Items;
   3653    ImVector<const char*> Commands;
   3654    ImVector<char*>       History;
   3655    int                   HistoryPos;    // -1: new line, 0..History.Size-1 browsing history.
   3656    ImGuiTextFilter       Filter;
   3657    bool                  AutoScroll;
   3658    bool                  ScrollToBottom;
   3659
   3660    ExampleAppConsole()
   3661    {
   3662        ClearLog();
   3663        memset(InputBuf, 0, sizeof(InputBuf));
   3664        HistoryPos = -1;
   3665        Commands.push_back("HELP");
   3666        Commands.push_back("HISTORY");
   3667        Commands.push_back("CLEAR");
   3668        Commands.push_back("CLASSIFY");  // "classify" is only here to provide an example of "C"+[tab] completing to "CL" and displaying matches.
   3669        AutoScroll = true;
   3670        ScrollToBottom = false;
   3671        AddLog("Welcome to Dear ImGui!");
   3672    }
   3673    ~ExampleAppConsole()
   3674    {
   3675        ClearLog();
   3676        for (int i = 0; i < History.Size; i++)
   3677            free(History[i]);
   3678    }
   3679
   3680    // Portable helpers
   3681    static int   Stricmp(const char* str1, const char* str2)         { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; }
   3682    static int   Strnicmp(const char* str1, const char* str2, int n) { int d = 0; while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; n--; } return d; }
   3683    static char* Strdup(const char *str)                             { size_t len = strlen(str) + 1; void* buf = malloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)str, len); }
   3684    static void  Strtrim(char* str)                                  { char* str_end = str + strlen(str); while (str_end > str && str_end[-1] == ' ') str_end--; *str_end = 0; }
   3685
   3686    void    ClearLog()
   3687    {
   3688        for (int i = 0; i < Items.Size; i++)
   3689            free(Items[i]);
   3690        Items.clear();
   3691    }
   3692
   3693    void    AddLog(const char* fmt, ...) IM_FMTARGS(2)
   3694    {
   3695        // FIXME-OPT
   3696        char buf[1024];
   3697        va_list args;
   3698        va_start(args, fmt);
   3699        vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
   3700        buf[IM_ARRAYSIZE(buf)-1] = 0;
   3701        va_end(args);
   3702        Items.push_back(Strdup(buf));
   3703    }
   3704
   3705    void    Draw(const char* title, bool* p_open)
   3706    {
   3707        ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiCond_FirstUseEver);
   3708        if (!ImGui::Begin(title, p_open))
   3709        {
   3710            ImGui::End();
   3711            return;
   3712        }
   3713
   3714        // As a specific feature guaranteed by the library, after calling Begin() the last Item represent the title bar. So e.g. IsItemHovered() will return true when hovering the title bar.
   3715        // Here we create a context menu only available from the title bar.
   3716        if (ImGui::BeginPopupContextItem())
   3717        {
   3718            if (ImGui::MenuItem("Close Console"))
   3719                *p_open = false;
   3720            ImGui::EndPopup();
   3721        }
   3722
   3723        ImGui::TextWrapped("This example implements a console with basic coloring, completion and history. A more elaborate implementation may want to store entries along with extra data such as timestamp, emitter, etc.");
   3724        ImGui::TextWrapped("Enter 'HELP' for help, press TAB to use text completion.");
   3725
   3726        // TODO: display items starting from the bottom
   3727
   3728        if (ImGui::SmallButton("Add Dummy Text"))  { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
   3729        if (ImGui::SmallButton("Add Dummy Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine();
   3730        if (ImGui::SmallButton("Clear")) { ClearLog(); } ImGui::SameLine();
   3731        bool copy_to_clipboard = ImGui::SmallButton("Copy");
   3732        //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); }
   3733
   3734        ImGui::Separator();
   3735
   3736        // Options menu
   3737        if (ImGui::BeginPopup("Options"))
   3738        {
   3739            ImGui::Checkbox("Auto-scroll", &AutoScroll);
   3740            ImGui::EndPopup();
   3741        }
   3742
   3743        // Options, Filter
   3744        if (ImGui::Button("Options"))
   3745            ImGui::OpenPopup("Options");
   3746        ImGui::SameLine();
   3747        Filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180);
   3748        ImGui::Separator();
   3749
   3750        const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); // 1 separator, 1 input text
   3751        ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), false, ImGuiWindowFlags_HorizontalScrollbar); // Leave room for 1 separator + 1 InputText
   3752        if (ImGui::BeginPopupContextWindow())
   3753        {
   3754            if (ImGui::Selectable("Clear")) ClearLog();
   3755            ImGui::EndPopup();
   3756        }
   3757
   3758        // Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end());
   3759        // NB- if you have thousands of entries this approach may be too inefficient and may require user-side clipping to only process visible items.
   3760        // You can seek and display only the lines that are visible using the ImGuiListClipper helper, if your elements are evenly spaced and you have cheap random access to the elements.
   3761        // To use the clipper we could replace the 'for (int i = 0; i < Items.Size; i++)' loop with:
   3762        //     ImGuiListClipper clipper(Items.Size);
   3763        //     while (clipper.Step())
   3764        //         for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
   3765        // However, note that you can not use this code as is if a filter is active because it breaks the 'cheap random-access' property. We would need random-access on the post-filtered list.
   3766        // A typical application wanting coarse clipping and filtering may want to pre-compute an array of indices that passed the filtering test, recomputing this array when user changes the filter,
   3767        // and appending newly elements as they are inserted. This is left as a task to the user until we can manage to improve this example code!
   3768        // If your items are of variable size you may want to implement code similar to what ImGuiListClipper does. Or split your data into fixed height items to allow random-seeking into your list.
   3769        ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing
   3770        if (copy_to_clipboard)
   3771            ImGui::LogToClipboard();
   3772        for (int i = 0; i < Items.Size; i++)
   3773        {
   3774            const char* item = Items[i];
   3775            if (!Filter.PassFilter(item))
   3776                continue;
   3777
   3778            // Normally you would store more information in your item (e.g. make Items[] an array of structure, store color/type etc.)
   3779            bool pop_color = false;
   3780            if (strstr(item, "[error]"))            { ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.4f, 0.4f, 1.0f)); pop_color = true; }
   3781            else if (strncmp(item, "# ", 2) == 0)   { ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.8f, 0.6f, 1.0f)); pop_color = true; }
   3782            ImGui::TextUnformatted(item);
   3783            if (pop_color)
   3784                ImGui::PopStyleColor();
   3785        }
   3786        if (copy_to_clipboard)
   3787            ImGui::LogFinish();
   3788
   3789        if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
   3790            ImGui::SetScrollHereY(1.0f);
   3791        ScrollToBottom = false;
   3792
   3793        ImGui::PopStyleVar();
   3794        ImGui::EndChild();
   3795        ImGui::Separator();
   3796
   3797        // Command-line
   3798        bool reclaim_focus = false;
   3799        if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this))
   3800        {
   3801            char* s = InputBuf;
   3802            Strtrim(s);
   3803            if (s[0])
   3804                ExecCommand(s);
   3805            strcpy(s, "");
   3806            reclaim_focus = true;
   3807        }
   3808
   3809        // Auto-focus on window apparition
   3810        ImGui::SetItemDefaultFocus();
   3811        if (reclaim_focus)
   3812            ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget
   3813
   3814        ImGui::End();
   3815    }
   3816
   3817    void    ExecCommand(const char* command_line)
   3818    {
   3819        AddLog("# %s\n", command_line);
   3820
   3821        // Insert into history. First find match and delete it so it can be pushed to the back. This isn't trying to be smart or optimal.
   3822        HistoryPos = -1;
   3823        for (int i = History.Size-1; i >= 0; i--)
   3824            if (Stricmp(History[i], command_line) == 0)
   3825            {
   3826                free(History[i]);
   3827                History.erase(History.begin() + i);
   3828                break;
   3829            }
   3830        History.push_back(Strdup(command_line));
   3831
   3832        // Process command
   3833        if (Stricmp(command_line, "CLEAR") == 0)
   3834        {
   3835            ClearLog();
   3836        }
   3837        else if (Stricmp(command_line, "HELP") == 0)
   3838        {
   3839            AddLog("Commands:");
   3840            for (int i = 0; i < Commands.Size; i++)
   3841                AddLog("- %s", Commands[i]);
   3842        }
   3843        else if (Stricmp(command_line, "HISTORY") == 0)
   3844        {
   3845            int first = History.Size - 10;
   3846            for (int i = first > 0 ? first : 0; i < History.Size; i++)
   3847                AddLog("%3d: %s\n", i, History[i]);
   3848        }
   3849        else
   3850        {
   3851            AddLog("Unknown command: '%s'\n", command_line);
   3852        }
   3853
   3854        // On commad input, we scroll to bottom even if AutoScroll==false
   3855        ScrollToBottom = true;
   3856    }
   3857
   3858    static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) // In C++11 you are better off using lambdas for this sort of forwarding callbacks
   3859    {
   3860        ExampleAppConsole* console = (ExampleAppConsole*)data->UserData;
   3861        return console->TextEditCallback(data);
   3862    }
   3863
   3864    int     TextEditCallback(ImGuiInputTextCallbackData* data)
   3865    {
   3866        //AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd);
   3867        switch (data->EventFlag)
   3868        {
   3869        case ImGuiInputTextFlags_CallbackCompletion:
   3870            {
   3871                // Example of TEXT COMPLETION
   3872
   3873                // Locate beginning of current word
   3874                const char* word_end = data->Buf + data->CursorPos;
   3875                const char* word_start = word_end;
   3876                while (word_start > data->Buf)
   3877                {
   3878                    const char c = word_start[-1];
   3879                    if (c == ' ' || c == '\t' || c == ',' || c == ';')
   3880                        break;
   3881                    word_start--;
   3882                }
   3883
   3884                // Build a list of candidates
   3885                ImVector<const char*> candidates;
   3886                for (int i = 0; i < Commands.Size; i++)
   3887                    if (Strnicmp(Commands[i], word_start, (int)(word_end-word_start)) == 0)
   3888                        candidates.push_back(Commands[i]);
   3889
   3890                if (candidates.Size == 0)
   3891                {
   3892                    // No match
   3893                    AddLog("No match for \"%.*s\"!\n", (int)(word_end-word_start), word_start);
   3894                }
   3895                else if (candidates.Size == 1)
   3896                {
   3897                    // Single match. Delete the beginning of the word and replace it entirely so we've got nice casing
   3898                    data->DeleteChars((int)(word_start-data->Buf), (int)(word_end-word_start));
   3899                    data->InsertChars(data->CursorPos, candidates[0]);
   3900                    data->InsertChars(data->CursorPos, " ");
   3901                }
   3902                else
   3903                {
   3904                    // Multiple matches. Complete as much as we can, so inputing "C" will complete to "CL" and display "CLEAR" and "CLASSIFY"
   3905                    int match_len = (int)(word_end - word_start);
   3906                    for (;;)
   3907                    {
   3908                        int c = 0;
   3909                        bool all_candidates_matches = true;
   3910                        for (int i = 0; i < candidates.Size && all_candidates_matches; i++)
   3911                            if (i == 0)
   3912                                c = toupper(candidates[i][match_len]);
   3913                            else if (c == 0 || c != toupper(candidates[i][match_len]))
   3914                                all_candidates_matches = false;
   3915                        if (!all_candidates_matches)
   3916                            break;
   3917                        match_len++;
   3918                    }
   3919
   3920                    if (match_len > 0)
   3921                    {
   3922                        data->DeleteChars((int)(word_start - data->Buf), (int)(word_end-word_start));
   3923                        data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len);
   3924                    }
   3925
   3926                    // List matches
   3927                    AddLog("Possible matches:\n");
   3928                    for (int i = 0; i < candidates.Size; i++)
   3929                        AddLog("- %s\n", candidates[i]);
   3930                }
   3931
   3932                break;
   3933            }
   3934        case ImGuiInputTextFlags_CallbackHistory:
   3935            {
   3936                // Example of HISTORY
   3937                const int prev_history_pos = HistoryPos;
   3938                if (data->EventKey == ImGuiKey_UpArrow)
   3939                {
   3940                    if (HistoryPos == -1)
   3941                        HistoryPos = History.Size - 1;
   3942                    else if (HistoryPos > 0)
   3943                        HistoryPos--;
   3944                }
   3945                else if (data->EventKey == ImGuiKey_DownArrow)
   3946                {
   3947                    if (HistoryPos != -1)
   3948                        if (++HistoryPos >= History.Size)
   3949                            HistoryPos = -1;
   3950                }
   3951
   3952                // A better implementation would preserve the data on the current input line along with cursor position.
   3953                if (prev_history_pos != HistoryPos)
   3954                {
   3955                    const char* history_str = (HistoryPos >= 0) ? History[HistoryPos] : "";
   3956                    data->DeleteChars(0, data->BufTextLen);
   3957                    data->InsertChars(0, history_str);
   3958                }
   3959            }
   3960        }
   3961        return 0;
   3962    }
   3963};
   3964
   3965static void ShowExampleAppConsole(bool* p_open)
   3966{
   3967    static ExampleAppConsole console;
   3968    console.Draw("Example: Console", p_open);
   3969}
   3970
   3971//-----------------------------------------------------------------------------
   3972// [SECTION] Example App: Debug Log / ShowExampleAppLog()
   3973//-----------------------------------------------------------------------------
   3974
   3975// Usage:
   3976//  static ExampleAppLog my_log;
   3977//  my_log.AddLog("Hello %d world\n", 123);
   3978//  my_log.Draw("title");
   3979struct ExampleAppLog
   3980{
   3981    ImGuiTextBuffer     Buf;
   3982    ImGuiTextFilter     Filter;
   3983    ImVector<int>       LineOffsets;        // Index to lines offset. We maintain this with AddLog() calls, allowing us to have a random access on lines
   3984    bool                AutoScroll;     // Keep scrolling if already at the bottom
   3985
   3986    ExampleAppLog()
   3987    {
   3988        AutoScroll = true;
   3989        Clear();
   3990    }
   3991
   3992    void    Clear()
   3993    {
   3994        Buf.clear();
   3995        LineOffsets.clear();
   3996        LineOffsets.push_back(0);
   3997    }
   3998
   3999    void    AddLog(const char* fmt, ...) IM_FMTARGS(2)
   4000    {
   4001        int old_size = Buf.size();
   4002        va_list args;
   4003        va_start(args, fmt);
   4004        Buf.appendfv(fmt, args);
   4005        va_end(args);
   4006        for (int new_size = Buf.size(); old_size < new_size; old_size++)
   4007            if (Buf[old_size] == '\n')
   4008                LineOffsets.push_back(old_size + 1);
   4009    }
   4010
   4011    void    Draw(const char* title, bool* p_open = NULL)
   4012    {
   4013        if (!ImGui::Begin(title, p_open))
   4014        {
   4015            ImGui::End();
   4016            return;
   4017        }
   4018
   4019        // Options menu
   4020        if (ImGui::BeginPopup("Options"))
   4021        {
   4022            ImGui::Checkbox("Auto-scroll", &AutoScroll);
   4023            ImGui::EndPopup();
   4024        }
   4025
   4026        // Main window
   4027        if (ImGui::Button("Options"))
   4028            ImGui::OpenPopup("Options");
   4029        ImGui::SameLine();
   4030        bool clear = ImGui::Button("Clear");
   4031        ImGui::SameLine();
   4032        bool copy = ImGui::Button("Copy");
   4033        ImGui::SameLine();
   4034        Filter.Draw("Filter", -100.0f);
   4035
   4036        ImGui::Separator();
   4037        ImGui::BeginChild("scrolling", ImVec2(0,0), false, ImGuiWindowFlags_HorizontalScrollbar);
   4038
   4039        if (clear)
   4040            Clear();
   4041        if (copy)
   4042            ImGui::LogToClipboard();
   4043
   4044        ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
   4045        const char* buf = Buf.begin();
   4046        const char* buf_end = Buf.end();
   4047        if (Filter.IsActive())
   4048        {
   4049            // In this example we don't use the clipper when Filter is enabled.
   4050            // This is because we don't have a random access on the result on our filter.
   4051            // A real application processing logs with ten of thousands of entries may want to store the result of search/filter.
   4052            // especially if the filtering function is not trivial (e.g. reg-exp).
   4053            for (int line_no = 0; line_no < LineOffsets.Size; line_no++)
   4054            {
   4055                const char* line_start = buf + LineOffsets[line_no];
   4056                const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end;
   4057                if (Filter.PassFilter(line_start, line_end))
   4058                    ImGui::TextUnformatted(line_start, line_end);
   4059            }
   4060        }
   4061        else
   4062        {
   4063            // The simplest and easy way to display the entire buffer:
   4064            //   ImGui::TextUnformatted(buf_begin, buf_end);
   4065            // And it'll just work. TextUnformatted() has specialization for large blob of text and will fast-forward to skip non-visible lines.
   4066            // Here we instead demonstrate using the clipper to only process lines that are within the visible area.
   4067            // If you have tens of thousands of items and their processing cost is non-negligible, coarse clipping them on your side is recommended.
   4068            // Using ImGuiListClipper requires A) random access into your data, and B) items all being the  same height,
   4069            // both of which we can handle since we an array pointing to the beginning of each line of text.
   4070            // When using the filter (in the block of code above) we don't have random access into the data to display anymore, which is why we don't use the clipper.
   4071            // Storing or skimming through the search result would make it possible (and would be recommended if you want to search through tens of thousands of entries)
   4072            ImGuiListClipper clipper;
   4073            clipper.Begin(LineOffsets.Size);
   4074            while (clipper.Step())
   4075            {
   4076                for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++)
   4077                {
   4078                    const char* line_start = buf + LineOffsets[line_no];
   4079                    const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end;
   4080                    ImGui::TextUnformatted(line_start, line_end);
   4081                }
   4082            }
   4083            clipper.End();
   4084        }
   4085        ImGui::PopStyleVar();
   4086
   4087        if (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
   4088            ImGui::SetScrollHereY(1.0f);
   4089
   4090        ImGui::EndChild();
   4091        ImGui::End();
   4092    }
   4093};
   4094
   4095// Demonstrate creating a simple log window with basic filtering.
   4096static void ShowExampleAppLog(bool* p_open)
   4097{
   4098    static ExampleAppLog log;
   4099
   4100    // For the demo: add a debug button _BEFORE_ the normal log window contents
   4101    // We take advantage of a rarely used feature: multiple calls to Begin()/End() are appending to the _same_ window.
   4102    // Most of the contents of the window will be added by the log.Draw() call.
   4103    ImGui::SetNextWindowSize(ImVec2(500, 400), ImGuiCond_FirstUseEver);
   4104    ImGui::Begin("Example: Log", p_open);
   4105    if (ImGui::SmallButton("[Debug] Add 5 entries"))
   4106    {
   4107        static int counter = 0;
   4108        for (int n = 0; n < 5; n++)
   4109        {
   4110            const char* categories[3] = { "info", "warn", "error" };
   4111            const char* words[] = { "Bumfuzzled", "Cattywampus", "Snickersnee", "Abibliophobia", "Absquatulate", "Nincompoop", "Pauciloquent" };
   4112            log.AddLog("[%05d] [%s] Hello, current time is %.1f, here's a word: '%s'\n",
   4113                ImGui::GetFrameCount(), categories[counter % IM_ARRAYSIZE(categories)], ImGui::GetTime(), words[counter % IM_ARRAYSIZE(words)]);
   4114            counter++;
   4115        }
   4116    }
   4117    ImGui::End();
   4118
   4119    // Actually call in the regular Log helper (which will Begin() into the same window as we just did)
   4120    log.Draw("Example: Log", p_open);
   4121}
   4122
   4123//-----------------------------------------------------------------------------
   4124// [SECTION] Example App: Simple Layout / ShowExampleAppLayout()
   4125//-----------------------------------------------------------------------------
   4126
   4127// Demonstrate create a window with multiple child windows.
   4128static void ShowExampleAppLayout(bool* p_open)
   4129{
   4130    ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiCond_FirstUseEver);
   4131    if (ImGui::Begin("Example: Simple layout", p_open, ImGuiWindowFlags_MenuBar))
   4132    {
   4133        if (ImGui::BeginMenuBar())
   4134        {
   4135            if (ImGui::BeginMenu("File"))
   4136            {
   4137                if (ImGui::MenuItem("Close")) *p_open = false;
   4138                ImGui::EndMenu();
   4139            }
   4140            ImGui::EndMenuBar();
   4141        }
   4142
   4143        // left
   4144        static int selected = 0;
   4145        ImGui::BeginChild("left pane", ImVec2(150, 0), true);
   4146        for (int i = 0; i < 100; i++)
   4147        {
   4148            char label[128];
   4149            sprintf(label, "MyObject %d", i);
   4150            if (ImGui::Selectable(label, selected == i))
   4151                selected = i;
   4152        }
   4153        ImGui::EndChild();
   4154        ImGui::SameLine();
   4155
   4156        // right
   4157        ImGui::BeginGroup();
   4158            ImGui::BeginChild("item view", ImVec2(0, -ImGui::GetFrameHeightWithSpacing())); // Leave room for 1 line below us
   4159                ImGui::Text("MyObject: %d", selected);
   4160                ImGui::Separator();
   4161                if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None))
   4162                {
   4163                    if (ImGui::BeginTabItem("Description"))
   4164                    {
   4165                        ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ");
   4166                        ImGui::EndTabItem();
   4167                    }
   4168                    if (ImGui::BeginTabItem("Details"))
   4169                    {
   4170                        ImGui::Text("ID: 0123456789");
   4171                        ImGui::EndTabItem();
   4172                    }
   4173                    ImGui::EndTabBar();
   4174                }
   4175            ImGui::EndChild();
   4176            if (ImGui::Button("Revert")) {}
   4177            ImGui::SameLine();
   4178            if (ImGui::Button("Save")) {}
   4179        ImGui::EndGroup();
   4180    }
   4181    ImGui::End();
   4182}
   4183
   4184//-----------------------------------------------------------------------------
   4185// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor()
   4186//-----------------------------------------------------------------------------
   4187
   4188// Demonstrate create a simple property editor.
   4189static void ShowExampleAppPropertyEditor(bool* p_open)
   4190{
   4191    ImGui::SetNextWindowSize(ImVec2(430,450), ImGuiCond_FirstUseEver);
   4192    if (!ImGui::Begin("Example: Property editor", p_open))
   4193    {
   4194        ImGui::End();
   4195        return;
   4196    }
   4197
   4198    HelpMarker("This example shows how you may implement a property editor using two columns.\nAll objects/fields data are dummies here.\nRemember that in many simple cases, you can use ImGui::SameLine(xxx) to position\nyour cursor horizontally instead of using the Columns() API.");
   4199
   4200    ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2,2));
   4201    ImGui::Columns(2);
   4202    ImGui::Separator();
   4203
   4204    struct funcs
   4205    {
   4206        static void ShowDummyObject(const char* prefix, int uid)
   4207        {
   4208            ImGui::PushID(uid);                      // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID.
   4209            ImGui::AlignTextToFramePadding();  // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high.
   4210            bool node_open = ImGui::TreeNode("Object", "%s_%u", prefix, uid);
   4211            ImGui::NextColumn();
   4212            ImGui::AlignTextToFramePadding();
   4213            ImGui::Text("my sailor is rich");
   4214            ImGui::NextColumn();
   4215            if (node_open)
   4216            {
   4217                static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f };
   4218                for (int i = 0; i < 8; i++)
   4219                {
   4220                    ImGui::PushID(i); // Use field index as identifier.
   4221                    if (i < 2)
   4222                    {
   4223                        ShowDummyObject("Child", 424242);
   4224                    }
   4225                    else
   4226                    {
   4227                        // Here we use a TreeNode to highlight on hover (we could use e.g. Selectable as well)
   4228                        ImGui::AlignTextToFramePadding();
   4229                        ImGui::TreeNodeEx("Field", ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_Bullet, "Field_%d", i);
   4230                        ImGui::NextColumn();
   4231                        ImGui::SetNextItemWidth(-1);
   4232                        if (i >= 5)
   4233                            ImGui::InputFloat("##value", &dummy_members[i], 1.0f);
   4234                        else
   4235                            ImGui::DragFloat("##value", &dummy_members[i], 0.01f);
   4236                        ImGui::NextColumn();
   4237                    }
   4238                    ImGui::PopID();
   4239                }
   4240                ImGui::TreePop();
   4241            }
   4242            ImGui::PopID();
   4243        }
   4244    };
   4245
   4246    // Iterate dummy objects with dummy members (all the same data)
   4247    for (int obj_i = 0; obj_i < 3; obj_i++)
   4248        funcs::ShowDummyObject("Object", obj_i);
   4249
   4250    ImGui::Columns(1);
   4251    ImGui::Separator();
   4252    ImGui::PopStyleVar();
   4253    ImGui::End();
   4254}
   4255
   4256//-----------------------------------------------------------------------------
   4257// [SECTION] Example App: Long Text / ShowExampleAppLongText()
   4258//-----------------------------------------------------------------------------
   4259
   4260// Demonstrate/test rendering huge amount of text, and the incidence of clipping.
   4261static void ShowExampleAppLongText(bool* p_open)
   4262{
   4263    ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiCond_FirstUseEver);
   4264    if (!ImGui::Begin("Example: Long text display", p_open))
   4265    {
   4266        ImGui::End();
   4267        return;
   4268    }
   4269
   4270    static int test_type = 0;
   4271    static ImGuiTextBuffer log;
   4272    static int lines = 0;
   4273    ImGui::Text("Printing unusually long amount of text.");
   4274    ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped\0Multiple calls to Text(), not clipped (slow)\0");
   4275    ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size());
   4276    if (ImGui::Button("Clear")) { log.clear(); lines = 0; }
   4277    ImGui::SameLine();
   4278    if (ImGui::Button("Add 1000 lines"))
   4279    {
   4280        for (int i = 0; i < 1000; i++)
   4281            log.appendf("%i The quick brown fox jumps over the lazy dog\n", lines+i);
   4282        lines += 1000;
   4283    }
   4284    ImGui::BeginChild("Log");
   4285    switch (test_type)
   4286    {
   4287    case 0:
   4288        // Single call to TextUnformatted() with a big buffer
   4289        ImGui::TextUnformatted(log.begin(), log.end());
   4290        break;
   4291    case 1:
   4292        {
   4293            // Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the ImGuiListClipper helper.
   4294            ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));
   4295            ImGuiListClipper clipper(lines);
   4296            while (clipper.Step())
   4297                for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
   4298                    ImGui::Text("%i The quick brown fox jumps over the lazy dog", i);
   4299            ImGui::PopStyleVar();
   4300            break;
   4301        }
   4302    case 2:
   4303        // Multiple calls to Text(), not clipped (slow)
   4304        ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));
   4305        for (int i = 0; i < lines; i++)
   4306            ImGui::Text("%i The quick brown fox jumps over the lazy dog", i);
   4307        ImGui::PopStyleVar();
   4308        break;
   4309    }
   4310    ImGui::EndChild();
   4311    ImGui::End();
   4312}
   4313
   4314//-----------------------------------------------------------------------------
   4315// [SECTION] Example App: Auto Resize / ShowExampleAppAutoResize()
   4316//-----------------------------------------------------------------------------
   4317
   4318// Demonstrate creating a window which gets auto-resized according to its content.
   4319static void ShowExampleAppAutoResize(bool* p_open)
   4320{
   4321    if (!ImGui::Begin("Example: Auto-resizing window", p_open, ImGuiWindowFlags_AlwaysAutoResize))
   4322    {
   4323        ImGui::End();
   4324        return;
   4325    }
   4326
   4327    static int lines = 10;
   4328    ImGui::Text("Window will resize every-frame to the size of its content.\nNote that you probably don't want to query the window size to\noutput your content because that would create a feedback loop.");
   4329    ImGui::SliderInt("Number of lines", &lines, 1, 20);
   4330    for (int i = 0; i < lines; i++)
   4331        ImGui::Text("%*sThis is line %d", i * 4, "", i); // Pad with space to extend size horizontally
   4332    ImGui::End();
   4333}
   4334
   4335//-----------------------------------------------------------------------------
   4336// [SECTION] Example App: Constrained Resize / ShowExampleAppConstrainedResize()
   4337//-----------------------------------------------------------------------------
   4338
   4339// Demonstrate creating a window with custom resize constraints.
   4340static void ShowExampleAppConstrainedResize(bool* p_open)
   4341{
   4342    struct CustomConstraints // Helper functions to demonstrate programmatic constraints
   4343    {
   4344        static void Square(ImGuiSizeCallbackData* data) { data->DesiredSize.x = data->DesiredSize.y = (data->DesiredSize.x > data->DesiredSize.y ? data->DesiredSize.x : data->DesiredSize.y); }
   4345        static void Step(ImGuiSizeCallbackData* data)   { float step = (float)(int)(intptr_t)data->UserData; data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); }
   4346    };
   4347
   4348    static bool auto_resize = false;
   4349    static int type = 0;
   4350    static int display_lines = 10;
   4351    if (type == 0) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0),    ImVec2(-1, FLT_MAX));      // Vertical only
   4352    if (type == 1) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1),    ImVec2(FLT_MAX, -1));      // Horizontal only
   4353    if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(100, 100), ImVec2(FLT_MAX, FLT_MAX)); // Width > 100, Height > 100
   4354    if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(400, -1),  ImVec2(500, -1));          // Width 400-500
   4355    if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 400),  ImVec2(-1, 500));          // Height 400-500
   4356    if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0),     ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square);                     // Always Square
   4357    if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0),     ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)(intptr_t)100); // Fixed Step
   4358
   4359    ImGuiWindowFlags flags = auto_resize ? ImGuiWindowFlags_AlwaysAutoResize : 0;
   4360    if (ImGui::Begin("Example: Constrained Resize", p_open, flags))
   4361    {
   4362        const char* desc[] =
   4363        {
   4364            "Resize vertical only",
   4365            "Resize horizontal only",
   4366            "Width > 100, Height > 100",
   4367            "Width 400-500",
   4368            "Height 400-500",
   4369            "Custom: Always Square",
   4370            "Custom: Fixed Steps (100)",
   4371        };
   4372        if (ImGui::Button("200x200")) { ImGui::SetWindowSize(ImVec2(200, 200)); } ImGui::SameLine();
   4373        if (ImGui::Button("500x500")) { ImGui::SetWindowSize(ImVec2(500, 500)); } ImGui::SameLine();
   4374        if (ImGui::Button("800x200")) { ImGui::SetWindowSize(ImVec2(800, 200)); }
   4375        ImGui::SetNextItemWidth(200);
   4376        ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc));
   4377        ImGui::SetNextItemWidth(200);
   4378        ImGui::DragInt("Lines", &display_lines, 0.2f, 1, 100);
   4379        ImGui::Checkbox("Auto-resize", &auto_resize);
   4380        for (int i = 0; i < display_lines; i++)
   4381            ImGui::Text("%*sHello, sailor! Making this line long enough for the example.", i * 4, "");
   4382    }
   4383    ImGui::End();
   4384}
   4385
   4386//-----------------------------------------------------------------------------
   4387// [SECTION] Example App: Simple Overlay / ShowExampleAppSimpleOverlay()
   4388//-----------------------------------------------------------------------------
   4389
   4390// Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use.
   4391static void ShowExampleAppSimpleOverlay(bool* p_open)
   4392{
   4393    const float DISTANCE = 10.0f;
   4394    static int corner = 0;
   4395    ImGuiIO& io = ImGui::GetIO();
   4396    if (corner != -1)
   4397    {
   4398        ImVec2 window_pos = ImVec2((corner & 1) ? io.DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? io.DisplaySize.y - DISTANCE : DISTANCE);
   4399        ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
   4400        ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
   4401    }
   4402    ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background
   4403    if (ImGui::Begin("Example: Simple overlay", p_open, (corner != -1 ? ImGuiWindowFlags_NoMove : 0) | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav))
   4404    {
   4405        ImGui::Text("Simple overlay\n" "in the corner of the screen.\n" "(right-click to change position)");
   4406        ImGui::Separator();
   4407        if (ImGui::IsMousePosValid())
   4408            ImGui::Text("Mouse Position: (%.1f,%.1f)", io.MousePos.x, io.MousePos.y);
   4409        else
   4410            ImGui::Text("Mouse Position: <invalid>");
   4411        if (ImGui::BeginPopupContextWindow())
   4412        {
   4413            if (ImGui::MenuItem("Custom",       NULL, corner == -1)) corner = -1;
   4414            if (ImGui::MenuItem("Top-left",     NULL, corner == 0)) corner = 0;
   4415            if (ImGui::MenuItem("Top-right",    NULL, corner == 1)) corner = 1;
   4416            if (ImGui::MenuItem("Bottom-left",  NULL, corner == 2)) corner = 2;
   4417            if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3;
   4418            if (p_open && ImGui::MenuItem("Close")) *p_open = false;
   4419            ImGui::EndPopup();
   4420        }
   4421    }
   4422    ImGui::End();
   4423}
   4424
   4425//-----------------------------------------------------------------------------
   4426// [SECTION] Example App: Manipulating Window Titles / ShowExampleAppWindowTitles()
   4427//-----------------------------------------------------------------------------
   4428
   4429// Demonstrate using "##" and "###" in identifiers to manipulate ID generation.
   4430// This apply to all regular items as well. Read FAQ section "How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs." for details.
   4431static void ShowExampleAppWindowTitles(bool*)
   4432{
   4433    // By default, Windows are uniquely identified by their title.
   4434    // You can use the "##" and "###" markers to manipulate the display/ID.
   4435
   4436    // Using "##" to display same title but have unique identifier.
   4437    ImGui::SetNextWindowPos(ImVec2(100, 100), ImGuiCond_FirstUseEver);
   4438    ImGui::Begin("Same title as another window##1");
   4439    ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique.");
   4440    ImGui::End();
   4441
   4442    ImGui::SetNextWindowPos(ImVec2(100, 200), ImGuiCond_FirstUseEver);
   4443    ImGui::Begin("Same title as another window##2");
   4444    ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique.");
   4445    ImGui::End();
   4446
   4447    // Using "###" to display a changing title but keep a static identifier "AnimatedTitle"
   4448    char buf[128];
   4449    sprintf(buf, "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime() / 0.25f) & 3], ImGui::GetFrameCount());
   4450    ImGui::SetNextWindowPos(ImVec2(100, 300), ImGuiCond_FirstUseEver);
   4451    ImGui::Begin(buf);
   4452    ImGui::Text("This window has a changing title.");
   4453    ImGui::End();
   4454}
   4455
   4456//-----------------------------------------------------------------------------
   4457// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering()
   4458//-----------------------------------------------------------------------------
   4459
   4460// Demonstrate using the low-level ImDrawList to draw custom shapes.
   4461static void ShowExampleAppCustomRendering(bool* p_open)
   4462{
   4463    if (!ImGui::Begin("Example: Custom rendering", p_open))
   4464    {
   4465        ImGui::End();
   4466        return;
   4467    }
   4468
   4469    // Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of overloaded operators, etc.
   4470    // Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your types and ImVec2/ImVec4.
   4471    // ImGui defines overloaded operators but they are internal to imgui.cpp and not exposed outside (to avoid messing with your types)
   4472    // In this example we are not using the maths operators!
   4473    ImDrawList* draw_list = ImGui::GetWindowDrawList();
   4474
   4475    if (ImGui::BeginTabBar("##TabBar"))
   4476    {
   4477        if (ImGui::BeginTabItem("Primitives"))
   4478        {
   4479            ImGui::PushItemWidth(-ImGui::GetFontSize() * 10);
   4480
   4481            // Draw gradients
   4482            // (note that those are currently exacerbating our sRGB/Linear issues)
   4483            ImGui::Text("Gradients");
   4484            ImVec2 gradient_size = ImVec2(ImGui::CalcItemWidth(), ImGui::GetFrameHeight());
   4485            {
   4486                ImVec2 p = ImGui::GetCursorScreenPos();
   4487                ImU32 col_a = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
   4488                ImU32 col_b = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
   4489                draw_list->AddRectFilledMultiColor(p, ImVec2(p.x + gradient_size.x, p.y + gradient_size.y), col_a, col_b, col_b, col_a);
   4490                ImGui::InvisibleButton("##gradient1", gradient_size);
   4491            }
   4492            {
   4493                ImVec2 p = ImGui::GetCursorScreenPos();
   4494                ImU32 col_a = ImGui::GetColorU32(ImVec4(0.0f, 1.0f, 0.0f, 1.0f));
   4495                ImU32 col_b = ImGui::GetColorU32(ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
   4496                draw_list->AddRectFilledMultiColor(p, ImVec2(p.x + gradient_size.x, p.y + gradient_size.y), col_a, col_b, col_b, col_a);
   4497                ImGui::InvisibleButton("##gradient2", gradient_size);
   4498            }
   4499
   4500            // Draw a bunch of primitives
   4501            ImGui::Text("All primitives");
   4502            static float sz = 36.0f;
   4503            static float thickness = 3.0f;
   4504            static int ngon_sides = 6;
   4505            static bool circle_segments_override = false;
   4506            static int circle_segments_override_v = 12;
   4507            static ImVec4 colf = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
   4508            ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
   4509            ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
   4510            ImGui::SliderInt("N-gon sides", &ngon_sides, 3, 12);
   4511            ImGui::Checkbox("##circlesegmentoverride", &circle_segments_override);
   4512            ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
   4513            if (ImGui::SliderInt("Circle segments", &circle_segments_override_v, 3, 40))
   4514                circle_segments_override = true;
   4515            ImGui::ColorEdit4("Color", &colf.x);
   4516            const ImVec2 p = ImGui::GetCursorScreenPos();
   4517            const ImU32 col = ImColor(colf);
   4518            const float spacing = 10.0f;
   4519            const ImDrawCornerFlags corners_none = 0;
   4520            const ImDrawCornerFlags corners_all = ImDrawCornerFlags_All;
   4521            const ImDrawCornerFlags corners_tl_br = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight;
   4522            const int circle_segments = circle_segments_override ? circle_segments_override_v : 0;
   4523            float x = p.x + 4.0f, y = p.y + 4.0f;
   4524            for (int n = 0; n < 2; n++)
   4525            {
   4526                // First line uses a thickness of 1.0f, second line uses the configurable thickness
   4527                float th = (n == 0) ? 1.0f : thickness;
   4528                draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th);         x += sz + spacing;  // N-gon
   4529                draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th);  x += sz + spacing;  // Circle
   4530                draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f,  corners_none, th);     x += sz + spacing;  // Square
   4531                draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_all, th);      x += sz + spacing;  // Square with all rounded corners
   4532                draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br, th);    x += sz + spacing;  // Square with two rounded corners
   4533                draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);      x += sz + spacing;      // Triangle
   4534                draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th); x += sz*0.4f + spacing; // Thin triangle
   4535                draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th);                               x += sz + spacing;  // Horizontal line (note: drawing a filled rectangle will be faster!)
   4536                draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th);                               x += spacing;       // Vertical line (note: drawing a filled rectangle will be faster!)
   4537                draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th);                          x += sz + spacing;  // Diagonal line
   4538                draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x + sz*1.3f, y + sz*0.3f), ImVec2(x + sz - sz*1.3f, y + sz - sz*0.3f), ImVec2(x + sz, y + sz), col, th);
   4539                x = p.x + 4;
   4540                y += sz + spacing;
   4541            }
   4542            draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides);   x += sz + spacing;  // N-gon
   4543            draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments);x += sz + spacing;  // Circle
   4544            draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col);                        x += sz + spacing;  // Square
   4545            draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f);                 x += sz + spacing;  // Square with all rounded corners
   4546            draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br);  x += sz + spacing;  // Square with two rounded corners
   4547            draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col);      x += sz + spacing;      // Triangle
   4548            draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle
   4549            draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col);                 x += sz + spacing;  // Horizontal line (faster than AddLine, but only handle integer thickness)
   4550            draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col);                 x += spacing*2.0f;  // Vertical line (faster than AddLine, but only handle integer thickness)
   4551            draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col);                          x += sz;            // Pixel (faster than AddLine)
   4552            draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
   4553            ImGui::Dummy(ImVec2((sz + spacing) * 9.8f, (sz + spacing) * 3));
   4554
   4555            ImGui::PopItemWidth();
   4556            ImGui::EndTabItem();
   4557        }
   4558
   4559        if (ImGui::BeginTabItem("Canvas"))
   4560        {
   4561            static ImVector<ImVec2> points;
   4562            static bool adding_line = false;
   4563            if (ImGui::Button("Clear")) points.clear();
   4564            if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } }
   4565            ImGui::Text("Left-click and drag to add lines,\nRight-click to undo");
   4566
   4567            // Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered()
   4568            // But you can also draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos().
   4569            // If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max).
   4570            ImVec2 canvas_pos = ImGui::GetCursorScreenPos();            // ImDrawList API uses screen coordinates!
   4571            ImVec2 canvas_size = ImGui::GetContentRegionAvail();        // Resize canvas to what's available
   4572            if (canvas_size.x < 50.0f) canvas_size.x = 50.0f;
   4573            if (canvas_size.y < 50.0f) canvas_size.y = 50.0f;
   4574            draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(50, 50, 50, 255), IM_COL32(50, 50, 60, 255), IM_COL32(60, 60, 70, 255), IM_COL32(50, 50, 60, 255));
   4575            draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(255, 255, 255, 255));
   4576
   4577            bool adding_preview = false;
   4578            ImGui::InvisibleButton("canvas", canvas_size);
   4579            ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y);
   4580            if (adding_line)
   4581            {
   4582                adding_preview = true;
   4583                points.push_back(mouse_pos_in_canvas);
   4584                if (!ImGui::IsMouseDown(0))
   4585                    adding_line = adding_preview = false;
   4586            }
   4587            if (ImGui::IsItemHovered())
   4588            {
   4589                if (!adding_line && ImGui::IsMouseClicked(0))
   4590                {
   4591                    points.push_back(mouse_pos_in_canvas);
   4592                    adding_line = true;
   4593                }
   4594                if (ImGui::IsMouseClicked(1) && !points.empty())
   4595                {
   4596                    adding_line = adding_preview = false;
   4597                    points.pop_back();
   4598                    points.pop_back();
   4599                }
   4600            }
   4601            draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), true);      // clip lines within the canvas (if we resize it, etc.)
   4602            for (int i = 0; i < points.Size - 1; i += 2)
   4603                draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i + 1].x, canvas_pos.y + points[i + 1].y), IM_COL32(255, 255, 0, 255), 2.0f);
   4604            draw_list->PopClipRect();
   4605            if (adding_preview)
   4606                points.pop_back();
   4607            ImGui::EndTabItem();
   4608        }
   4609
   4610        if (ImGui::BeginTabItem("BG/FG draw lists"))
   4611        {
   4612            static bool draw_bg = true;
   4613            static bool draw_fg = true;
   4614            ImGui::Checkbox("Draw in Background draw list", &draw_bg);
   4615            ImGui::SameLine(); HelpMarker("The Background draw list will be rendered below every Dear ImGui windows.");
   4616            ImGui::Checkbox("Draw in Foreground draw list", &draw_fg);
   4617            ImGui::SameLine(); HelpMarker("The Foreground draw list will be rendered over every Dear ImGui windows.");
   4618            ImVec2 window_pos = ImGui::GetWindowPos();
   4619            ImVec2 window_size = ImGui::GetWindowSize();
   4620            ImVec2 window_center = ImVec2(window_pos.x + window_size.x * 0.5f, window_pos.y + window_size.y * 0.5f);
   4621            if (draw_bg)
   4622                ImGui::GetBackgroundDrawList()->AddCircle(window_center, window_size.x * 0.6f, IM_COL32(255, 0, 0, 200), 0, 10+4);
   4623            if (draw_fg)
   4624                ImGui::GetForegroundDrawList()->AddCircle(window_center, window_size.y * 0.6f, IM_COL32(0, 255, 0, 200), 0, 10);
   4625            ImGui::EndTabItem();
   4626        }
   4627
   4628        ImGui::EndTabBar();
   4629    }
   4630
   4631    ImGui::End();
   4632}
   4633
   4634//-----------------------------------------------------------------------------
   4635// [SECTION] Example App: Documents Handling / ShowExampleAppDocuments()
   4636//-----------------------------------------------------------------------------
   4637
   4638// Simplified structure to mimic a Document model
   4639struct MyDocument
   4640{
   4641    const char* Name;           // Document title
   4642    bool        Open;           // Set when the document is open (in this demo, we keep an array of all available documents to simplify the demo)
   4643    bool        OpenPrev;       // Copy of Open from last update.
   4644    bool        Dirty;          // Set when the document has been modified
   4645    bool        WantClose;      // Set when the document
   4646    ImVec4      Color;          // An arbitrary variable associated to the document
   4647
   4648    MyDocument(const char* name, bool open = true, const ImVec4& color = ImVec4(1.0f,1.0f,1.0f,1.0f))
   4649    {
   4650        Name = name;
   4651        Open = OpenPrev = open;
   4652        Dirty = false;
   4653        WantClose = false;
   4654        Color = color;
   4655    }
   4656    void DoOpen()       { Open = true; }
   4657    void DoQueueClose() { WantClose = true; }
   4658    void DoForceClose() { Open = false; Dirty = false; }
   4659    void DoSave()       { Dirty = false; }
   4660
   4661    // Display dummy contents for the Document
   4662    static void DisplayContents(MyDocument* doc)
   4663    {
   4664        ImGui::PushID(doc);
   4665        ImGui::Text("Document \"%s\"", doc->Name);
   4666        ImGui::PushStyleColor(ImGuiCol_Text, doc->Color);
   4667        ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
   4668        ImGui::PopStyleColor();
   4669        if (ImGui::Button("Modify", ImVec2(100, 0)))
   4670            doc->Dirty = true;
   4671        ImGui::SameLine();
   4672        if (ImGui::Button("Save", ImVec2(100, 0)))
   4673            doc->DoSave();
   4674        ImGui::ColorEdit3("color", &doc->Color.x);  // Useful to test drag and drop and hold-dragged-to-open-tab behavior.
   4675        ImGui::PopID();
   4676    }
   4677
   4678    // Display context menu for the Document
   4679    static void DisplayContextMenu(MyDocument* doc)
   4680    {
   4681        if (!ImGui::BeginPopupContextItem())
   4682            return;
   4683
   4684        char buf[256];
   4685        sprintf(buf, "Save %s", doc->Name);
   4686        if (ImGui::MenuItem(buf, "CTRL+S", false, doc->Open))
   4687            doc->DoSave();
   4688        if (ImGui::MenuItem("Close", "CTRL+W", false, doc->Open))
   4689            doc->DoQueueClose();
   4690        ImGui::EndPopup();
   4691    }
   4692};
   4693
   4694struct ExampleAppDocuments
   4695{
   4696    ImVector<MyDocument> Documents;
   4697
   4698    ExampleAppDocuments()
   4699    {
   4700        Documents.push_back(MyDocument("Lettuce",             true,  ImVec4(0.4f, 0.8f, 0.4f, 1.0f)));
   4701        Documents.push_back(MyDocument("Eggplant",            true,  ImVec4(0.8f, 0.5f, 1.0f, 1.0f)));
   4702        Documents.push_back(MyDocument("Carrot",              true,  ImVec4(1.0f, 0.8f, 0.5f, 1.0f)));
   4703        Documents.push_back(MyDocument("Tomato",              false, ImVec4(1.0f, 0.3f, 0.4f, 1.0f)));
   4704        Documents.push_back(MyDocument("A Rather Long Title", false));
   4705        Documents.push_back(MyDocument("Some Document",       false));
   4706    }
   4707};
   4708
   4709// [Optional] Notify the system of Tabs/Windows closure that happened outside the regular tab interface.
   4710// If a tab has been closed programmatically (aka closed from another source such as the Checkbox() in the demo, as opposed
   4711// to clicking on the regular tab closing button) and stops being submitted, it will take a frame for the tab bar to notice its absence.
   4712// During this frame there will be a gap in the tab bar, and if the tab that has disappeared was the selected one, the tab bar
   4713// will report no selected tab during the frame. This will effectively give the impression of a flicker for one frame.
   4714// We call SetTabItemClosed() to manually notify the Tab Bar or Docking system of removed tabs to avoid this glitch.
   4715// Note that this completely optional, and only affect tab bars with the ImGuiTabBarFlags_Reorderable flag.
   4716static void NotifyOfDocumentsClosedElsewhere(ExampleAppDocuments& app)
   4717{
   4718    for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++)
   4719    {
   4720        MyDocument* doc = &app.Documents[doc_n];
   4721        if (!doc->Open && doc->OpenPrev)
   4722            ImGui::SetTabItemClosed(doc->Name);
   4723        doc->OpenPrev = doc->Open;
   4724    }
   4725}
   4726
   4727void ShowExampleAppDocuments(bool* p_open)
   4728{
   4729    static ExampleAppDocuments app;
   4730
   4731    // Options
   4732    static bool opt_reorderable = true;
   4733    static ImGuiTabBarFlags opt_fitting_flags = ImGuiTabBarFlags_FittingPolicyDefault_;
   4734
   4735    bool window_contents_visible = ImGui::Begin("Example: Documents", p_open, ImGuiWindowFlags_MenuBar);
   4736    if (!window_contents_visible)
   4737    {
   4738        ImGui::End();
   4739        return;
   4740    }
   4741
   4742    // Menu
   4743    if (ImGui::BeginMenuBar())
   4744    {
   4745        if (ImGui::BeginMenu("File"))
   4746        {
   4747            int open_count = 0;
   4748            for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++)
   4749                open_count += app.Documents[doc_n].Open ? 1 : 0;
   4750
   4751            if (ImGui::BeginMenu("Open", open_count < app.Documents.Size))
   4752            {
   4753                for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++)
   4754                {
   4755                    MyDocument* doc = &app.Documents[doc_n];
   4756                    if (!doc->Open)
   4757                        if (ImGui::MenuItem(doc->Name))
   4758                            doc->DoOpen();
   4759                }
   4760                ImGui::EndMenu();
   4761            }
   4762            if (ImGui::MenuItem("Close All Documents", NULL, false, open_count > 0))
   4763                for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++)
   4764                    app.Documents[doc_n].DoQueueClose();
   4765            if (ImGui::MenuItem("Exit", "Alt+F4")) {}
   4766            ImGui::EndMenu();
   4767        }
   4768        ImGui::EndMenuBar();
   4769    }
   4770
   4771    // [Debug] List documents with one checkbox for each
   4772    for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++)
   4773    {
   4774        MyDocument* doc = &app.Documents[doc_n];
   4775        if (doc_n > 0)
   4776            ImGui::SameLine();
   4777        ImGui::PushID(doc);
   4778        if (ImGui::Checkbox(doc->Name, &doc->Open))
   4779            if (!doc->Open)
   4780                doc->DoForceClose();
   4781        ImGui::PopID();
   4782    }
   4783
   4784    ImGui::Separator();
   4785
   4786    // Submit Tab Bar and Tabs
   4787    {
   4788        ImGuiTabBarFlags tab_bar_flags = (opt_fitting_flags) | (opt_reorderable ? ImGuiTabBarFlags_Reorderable : 0);
   4789        if (ImGui::BeginTabBar("##tabs", tab_bar_flags))
   4790        {
   4791            if (opt_reorderable)
   4792                NotifyOfDocumentsClosedElsewhere(app);
   4793
   4794            // [DEBUG] Stress tests
   4795            //if ((ImGui::GetFrameCount() % 30) == 0) docs[1].Open ^= 1;            // [DEBUG] Automatically show/hide a tab. Test various interactions e.g. dragging with this on.
   4796            //if (ImGui::GetIO().KeyCtrl) ImGui::SetTabItemSelected(docs[1].Name);  // [DEBUG] Test SetTabItemSelected(), probably not very useful as-is anyway..
   4797
   4798            // Submit Tabs
   4799            for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++)
   4800            {
   4801                MyDocument* doc = &app.Documents[doc_n];
   4802                if (!doc->Open)
   4803                    continue;
   4804
   4805                ImGuiTabItemFlags tab_flags = (doc->Dirty ? ImGuiTabItemFlags_UnsavedDocument : 0);
   4806                bool visible = ImGui::BeginTabItem(doc->Name, &doc->Open, tab_flags);
   4807
   4808                // Cancel attempt to close when unsaved add to save queue so we can display a popup.
   4809                if (!doc->Open && doc->Dirty)
   4810                {
   4811                    doc->Open = true;
   4812                    doc->DoQueueClose();
   4813                }
   4814
   4815                MyDocument::DisplayContextMenu(doc);
   4816                if (visible)
   4817                {
   4818                    MyDocument::DisplayContents(doc);
   4819                    ImGui::EndTabItem();
   4820                }
   4821            }
   4822
   4823            ImGui::EndTabBar();
   4824        }
   4825    }
   4826
   4827    // Update closing queue
   4828    static ImVector<MyDocument*> close_queue;
   4829    if (close_queue.empty())
   4830    {
   4831        // Close queue is locked once we started a popup
   4832        for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++)
   4833        {
   4834            MyDocument* doc = &app.Documents[doc_n];
   4835            if (doc->WantClose)
   4836            {
   4837                doc->WantClose = false;
   4838                close_queue.push_back(doc);
   4839            }
   4840        }
   4841    }
   4842
   4843    // Display closing confirmation UI
   4844    if (!close_queue.empty())
   4845    {
   4846        int close_queue_unsaved_documents = 0;
   4847        for (int n = 0; n < close_queue.Size; n++)
   4848            if (close_queue[n]->Dirty)
   4849                close_queue_unsaved_documents++;
   4850
   4851        if (close_queue_unsaved_documents == 0)
   4852        {
   4853            // Close documents when all are unsaved
   4854            for (int n = 0; n < close_queue.Size; n++)
   4855                close_queue[n]->DoForceClose();
   4856            close_queue.clear();
   4857        }
   4858        else
   4859        {
   4860            if (!ImGui::IsPopupOpen("Save?"))
   4861                ImGui::OpenPopup("Save?");
   4862            if (ImGui::BeginPopupModal("Save?"))
   4863            {
   4864                ImGui::Text("Save change to the following items?");
   4865                ImGui::SetNextItemWidth(-1.0f);
   4866                if (ImGui::ListBoxHeader("##", close_queue_unsaved_documents, 6))
   4867                {
   4868                    for (int n = 0; n < close_queue.Size; n++)
   4869                        if (close_queue[n]->Dirty)
   4870                            ImGui::Text("%s", close_queue[n]->Name);
   4871                    ImGui::ListBoxFooter();
   4872                }
   4873
   4874                if (ImGui::Button("Yes", ImVec2(80, 0)))
   4875                {
   4876                    for (int n = 0; n < close_queue.Size; n++)
   4877                    {
   4878                        if (close_queue[n]->Dirty)
   4879                            close_queue[n]->DoSave();
   4880                        close_queue[n]->DoForceClose();
   4881                    }
   4882                    close_queue.clear();
   4883                    ImGui::CloseCurrentPopup();
   4884                }
   4885                ImGui::SameLine();
   4886                if (ImGui::Button("No", ImVec2(80, 0)))
   4887                {
   4888                    for (int n = 0; n < close_queue.Size; n++)
   4889                        close_queue[n]->DoForceClose();
   4890                    close_queue.clear();
   4891                    ImGui::CloseCurrentPopup();
   4892                }
   4893                ImGui::SameLine();
   4894                if (ImGui::Button("Cancel", ImVec2(80, 0)))
   4895                {
   4896                    close_queue.clear();
   4897                    ImGui::CloseCurrentPopup();
   4898                }
   4899                ImGui::EndPopup();
   4900            }
   4901        }
   4902    }
   4903
   4904    ImGui::End();
   4905}
   4906
   4907// End of Demo code
   4908#else
   4909
   4910void ImGui::ShowAboutWindow(bool*) {}
   4911void ImGui::ShowDemoWindow(bool*) {}
   4912void ImGui::ShowUserGuide() {}
   4913void ImGui::ShowStyleEditor(ImGuiStyle*) {}
   4914
   4915#endif
   4916
   4917#endif // #ifndef IMGUI_DISABLE