Revision a8009d0e
Added by david.sorber 8 months ago
| external/imgui/imgui_demo.cpp | ||
|---|---|---|
|
// dear imgui, v1.91.5
|
||
|
// dear imgui, v1.92.5
|
||
|
// (demo code)
|
||
|
|
||
|
// Help:
|
||
| ... | ... | |
|
// Because we can't assume anything about your support of maths operators, we cannot use them in imgui_demo.cpp.
|
||
|
|
||
|
// Navigating this file:
|
||
|
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
|
||
|
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
|
||
|
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
|
||
|
// - In Visual Studio: Ctrl+Comma ("Edit.GoToAll") can follow symbols inside comments, whereas Ctrl+F12 ("Edit.GoToImplementation") cannot.
|
||
|
// - In Visual Studio w/ Visual Assist installed: Alt+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
|
||
|
// - In VS Code, CLion, etc.: Ctrl+Click can follow symbols inside comments.
|
||
|
// - You can search/grep for all sections listed in the index to find the section.
|
||
|
|
||
|
/*
|
||
| ... | ... | |
|
|
||
|
// [SECTION] Forward Declarations
|
||
|
// [SECTION] Helpers
|
||
|
// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor & Multi-Select demos)
|
||
|
// [SECTION] Demo Window / ShowDemoWindow()
|
||
|
// [SECTION] ShowDemoWindowMenuBar()
|
||
|
// [SECTION] ShowDemoWindowWidgets()
|
||
|
// [SECTION] ShowDemoWindowMultiSelect()
|
||
|
// [SECTION] ShowDemoWindowLayout()
|
||
|
// [SECTION] ShowDemoWindowPopups()
|
||
|
// [SECTION] ShowDemoWindowTables()
|
||
|
// [SECTION] ShowDemoWindowInputs()
|
||
|
// [SECTION] DemoWindowMenuBar()
|
||
|
// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor & Multi-Select demos)
|
||
|
// [SECTION] DemoWindowWidgetsBasic()
|
||
|
// [SECTION] DemoWindowWidgetsBullets()
|
||
|
// [SECTION] DemoWindowWidgetsCollapsingHeaders()
|
||
|
// [SECTION] DemoWindowWidgetsComboBoxes()
|
||
|
// [SECTION] DemoWindowWidgetsColorAndPickers()
|
||
|
// [SECTION] DemoWindowWidgetsDataTypes()
|
||
|
// [SECTION] DemoWindowWidgetsDisableBlocks()
|
||
|
// [SECTION] DemoWindowWidgetsDragAndDrop()
|
||
|
// [SECTION] DemoWindowWidgetsDragsAndSliders()
|
||
|
// [SECTION] DemoWindowWidgetsFonts()
|
||
|
// [SECTION] DemoWindowWidgetsImages()
|
||
|
// [SECTION] DemoWindowWidgetsListBoxes()
|
||
|
// [SECTION] DemoWindowWidgetsMultiComponents()
|
||
|
// [SECTION] DemoWindowWidgetsPlotting()
|
||
|
// [SECTION] DemoWindowWidgetsProgressBars()
|
||
|
// [SECTION] DemoWindowWidgetsQueryingStatuses()
|
||
|
// [SECTION] DemoWindowWidgetsSelectables()
|
||
|
// [SECTION] DemoWindowWidgetsSelectionAndMultiSelect()
|
||
|
// [SECTION] DemoWindowWidgetsTabs()
|
||
|
// [SECTION] DemoWindowWidgetsText()
|
||
|
// [SECTION] DemoWindowWidgetsTextFilter()
|
||
|
// [SECTION] DemoWindowWidgetsTextInput()
|
||
|
// [SECTION] DemoWindowWidgetsTooltips()
|
||
|
// [SECTION] DemoWindowWidgetsTreeNodes()
|
||
|
// [SECTION] DemoWindowWidgetsVerticalSliders()
|
||
|
// [SECTION] DemoWindowWidgets()
|
||
|
// [SECTION] DemoWindowLayout()
|
||
|
// [SECTION] DemoWindowPopups()
|
||
|
// [SECTION] DemoWindowTables()
|
||
|
// [SECTION] DemoWindowInputs()
|
||
|
// [SECTION] About Window / ShowAboutWindow()
|
||
|
// [SECTION] Style Editor / ShowStyleEditor()
|
||
|
// [SECTION] User Guide / ShowUserGuide()
|
||
| ... | ... | |
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning: 'xx' is deprecated: The POSIX name for this.. // for strdup used in demo code (so user can copy & paste the code)
|
||
|
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type
|
||
|
#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int'
|
||
|
#pragma clang diagnostic ignored "-Wformat-security" // warning: format string is not a string literal
|
||
|
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
|
||
|
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used.
|
||
| ... | ... | |
|
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier
|
||
|
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||
|
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||
|
#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label
|
||
|
#elif defined(__GNUC__)
|
||
|
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||
|
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||
|
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
|
||
|
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||
|
#pragma GCC diagnostic ignored "-Wformat-security" // warning: format string is not a string literal (potentially insecure)
|
||
|
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||
|
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
|
||
|
#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.
|
||
|
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||
|
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||
|
#endif
|
||
|
|
||
|
// Play it nice with Windows users (Update: May 2018, Notepad now supports Unix-style carriage returns!)
|
||
| ... | ... | |
|
|
||
|
// We split the contents of the big ShowDemoWindow() function into smaller functions
|
||
|
// (because the link time of very large functions tends to grow non-linearly)
|
||
|
static void ShowDemoWindowMenuBar(ImGuiDemoWindowData* demo_data);
|
||
|
static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data);
|
||
|
static void ShowDemoWindowMultiSelect(ImGuiDemoWindowData* demo_data);
|
||
|
static void ShowDemoWindowLayout();
|
||
|
static void ShowDemoWindowPopups();
|
||
|
static void ShowDemoWindowTables();
|
||
|
static void ShowDemoWindowColumns();
|
||
|
static void ShowDemoWindowInputs();
|
||
|
static void DemoWindowMenuBar(ImGuiDemoWindowData* demo_data);
|
||
|
static void DemoWindowWidgets(ImGuiDemoWindowData* demo_data);
|
||
|
static void DemoWindowLayout();
|
||
|
static void DemoWindowPopups();
|
||
|
static void DemoWindowTables();
|
||
|
static void DemoWindowColumns();
|
||
|
static void DemoWindowInputs();
|
||
|
|
||
|
// Helper tree functions used by Property Editor & Multi-Select demos
|
||
|
struct ExampleTreeNode;
|
||
|
static ExampleTreeNode* ExampleTree_CreateNode(const char* name, int uid, ExampleTreeNode* parent);
|
||
|
static void ExampleTree_DestroyNode(ExampleTreeNode* node);
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] Helpers
|
||
| ... | ... | |
|
extern void* GImGuiDemoMarkerCallbackUserData;
|
||
|
ImGuiDemoMarkerCallback GImGuiDemoMarkerCallback = NULL;
|
||
|
void* GImGuiDemoMarkerCallbackUserData = NULL;
|
||
|
#define IMGUI_DEMO_MARKER(section) do { if (GImGuiDemoMarkerCallback != NULL) GImGuiDemoMarkerCallback(__FILE__, __LINE__, section, GImGuiDemoMarkerCallbackUserData); } while (0)
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor etc.)
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
// Simple representation for a tree
|
||
|
// (this is designed to be simple to understand for our demos, not to be fancy or efficient etc.)
|
||
|
struct ExampleTreeNode
|
||
|
{
|
||
|
// Tree structure
|
||
|
char Name[28] = "";
|
||
|
int UID = 0;
|
||
|
ExampleTreeNode* Parent = NULL;
|
||
|
ImVector<ExampleTreeNode*> Childs;
|
||
|
unsigned short IndexInParent = 0; // Maintaining this allows us to implement linear traversal more easily
|
||
|
|
||
|
// Leaf Data
|
||
|
bool HasData = false; // All leaves have data
|
||
|
bool DataMyBool = true;
|
||
|
int DataMyInt = 128;
|
||
|
ImVec2 DataMyVec2 = ImVec2(0.0f, 3.141592f);
|
||
|
};
|
||
|
|
||
|
// Simple representation of struct metadata/serialization data.
|
||
|
// (this is a minimal version of what a typical advanced application may provide)
|
||
|
struct ExampleMemberInfo
|
||
|
{
|
||
|
const char* Name; // Member name
|
||
|
ImGuiDataType DataType; // Member type
|
||
|
int DataCount; // Member count (1 when scalar)
|
||
|
int Offset; // Offset inside parent structure
|
||
|
};
|
||
|
|
||
|
// Metadata description of ExampleTreeNode struct.
|
||
|
static const ExampleMemberInfo ExampleTreeNodeMemberInfos[]
|
||
|
{
|
||
|
{ "MyBool", ImGuiDataType_Bool, 1, offsetof(ExampleTreeNode, DataMyBool) },
|
||
|
{ "MyInt", ImGuiDataType_S32, 1, offsetof(ExampleTreeNode, DataMyInt) },
|
||
|
{ "MyVec2", ImGuiDataType_Float, 2, offsetof(ExampleTreeNode, DataMyVec2) },
|
||
|
};
|
||
|
|
||
|
static ExampleTreeNode* ExampleTree_CreateNode(const char* name, int uid, ExampleTreeNode* parent)
|
||
|
{
|
||
|
ExampleTreeNode* node = IM_NEW(ExampleTreeNode);
|
||
|
snprintf(node->Name, IM_ARRAYSIZE(node->Name), "%s", name);
|
||
|
node->UID = uid;
|
||
|
node->Parent = parent;
|
||
|
node->IndexInParent = parent ? (unsigned short)parent->Childs.Size : 0;
|
||
|
if (parent)
|
||
|
parent->Childs.push_back(node);
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
// Create example tree data
|
||
|
// (this allocates _many_ more times than most other code in either Dear ImGui or others demo)
|
||
|
static ExampleTreeNode* ExampleTree_CreateDemoTree()
|
||
|
{
|
||
|
static const char* root_names[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pear", "Pineapple", "Strawberry", "Watermelon" };
|
||
|
const size_t NAME_MAX_LEN = sizeof(ExampleTreeNode::Name);
|
||
|
char name_buf[NAME_MAX_LEN];
|
||
|
int uid = 0;
|
||
|
ExampleTreeNode* node_L0 = ExampleTree_CreateNode("<ROOT>", ++uid, NULL);
|
||
|
const int root_items_multiplier = 2;
|
||
|
for (int idx_L0 = 0; idx_L0 < IM_ARRAYSIZE(root_names) * root_items_multiplier; idx_L0++)
|
||
|
{
|
||
|
snprintf(name_buf, IM_ARRAYSIZE(name_buf), "%s %d", root_names[idx_L0 / root_items_multiplier], idx_L0 % root_items_multiplier);
|
||
|
ExampleTreeNode* node_L1 = ExampleTree_CreateNode(name_buf, ++uid, node_L0);
|
||
|
const int number_of_childs = (int)strlen(node_L1->Name);
|
||
|
for (int idx_L1 = 0; idx_L1 < number_of_childs; idx_L1++)
|
||
|
{
|
||
|
snprintf(name_buf, IM_ARRAYSIZE(name_buf), "Child %d", idx_L1);
|
||
|
ExampleTreeNode* node_L2 = ExampleTree_CreateNode(name_buf, ++uid, node_L1);
|
||
|
node_L2->HasData = true;
|
||
|
if (idx_L1 == 0)
|
||
|
{
|
||
|
snprintf(name_buf, IM_ARRAYSIZE(name_buf), "Sub-child %d", 0);
|
||
|
ExampleTreeNode* node_L3 = ExampleTree_CreateNode(name_buf, ++uid, node_L2);
|
||
|
node_L3->HasData = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return node_L0;
|
||
|
}
|
||
|
#define IMGUI_DEMO_MARKER(section) do { if (GImGuiDemoMarkerCallback != NULL) GImGuiDemoMarkerCallback("imgui_demo.cpp", __LINE__, section, GImGuiDemoMarkerCallbackUserData); } while (0)
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] Demo Window / ShowDemoWindow()
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
// Data to be shared accross different functions of the demo.
|
||
|
// Data to be shared across different functions of the demo.
|
||
|
struct ImGuiDemoWindowData
|
||
|
{
|
||
|
// Examples Apps (accessible from the "Examples" menu)
|
||
| ... | ... | |
|
bool ShowAbout = false;
|
||
|
|
||
|
// Other data
|
||
|
bool DisableSections = false;
|
||
|
ExampleTreeNode* DemoTree = NULL;
|
||
|
|
||
|
~ImGuiDemoWindowData() { if (DemoTree) ExampleTree_DestroyNode(DemoTree); }
|
||
|
};
|
||
|
|
||
|
// Demonstrate most Dear ImGui features (this is big function!)
|
||
| ... | ... | |
|
return;
|
||
|
}
|
||
|
|
||
|
// Most "big" widgets share a common width settings by default. See 'Demo->Layout->Widgets Width' for details.
|
||
|
ImGui::PushItemWidth(ImGui::GetFontSize() * -12); // e.g. Leave a fixed amount of width for labels (by passing a negative value), the rest goes to widgets.
|
||
|
//ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.35f); // e.g. Use 2/3 of the space for widgets and 1/3 for labels (right align)
|
||
|
// Most framed widgets share a common width settings. Remaining width is used for the label.
|
||
|
// The width of the frame may be changed with PushItemWidth() or SetNextItemWidth().
|
||
|
// - Positive value for absolute size, negative value for right-alignment.
|
||
|
// - The default value is about GetWindowWidth() * 0.65f.
|
||
|
// - See 'Demo->Layout->Widgets Width' for details.
|
||
|
// Here we change the frame width based on how much width we want to give to the label.
|
||
|
const float label_width_base = ImGui::GetFontSize() * 12; // Some amount of width for label, based on font size.
|
||
|
const float label_width_max = ImGui::GetContentRegionAvail().x * 0.40f; // ...but always leave some room for framed widgets.
|
||
|
const float label_width = IM_MIN(label_width_base, label_width_max);
|
||
|
ImGui::PushItemWidth(-label_width); // Right-align: framed items will leave 'label_width' available for the label.
|
||
|
//ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.40f); // e.g. Use 40% width for framed widgets, leaving 60% width for labels.
|
||
|
//ImGui::PushItemWidth(-ImGui::GetContentRegionAvail().x * 0.40f); // e.g. Use 40% width for labels, leaving 60% width for framed widgets.
|
||
|
//ImGui::PushItemWidth(ImGui::GetFontSize() * -12); // e.g. Use XXX width for labels, leaving the rest for framed widgets.
|
||
|
|
||
|
// Menu Bar
|
||
|
ShowDemoWindowMenuBar(&demo_data);
|
||
|
DemoWindowMenuBar(&demo_data);
|
||
|
|
||
|
ImGui::Text("dear imgui says hello! (%s) (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM);
|
||
|
ImGui::Spacing();
|
||
| ... | ... | |
|
ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires ImGuiBackendFlags_HasMouseCursors for better mouse cursor feedback.");
|
||
|
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
|
||
|
ImGui::Checkbox("io.ConfigWindowsCopyContentsWithCtrlC", &io.ConfigWindowsCopyContentsWithCtrlC); // [EXPERIMENTAL]
|
||
|
ImGui::SameLine(); HelpMarker("*EXPERIMENTAL* CTRL+C copy the contents of focused window into the clipboard.\n\nExperimental because:\n- (1) has known issues with nested Begin/End pairs.\n- (2) text output quality varies.\n- (3) text output is in submission order rather than spatial order.");
|
||
|
ImGui::SameLine(); HelpMarker("*EXPERIMENTAL* Ctrl+C copy the contents of focused window into the clipboard.\n\nExperimental because:\n- (1) has known issues with nested Begin/End pairs.\n- (2) text output quality varies.\n- (3) text output is in submission order rather than spatial order.");
|
||
|
ImGui::Checkbox("io.ConfigScrollbarScrollByPage", &io.ConfigScrollbarScrollByPage);
|
||
|
ImGui::SameLine(); HelpMarker("Enable scrolling page by page when clicking outside the scrollbar grab.\nWhen disabled, always scroll to clicked location.\nWhen enabled, Shift+Click scrolls to clicked location.");
|
||
|
|
||
| ... | ... | |
|
"- Error recovery is not perfect nor guaranteed! It is a feature to ease development.\n"
|
||
|
"- You not are not supposed to rely on it in the course of a normal application run.\n"
|
||
|
"- Possible usage: facilitate recovery from errors triggered from a scripting language or after specific exceptions handlers.\n"
|
||
|
"- Always ensure that on programmers seat you have at minimum Asserts or Tooltips enabled when making direct imgui API call!"
|
||
|
"- Always ensure that on programmers seat you have at minimum Asserts or Tooltips enabled when making direct imgui API call! "
|
||
|
"Otherwise it would severely hinder your ability to catch and correct mistakes!");
|
||
|
ImGui::Checkbox("io.ConfigErrorRecoveryEnableAssert", &io.ConfigErrorRecoveryEnableAssert);
|
||
|
ImGui::Checkbox("io.ConfigErrorRecoveryEnableDebugLog", &io.ConfigErrorRecoveryEnableDebugLog);
|
||
| ... | ... | |
|
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &io.BackendFlags, ImGuiBackendFlags_HasMouseCursors);
|
||
|
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &io.BackendFlags, ImGuiBackendFlags_HasSetMousePos);
|
||
|
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset);
|
||
|
ImGui::CheckboxFlags("io.BackendFlags: RendererHasTextures", &io.BackendFlags, ImGuiBackendFlags_RendererHasTextures);
|
||
|
ImGui::EndDisabled();
|
||
|
|
||
|
ImGui::TreePop();
|
||
|
ImGui::Spacing();
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Configuration/Style");
|
||
|
if (ImGui::TreeNode("Style"))
|
||
|
IMGUI_DEMO_MARKER("Configuration/Style, Fonts");
|
||
|
if (ImGui::TreeNode("Style, Fonts"))
|
||
|
{
|
||
|
ImGui::Checkbox("Style Editor", &demo_data.ShowStyleEditor);
|
||
|
ImGui::SameLine();
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// All demo contents
|
||
|
ShowDemoWindowWidgets(&demo_data);
|
||
|
ShowDemoWindowLayout();
|
||
|
ShowDemoWindowPopups();
|
||
|
ShowDemoWindowTables();
|
||
|
ShowDemoWindowInputs();
|
||
|
DemoWindowWidgets(&demo_data);
|
||
|
DemoWindowLayout();
|
||
|
DemoWindowPopups();
|
||
|
DemoWindowTables();
|
||
|
DemoWindowInputs();
|
||
|
|
||
|
// End of ShowDemoWindow()
|
||
|
ImGui::PopItemWidth();
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] ShowDemoWindowMenuBar()
|
||
|
// [SECTION] DemoWindowMenuBar()
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
static void ShowDemoWindowMenuBar(ImGuiDemoWindowData* demo_data)
|
||
|
static void DemoWindowMenuBar(ImGuiDemoWindowData* demo_data)
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Menu");
|
||
|
if (ImGui::BeginMenuBar())
|
||
| ... | ... | |
|
const bool has_debug_tools = false;
|
||
|
#endif
|
||
|
ImGui::MenuItem("Metrics/Debugger", NULL, &demo_data->ShowMetrics, has_debug_tools);
|
||
|
if (ImGui::BeginMenu("Debug Options"))
|
||
|
{
|
||
|
ImGui::BeginDisabled(!has_debug_tools);
|
||
|
ImGui::Checkbox("Highlight ID Conflicts", &io.ConfigDebugHighlightIdConflicts);
|
||
|
ImGui::EndDisabled();
|
||
|
ImGui::Checkbox("Assert on error recovery", &io.ConfigErrorRecoveryEnableAssert);
|
||
|
ImGui::TextDisabled("(see Demo->Configuration for details & more)");
|
||
|
ImGui::EndMenu();
|
||
|
}
|
||
|
ImGui::MenuItem("Debug Log", NULL, &demo_data->ShowDebugLog, has_debug_tools);
|
||
|
ImGui::MenuItem("ID Stack Tool", NULL, &demo_data->ShowIDStackTool, has_debug_tools);
|
||
|
bool is_debugger_present = io.ConfigDebugIsDebuggerPresent;
|
||
|
if (ImGui::MenuItem("Item Picker", NULL, false, has_debug_tools && is_debugger_present))
|
||
|
if (ImGui::MenuItem("Item Picker", NULL, false, has_debug_tools))// && is_debugger_present))
|
||
|
ImGui::DebugStartItemPicker();
|
||
|
if (!is_debugger_present)
|
||
|
ImGui::SetItemTooltip("Requires io.ConfigDebugIsDebuggerPresent=true to be set.\n\nWe otherwise disable the menu option to avoid casual users crashing the application.\n\nYou can however always access the Item Picker in Metrics->Tools.");
|
||
|
ImGui::SetItemTooltip("Requires io.ConfigDebugIsDebuggerPresent=true to be set.\n\nWe otherwise disable some extra features to avoid casual users crashing the application.");
|
||
|
ImGui::MenuItem("Style Editor", NULL, &demo_data->ShowStyleEditor);
|
||
|
ImGui::MenuItem("About Dear ImGui", NULL, &demo_data->ShowAbout);
|
||
|
|
||
|
ImGui::SeparatorText("Debug Options");
|
||
|
ImGui::MenuItem("Highlight ID Conflicts", NULL, &io.ConfigDebugHighlightIdConflicts, has_debug_tools);
|
||
|
ImGui::EndMenu();
|
||
|
}
|
||
|
ImGui::EndMenuBar();
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] ShowDemoWindowWidgets()
|
||
|
// [SECTION] Helpers: ExampleTreeNode, ExampleMemberInfo (for use by Property Editor & Multi-Select demos)
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||
|
// Simple representation for a tree
|
||
|
// (this is designed to be simple to understand for our demos, not to be fancy or efficient etc.)
|
||
|
struct ExampleTreeNode
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets");
|
||
|
//ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||
|
if (!ImGui::CollapsingHeader("Widgets"))
|
||
|
return;
|
||
|
// Tree structure
|
||
|
char Name[28] = "";
|
||
|
int UID = 0;
|
||
|
ExampleTreeNode* Parent = NULL;
|
||
|
ImVector<ExampleTreeNode*> Childs;
|
||
|
unsigned short IndexInParent = 0; // Maintaining this allows us to implement linear traversal more easily
|
||
|
|
||
|
static bool disable_all = false; // The Checkbox for that is inside the "Disabled" section at the bottom
|
||
|
if (disable_all)
|
||
|
ImGui::BeginDisabled();
|
||
|
// Leaf Data
|
||
|
bool HasData = false; // All leaves have data
|
||
|
bool DataMyBool = true;
|
||
|
int DataMyInt = 128;
|
||
|
ImVec2 DataMyVec2 = ImVec2(0.0f, 3.141592f);
|
||
|
};
|
||
|
|
||
|
// Simple representation of struct metadata/serialization data.
|
||
|
// (this is a minimal version of what a typical advanced application may provide)
|
||
|
struct ExampleMemberInfo
|
||
|
{
|
||
|
const char* Name; // Member name
|
||
|
ImGuiDataType DataType; // Member type
|
||
|
int DataCount; // Member count (1 when scalar)
|
||
|
int Offset; // Offset inside parent structure
|
||
|
};
|
||
|
|
||
|
// Metadata description of ExampleTreeNode struct.
|
||
|
static const ExampleMemberInfo ExampleTreeNodeMemberInfos[]
|
||
|
{
|
||
|
{ "MyName", ImGuiDataType_String, 1, offsetof(ExampleTreeNode, Name) },
|
||
|
{ "MyBool", ImGuiDataType_Bool, 1, offsetof(ExampleTreeNode, DataMyBool) },
|
||
|
{ "MyInt", ImGuiDataType_S32, 1, offsetof(ExampleTreeNode, DataMyInt) },
|
||
|
{ "MyVec2", ImGuiDataType_Float, 2, offsetof(ExampleTreeNode, DataMyVec2) },
|
||
|
};
|
||
|
|
||
|
static ExampleTreeNode* ExampleTree_CreateNode(const char* name, int uid, ExampleTreeNode* parent)
|
||
|
{
|
||
|
ExampleTreeNode* node = IM_NEW(ExampleTreeNode);
|
||
|
snprintf(node->Name, IM_ARRAYSIZE(node->Name), "%s", name);
|
||
|
node->UID = uid;
|
||
|
node->Parent = parent;
|
||
|
node->IndexInParent = parent ? (unsigned short)parent->Childs.Size : 0;
|
||
|
if (parent)
|
||
|
parent->Childs.push_back(node);
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
static void ExampleTree_DestroyNode(ExampleTreeNode* node)
|
||
|
{
|
||
|
for (ExampleTreeNode* child_node : node->Childs)
|
||
|
ExampleTree_DestroyNode(child_node);
|
||
|
IM_DELETE(node);
|
||
|
}
|
||
|
|
||
|
// Create example tree data
|
||
|
// (this allocates _many_ more times than most other code in either Dear ImGui or others demo)
|
||
|
static ExampleTreeNode* ExampleTree_CreateDemoTree()
|
||
|
{
|
||
|
static const char* root_names[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pear", "Pineapple", "Strawberry", "Watermelon" };
|
||
|
const size_t NAME_MAX_LEN = sizeof(ExampleTreeNode::Name);
|
||
|
char name_buf[NAME_MAX_LEN];
|
||
|
int uid = 0;
|
||
|
ExampleTreeNode* node_L0 = ExampleTree_CreateNode("<ROOT>", ++uid, NULL);
|
||
|
const int root_items_multiplier = 2;
|
||
|
for (int idx_L0 = 0; idx_L0 < IM_ARRAYSIZE(root_names) * root_items_multiplier; idx_L0++)
|
||
|
{
|
||
|
snprintf(name_buf, IM_ARRAYSIZE(name_buf), "%s %d", root_names[idx_L0 / root_items_multiplier], idx_L0 % root_items_multiplier);
|
||
|
ExampleTreeNode* node_L1 = ExampleTree_CreateNode(name_buf, ++uid, node_L0);
|
||
|
const int number_of_childs = (int)strlen(node_L1->Name);
|
||
|
for (int idx_L1 = 0; idx_L1 < number_of_childs; idx_L1++)
|
||
|
{
|
||
|
snprintf(name_buf, IM_ARRAYSIZE(name_buf), "Child %d", idx_L1);
|
||
|
ExampleTreeNode* node_L2 = ExampleTree_CreateNode(name_buf, ++uid, node_L1);
|
||
|
node_L2->HasData = true;
|
||
|
if (idx_L1 == 0)
|
||
|
{
|
||
|
snprintf(name_buf, IM_ARRAYSIZE(name_buf), "Sub-child %d", 0);
|
||
|
ExampleTreeNode* node_L3 = ExampleTree_CreateNode(name_buf, ++uid, node_L2);
|
||
|
node_L3->HasData = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return node_L0;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] DemoWindowWidgetsBasic()
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
static void DemoWindowWidgetsBasic()
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets/Basic");
|
||
|
if (ImGui::TreeNode("Basic"))
|
||
|
{
|
||
| ... | ... | |
|
ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine();
|
||
|
ImGui::RadioButton("radio c", &e, 2);
|
||
|
|
||
|
ImGui::AlignTextToFramePadding();
|
||
|
ImGui::TextLinkOpenURL("Hyperlink", "https://github.com/ocornut/imgui/wiki/Error-Handling");
|
||
|
|
||
|
// Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style.
|
||
|
IMGUI_DEMO_MARKER("Widgets/Basic/Buttons (Colored)");
|
||
|
for (int i = 0; i < 7; i++)
|
||
| ... | ... | |
|
ImGui::SeparatorText("Inputs");
|
||
|
|
||
|
{
|
||
|
// To wire InputText() with std::string or any other custom string type,
|
||
|
// see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file.
|
||
|
// If you want to use InputText() with std::string or any custom dynamic string type:
|
||
|
// - For std::string: use the wrapper in misc/cpp/imgui_stdlib.h/.cpp
|
||
|
// - Otherwise, see the 'Dear ImGui Demo->Widgets->Text Input->Resize Callback' for using ImGuiInputTextFlags_CallbackResize.
|
||
|
IMGUI_DEMO_MARKER("Widgets/Basic/InputText");
|
||
|
static char str0[128] = "Hello, world!";
|
||
|
ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0));
|
||
|
ImGui::SameLine(); HelpMarker(
|
||
|
"USER:\n"
|
||
|
"Hold SHIFT or use mouse to select text.\n"
|
||
|
"CTRL+Left/Right to word jump.\n"
|
||
|
"CTRL+A or Double-Click to select all.\n"
|
||
|
"CTRL+X,CTRL+C,CTRL+V clipboard.\n"
|
||
|
"CTRL+Z,CTRL+Y undo/redo.\n"
|
||
|
"ESCAPE to revert.\n\n"
|
||
|
"Hold Shift or use mouse to select text.\n"
|
||
|
"Ctrl+Left/Right to word jump.\n"
|
||
|
"Ctrl+A or Double-Click to select all.\n"
|
||
|
"Ctrl+X,Ctrl+C,Ctrl+V for clipboard.\n"
|
||
|
"Ctrl+Z to undo, Ctrl+Y/Ctrl+Shift+Z to redo.\n"
|
||
|
"Escape to revert.\n\n"
|
||
|
"PROGRAMMER:\n"
|
||
|
"You 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 "
|
||
| ... | ... | |
|
ImGui::DragInt("drag int", &i1, 1);
|
||
|
ImGui::SameLine(); HelpMarker(
|
||
|
"Click and drag to edit value.\n"
|
||
|
"Hold SHIFT/ALT for faster/slower edit.\n"
|
||
|
"Double-click or CTRL+click to input value.");
|
||
|
"Hold Shift/Alt for faster/slower edit.\n"
|
||
|
"Double-Click or Ctrl+Click to input value.");
|
||
|
ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp);
|
||
|
ImGui::DragInt("drag int wrap 100..200", &i3, 1, 100, 200, "%d", ImGuiSliderFlags_WrapAround);
|
||
|
|
||
| ... | ... | |
|
IMGUI_DEMO_MARKER("Widgets/Basic/SliderInt, SliderFloat");
|
||
|
static int i1 = 0;
|
||
|
ImGui::SliderInt("slider int", &i1, -1, 3);
|
||
|
ImGui::SameLine(); HelpMarker("CTRL+click to input value.");
|
||
|
ImGui::SameLine(); HelpMarker("Ctrl+Click to input value.");
|
||
|
|
||
|
static float f1 = 0.123f, f2 = 0.0f;
|
||
|
ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f");
|
||
| ... | ... | |
|
static int elem = Element_Fire;
|
||
|
const char* elems_names[Element_COUNT] = { "Fire", "Earth", "Air", "Water" };
|
||
|
const char* elem_name = (elem >= 0 && elem < Element_COUNT) ? elems_names[elem] : "Unknown";
|
||
|
ImGui::SliderInt("slider enum", &elem, 0, Element_COUNT - 1, elem_name); // Use ImGuiSliderFlags_NoInput flag to disable CTRL+Click here.
|
||
|
ImGui::SliderInt("slider enum", &elem, 0, Element_COUNT - 1, elem_name); // Use ImGuiSliderFlags_NoInput flag to disable Ctrl+Click here.
|
||
|
ImGui::SameLine(); HelpMarker("Using the format string parameter to display a name instead of the underlying integer.");
|
||
|
}
|
||
|
|
||
| ... | ... | |
|
ImGui::SameLine(); HelpMarker(
|
||
|
"Click on the color square to open a color picker.\n"
|
||
|
"Click and hold to use drag and drop.\n"
|
||
|
"Right-click on the color square to show options.\n"
|
||
|
"CTRL+click on individual component to input value.\n");
|
||
|
"Right-Click on the color square to show options.\n"
|
||
|
"Ctrl+Click on individual component to input value.\n");
|
||
|
|
||
|
ImGui::ColorEdit4("color 2", col2);
|
||
|
}
|
||
| ... | ... | |
|
"Refer to the \"List boxes\" section below for an explanation of how to use the more flexible and general BeginListBox/EndListBox API.");
|
||
|
}
|
||
|
|
||
|
// Testing ImGuiOnceUponAFrame helper.
|
||
|
//static ImGuiOnceUponAFrame once;
|
||
|
//for (int i = 0; i < 5; i++)
|
||
|
// if (once)
|
||
|
// ImGui::Text("This will be displayed only once.");
|
||
|
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Tooltips");
|
||
|
if (ImGui::TreeNode("Tooltips"))
|
||
|
{
|
||
|
// Tooltips are windows following the mouse. They do not take focus away.
|
||
|
ImGui::SeparatorText("General");
|
||
|
|
||
|
// Typical use cases:
|
||
|
// - Short-form (text only): SetItemTooltip("Hello");
|
||
|
// - Short-form (any contents): if (BeginItemTooltip()) { Text("Hello"); EndTooltip(); }
|
||
|
|
||
|
// - Full-form (text only): if (IsItemHovered(...)) { SetTooltip("Hello"); }
|
||
|
// - Full-form (any contents): if (IsItemHovered(...) && BeginTooltip()) { Text("Hello"); EndTooltip(); }
|
||
|
|
||
|
HelpMarker(
|
||
|
"Tooltip are typically created by using a IsItemHovered() + SetTooltip() sequence.\n\n"
|
||
|
"We provide a helper SetItemTooltip() function to perform the two with standards flags.");
|
||
|
|
||
|
ImVec2 sz = ImVec2(-FLT_MIN, 0.0f);
|
||
|
|
||
|
ImGui::Button("Basic", sz);
|
||
|
ImGui::SetItemTooltip("I am a tooltip");
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] DemoWindowWidgetsBullets()
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
ImGui::Button("Fancy", sz);
|
||
|
if (ImGui::BeginItemTooltip())
|
||
|
static void DemoWindowWidgetsBullets()
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets/Bullets");
|
||
|
if (ImGui::TreeNode("Bullets"))
|
||
|
{
|
||
|
ImGui::BulletText("Bullet point 1");
|
||
|
ImGui::BulletText("Bullet point 2\nOn multiple lines");
|
||
|
if (ImGui::TreeNode("Tree node"))
|
||
|
{
|
||
|
ImGui::Text("I am a fancy tooltip");
|
||
|
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
|
||
|
ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr));
|
||
|
ImGui::Text("Sin(time) = %f", sinf((float)ImGui::GetTime()));
|
||
|
ImGui::EndTooltip();
|
||
|
ImGui::BulletText("Another bullet point");
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)");
|
||
|
ImGui::Bullet(); ImGui::SmallButton("Button");
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ImGui::SeparatorText("Always On");
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] DemoWindowWidgetsCollapsingHeaders()
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
// Showcase NOT relying on a IsItemHovered() to emit a tooltip.
|
||
|
// Here the tooltip is always emitted when 'always_on == true'.
|
||
|
static int always_on = 0;
|
||
|
ImGui::RadioButton("Off", &always_on, 0);
|
||
|
ImGui::SameLine();
|
||
|
ImGui::RadioButton("Always On (Simple)", &always_on, 1);
|
||
|
ImGui::SameLine();
|
||
|
ImGui::RadioButton("Always On (Advanced)", &always_on, 2);
|
||
|
if (always_on == 1)
|
||
|
ImGui::SetTooltip("I am following you around.");
|
||
|
else if (always_on == 2 && ImGui::BeginTooltip())
|
||
|
static void DemoWindowWidgetsCollapsingHeaders()
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets/Collapsing Headers");
|
||
|
if (ImGui::TreeNode("Collapsing Headers"))
|
||
|
{
|
||
|
static bool closable_group = true;
|
||
|
ImGui::Checkbox("Show 2nd header", &closable_group);
|
||
|
if (ImGui::CollapsingHeader("Header", ImGuiTreeNodeFlags_None))
|
||
|
{
|
||
|
ImGui::ProgressBar(sinf((float)ImGui::GetTime()) * 0.5f + 0.5f, ImVec2(ImGui::GetFontSize() * 25, 0.0f));
|
||
|
ImGui::EndTooltip();
|
||
|
ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
|
||
|
for (int i = 0; i < 5; i++)
|
||
|
ImGui::Text("Some content %d", i);
|
||
|
}
|
||
|
if (ImGui::CollapsingHeader("Header with a close button", &closable_group))
|
||
|
{
|
||
|
ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
|
||
|
for (int i = 0; i < 5; i++)
|
||
|
ImGui::Text("More content %d", i);
|
||
|
}
|
||
|
/*
|
||
|
if (ImGui::CollapsingHeader("Header with a bullet", ImGuiTreeNodeFlags_Bullet))
|
||
|
ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
|
||
|
*/
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ImGui::SeparatorText("Custom");
|
||
|
|
||
|
HelpMarker(
|
||
|
"Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() is the preferred way to standardize"
|
||
|
"tooltip activation details across your application. You may however decide to use custom"
|
||
|
"flags for a specific tooltip instance.");
|
||
|
|
||
|
// The following examples are passed for documentation purpose but may not be useful to most users.
|
||
|
// Passing ImGuiHoveredFlags_ForTooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from
|
||
|
// 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or keyboard/gamepad is being used.
|
||
|
// With default settings, ImGuiHoveredFlags_ForTooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary.
|
||
|
ImGui::Button("Manual", sz);
|
||
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
||
|
ImGui::SetTooltip("I am a manually emitted tooltip.");
|
||
|
|
||
|
ImGui::Button("DelayNone", sz);
|
||
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNone))
|
||
|
ImGui::SetTooltip("I am a tooltip with no delay.");
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] DemoWindowWidgetsColorAndPickers()
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
ImGui::Button("DelayShort", sz);
|
||
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_NoSharedDelay))
|
||
|
ImGui::SetTooltip("I am a tooltip with a short delay (%0.2f sec).", ImGui::GetStyle().HoverDelayShort);
|
||
|
static void DemoWindowWidgetsColorAndPickers()
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets/Color");
|
||
|
if (ImGui::TreeNode("Color/Picker Widgets"))
|
||
|
{
|
||
|
static ImVec4 color = ImVec4(114.0f / 255.0f, 144.0f / 255.0f, 154.0f / 255.0f, 200.0f / 255.0f);
|
||
|
static ImGuiColorEditFlags base_flags = ImGuiColorEditFlags_None;
|
||
|
|
||
|
ImGui::Button("DelayLong", sz);
|
||
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay))
|
||
|
ImGui::SetTooltip("I am a tooltip with a long delay (%0.2f sec).", ImGui::GetStyle().HoverDelayNormal);
|
||
|
ImGui::SeparatorText("Options");
|
||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoAlpha", &base_flags, ImGuiColorEditFlags_NoAlpha);
|
||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaOpaque", &base_flags, ImGuiColorEditFlags_AlphaOpaque);
|
||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaNoBg", &base_flags, ImGuiColorEditFlags_AlphaNoBg);
|
||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaPreviewHalf", &base_flags, ImGuiColorEditFlags_AlphaPreviewHalf);
|
||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoDragDrop", &base_flags, ImGuiColorEditFlags_NoDragDrop);
|
||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoOptions", &base_flags, ImGuiColorEditFlags_NoOptions); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options.");
|
||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_HDR", &base_flags, ImGuiColorEditFlags_HDR); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
|
||
|
|
||
|
ImGui::Button("Stationary", sz);
|
||
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary))
|
||
|
ImGui::SetTooltip("I am a tooltip requiring mouse to be stationary before activating.");
|
||
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit");
|
||
|
ImGui::SeparatorText("Inline color editor");
|
||
|
ImGui::Text("Color widget:");
|
||
|
ImGui::SameLine(); HelpMarker(
|
||
|
"Click on the color square to open a color picker.\n"
|
||
|
"Ctrl+Click on individual component to input value.\n");
|
||
|
ImGui::ColorEdit3("MyColor##1", (float*)&color, base_flags);
|
||
|
|
||
|
// Using ImGuiHoveredFlags_ForTooltip will pull flags from 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav',
|
||
|
// which default value include the ImGuiHoveredFlags_AllowWhenDisabled flag.
|
||
|
ImGui::BeginDisabled();
|
||
|
ImGui::Button("Disabled item", sz);
|
||
|
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
||
|
ImGui::SetTooltip("I am a a tooltip for a disabled item.");
|
||
|
ImGui::EndDisabled();
|
||
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (HSV, with Alpha)");
|
||
|
ImGui::Text("Color widget HSV with Alpha:");
|
||
|
ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | base_flags);
|
||
|
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (float display)");
|
||
|
ImGui::Text("Color widget with Float Display:");
|
||
|
ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | base_flags);
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with Picker)");
|
||
|
ImGui::Text("Color button with Picker:");
|
||
|
ImGui::SameLine(); HelpMarker(
|
||
|
"With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\n"
|
||
|
"With the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only "
|
||
|
"be used for the tooltip and picker popup.");
|
||
|
ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | base_flags);
|
||
|
|
||
|
// Testing ImGuiOnceUponAFrame helper.
|
||
|
//static ImGuiOnceUponAFrame once;
|
||
|
//for (int i = 0; i < 5; i++)
|
||
|
// if (once)
|
||
|
// ImGui::Text("This will be displayed only once.");
|
||
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with custom Picker popup)");
|
||
|
ImGui::Text("Color button with Custom Picker Popup:");
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Tree Nodes");
|
||
|
if (ImGui::TreeNode("Tree Nodes"))
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Basic trees");
|
||
|
if (ImGui::TreeNode("Basic trees"))
|
||
|
// Generate a default palette. The palette will persist and can be edited.
|
||
|
static bool saved_palette_init = true;
|
||
|
static ImVec4 saved_palette[32] = {};
|
||
|
if (saved_palette_init)
|
||
|
{
|
||
|
for (int i = 0; i < 5; i++)
|
||
|
for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++)
|
||
|
{
|
||
|
// Use SetNextItemOpen() so set the default state of a node to be open. We could
|
||
|
// also use TreeNodeEx() with the ImGuiTreeNodeFlags_DefaultOpen flag to achieve the same thing!
|
||
|
if (i == 0)
|
||
|
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||
|
|
||
|
// Here we use PushID() to generate a unique base ID, and then the "" used as TreeNode id won't conflict.
|
||
|
// An alternative to using 'PushID() + TreeNode("", ...)' to generate a unique ID is to use 'TreeNode((void*)(intptr_t)i, ...)',
|
||
|
// aka generate a dummy pointer-sized value to be hashed. The demo below uses that technique. Both are fine.
|
||
|
ImGui::PushID(i);
|
||
|
if (ImGui::TreeNode("", "Child %d", i))
|
||
|
{
|
||
|
ImGui::Text("blah blah");
|
||
|
ImGui::SameLine();
|
||
|
if (ImGui::SmallButton("button")) {}
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
ImGui::PopID();
|
||
|
ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f,
|
||
|
saved_palette[n].x, saved_palette[n].y, saved_palette[n].z);
|
||
|
saved_palette[n].w = 1.0f; // Alpha
|
||
|
}
|
||
|
ImGui::TreePop();
|
||
|
saved_palette_init = false;
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Tree Nodes/Advanced, with Selectable nodes");
|
||
|
if (ImGui::TreeNode("Advanced, with Selectable nodes"))
|
||
|
static ImVec4 backup_color;
|
||
|
bool open_popup = ImGui::ColorButton("MyColor##3b", color, base_flags);
|
||
|
ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
|
||
|
open_popup |= ImGui::Button("Palette");
|
||
|
if (open_popup)
|
||
|
{
|
||
|
HelpMarker(
|
||
|
"This is a more typical looking tree with selectable nodes.\n"
|
||
|
"Click to select, CTRL+Click to toggle, click on arrows or double-click to open.");
|
||
|
static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
|
||
|
static bool align_label_with_current_x_position = false;
|
||
|
static bool test_drag_and_drop = false;
|
||
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", &base_flags, ImGuiTreeNodeFlags_OpenOnArrow);
|
||
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
|
||
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node.");
|
||
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth);
|
||
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &base_flags, ImGuiTreeNodeFlags_SpanTextWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin.");
|
||
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &base_flags, ImGuiTreeNodeFlags_SpanAllColumns); ImGui::SameLine(); HelpMarker("For use in Tables only.");
|
||
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_AllowOverlap", &base_flags, ImGuiTreeNodeFlags_AllowOverlap);
|
||
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_Framed", &base_flags, ImGuiTreeNodeFlags_Framed); ImGui::SameLine(); HelpMarker("Draw frame with background (e.g. for CollapsingHeader)");
|
||
|
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_NavLeftJumpsBackHere", &base_flags, ImGuiTreeNodeFlags_NavLeftJumpsBackHere);
|
||
|
ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position);
|
||
|
ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop);
|
||
|
ImGui::Text("Hello!");
|
||
|
if (align_label_with_current_x_position)
|
||
|
ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing());
|
||
|
ImGui::OpenPopup("mypicker");
|
||
|
backup_color = color;
|
||
|
}
|
||
|
if (ImGui::BeginPopup("mypicker"))
|
||
|
{
|
||
|
ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!");
|
||
|
ImGui::Separator();
|
||
|
ImGui::ColorPicker4("##picker", (float*)&color, base_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview);
|
||
|
ImGui::SameLine();
|
||
|
|
||
|
// 'selection_mask' is dumb representation of what may be user-side selection state.
|
||
|
// You may retain selection state inside or outside your objects in whatever format you see fit.
|
||
|
// 'node_clicked' is 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.
|
||
|
static int selection_mask = (1 << 2);
|
||
|
int node_clicked = -1;
|
||
|
for (int i = 0; i < 6; i++)
|
||
|
ImGui::BeginGroup(); // Lock X position
|
||
|
ImGui::Text("Current");
|
||
|
ImGui::ColorButton("##current", color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60, 40));
|
||
|
ImGui::Text("Previous");
|
||
|
if (ImGui::ColorButton("##previous", backup_color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60, 40)))
|
||
|
color = backup_color;
|
||
|
ImGui::Separator();
|
||
|
ImGui::Text("Palette");
|
||
|
for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++)
|
||
|
{
|
||
|
// Disable the default "open on single-click behavior" + set Selected flag according to our selection.
|
||
|
// To alter selection we use IsItemClicked() && !IsItemToggledOpen(), so clicking on an arrow doesn't alter selection.
|
||
|
ImGuiTreeNodeFlags node_flags = base_flags;
|
||
|
const bool is_selected = (selection_mask & (1 << i)) != 0;
|
||
|
if (is_selected)
|
||
|
node_flags |= ImGuiTreeNodeFlags_Selected;
|
||
|
if (i < 3)
|
||
|
{
|
||
|
// Items 0..2 are Tree Node
|
||
|
bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i);
|
||
|
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen())
|
||
|
node_clicked = i;
|
||
|
if (test_drag_and_drop && ImGui::BeginDragDropSource())
|
||
|
{
|
||
|
ImGui::SetDragDropPayload("_TREENODE", NULL, 0);
|
||
|
ImGui::Text("This is a drag and drop source");
|
||
|
ImGui::EndDragDropSource();
|
||
|
}
|
||
|
if (i == 2 && (base_flags & ImGuiTreeNodeFlags_SpanTextWidth))
|
||
|
{
|
||
|
// Item 2 has an additional inline button to help demonstrate SpanTextWidth.
|
||
|
ImGui::SameLine();
|
||
|
if (ImGui::SmallButton("button")) {}
|
||
|
}
|
||
|
if (node_open)
|
||
|
{
|
||
|
ImGui::BulletText("Blah blah\nBlah Blah");
|
||
|
ImGui::SameLine();
|
||
|
ImGui::SmallButton("Button");
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
ImGui::PushID(n);
|
||
|
if ((n % 8) != 0)
|
||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
|
||
|
|
||
|
ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip;
|
||
|
if (ImGui::ColorButton("##palette", saved_palette[n], palette_button_flags, ImVec2(20, 20)))
|
||
|
color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z, color.w); // Preserve alpha!
|
||
|
|
||
|
// Allow user to drop colors into each palette entry. Note that ColorButton() is already a
|
||
|
// drag source by default, unless specifying the ImGuiColorEditFlags_NoDragDrop flag.
|
||
|
if (ImGui::BeginDragDropTarget())
|
||
|
{
|
||
|
// Items 3..5 are Tree Leaves
|
||
|
// The only reason we use TreeNode at all is to allow selection of the leaf. Otherwise we can
|
||
|
// use BulletText() or advance the cursor by GetTreeNodeToLabelSpacing() and call Text().
|
||
|
node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet
|
||
|
ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i);
|
||
|
if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen())
|
||
|
node_clicked = i;
|
||
|
if (test_drag_and_drop && ImGui::BeginDragDropSource())
|
||
|
{
|
||
|
ImGui::SetDragDropPayload("_TREENODE", NULL, 0);
|
||
|
ImGui::Text("This is a drag and drop source");
|
||
|
ImGui::EndDragDropSource();
|
||
|
}
|
||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
|
||
|
memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3);
|
||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
|
||
|
memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4);
|
||
|
ImGui::EndDragDropTarget();
|
||
|
}
|
||
|
|
||
|
ImGui::PopID();
|
||
|
}
|
||
|
if (node_clicked != -1)
|
||
|
{
|
||
|
// Update selection state
|
||
|
// (process outside of tree loop to avoid visual inconsistencies during the clicking frame)
|
||
|
if (ImGui::GetIO().KeyCtrl)
|
||
|
selection_mask ^= (1 << node_clicked); // CTRL+click to toggle
|
||
|
else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, may want to preserve selection when clicking on item that is part of the selection
|
||
|
selection_mask = (1 << node_clicked); // Click to single-select
|
||
|
}
|
||
|
if (align_label_with_current_x_position)
|
||
|
ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing());
|
||
|
ImGui::TreePop();
|
||
|
ImGui::EndGroup();
|
||
|
ImGui::EndPopup();
|
||
|
}
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Collapsing Headers");
|
||
|
if (ImGui::TreeNode("Collapsing Headers"))
|
||
|
{
|
||
|
static bool closable_group = true;
|
||
|
ImGui::Checkbox("Show 2nd header", &closable_group);
|
||
|
if (ImGui::CollapsingHeader("Header", ImGuiTreeNodeFlags_None))
|
||
|
{
|
||
|
ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
|
||
|
for (int i = 0; i < 5; i++)
|
||
|
ImGui::Text("Some content %d", i);
|
||
|
}
|
||
|
if (ImGui::CollapsingHeader("Header with a close button", &closable_group))
|
||
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (simple)");
|
||
|
ImGui::Text("Color button only:");
|
||
|
static bool no_border = false;
|
||
|
ImGui::Checkbox("ImGuiColorEditFlags_NoBorder", &no_border);
|
||
|
ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, base_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80, 80));
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorPicker");
|
||
|
ImGui::SeparatorText("Color picker");
|
||
|
|
||
|
static bool ref_color = false;
|
||
|
static ImVec4 ref_color_v(1.0f, 0.0f, 1.0f, 0.5f);
|
||
|
static int picker_mode = 0;
|
||
|
static int display_mode = 0;
|
||
|
static ImGuiColorEditFlags color_picker_flags = ImGuiColorEditFlags_AlphaBar;
|
||
|
|
||
|
ImGui::PushID("Color picker");
|
||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoAlpha", &color_picker_flags, ImGuiColorEditFlags_NoAlpha);
|
||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaBar", &color_picker_flags, ImGuiColorEditFlags_AlphaBar);
|
||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoSidePreview", &color_picker_flags, ImGuiColorEditFlags_NoSidePreview);
|
||
|
if (color_picker_flags & ImGuiColorEditFlags_NoSidePreview)
|
||
|
{
|
||
|
ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
|
||
|
for (int i = 0; i < 5; i++)
|
||
|
ImGui::Text("More content %d", i);
|
||
|
ImGui::SameLine();
|
||
|
ImGui::Checkbox("With Ref Color", &ref_color);
|
||
|
if (ref_color)
|
||
|
{
|
||
|
ImGui::SameLine();
|
||
|
ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | base_flags);
|
||
|
}
|
||
|
}
|
||
|
/*
|
||
|
if (ImGui::CollapsingHeader("Header with a bullet", ImGuiTreeNodeFlags_Bullet))
|
||
|
ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered());
|
||
|
*/
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Bullets");
|
||
|
if (ImGui::TreeNode("Bullets"))
|
||
|
{
|
||
|
ImGui::BulletText("Bullet point 1");
|
||
|
ImGui::BulletText("Bullet point 2\nOn multiple lines");
|
||
|
if (ImGui::TreeNode("Tree node"))
|
||
|
{
|
||
|
ImGui::BulletText("Another bullet point");
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)");
|
||
|
ImGui::Bullet(); ImGui::SmallButton("Button");
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Text");
|
||
|
if (ImGui::TreeNode("Text"))
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets/Text/Colored Text");
|
||
|
if (ImGui::TreeNode("Colorful Text"))
|
||
|
{
|
||
|
// Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility.
|
||
|
ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Pink");
|
||
|
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Yellow");
|
||
|
ImGui::TextDisabled("Disabled");
|
||
|
ImGui::SameLine(); HelpMarker("The TextDisabled color is stored in ImGuiStyle.");
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0ImGuiColorEditFlags_PickerHueBar\0ImGuiColorEditFlags_PickerHueWheel\0");
|
||
|
ImGui::SameLine(); HelpMarker("When not specified explicitly, user can right-click the picker to change mode.");
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Text/Word Wrapping");
|
||
|
if (ImGui::TreeNode("Word Wrapping"))
|
||
|
{
|
||
|
// Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility.
|
||
|
ImGui::TextWrapped(
|
||
|
"This text should automatically wrap on the edge of the window. The current implementation "
|
||
|
"for text wrapping follows simple rules suitable for English and possibly other languages.");
|
||
|
ImGui::Spacing();
|
||
|
ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0ImGuiColorEditFlags_NoInputs\0ImGuiColorEditFlags_DisplayRGB\0ImGuiColorEditFlags_DisplayHSV\0ImGuiColorEditFlags_DisplayHex\0");
|
||
|
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 on those inputs.\n\nColorPicker defaults to displaying RGB+HSV+Hex "
|
||
|
"if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions().");
|
||
|
|
||
|
static float wrap_width = 200.0f;
|
||
|
ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f");
|
||
|
ImGuiColorEditFlags flags = base_flags | color_picker_flags;
|
||
|
if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar;
|
||
|
if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel;
|
||
|
if (display_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; // Disable all RGB/HSV/Hex displays
|
||
|
if (display_mode == 2) flags |= ImGuiColorEditFlags_DisplayRGB; // Override display mode
|
||
|
if (display_mode == 3) flags |= ImGuiColorEditFlags_DisplayHSV;
|
||
|
if (display_mode == 4) flags |= ImGuiColorEditFlags_DisplayHex;
|
||
|
ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL);
|
||
|
|
||
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||
|
for (int n = 0; n < 2; n++)
|
||
|
{
|
||
|
ImGui::Text("Test paragraph %d:", n);
|
||
|
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||
|
ImVec2 marker_min = ImVec2(pos.x + wrap_width, pos.y);
|
||
|
ImVec2 marker_max = ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight());
|
||
|
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width);
|
||
|
if (n == 0)
|
||
|
ImGui::Text("The lazy dog is a good dog. This paragraph should fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width);
|
||
|
else
|
||
|
ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh");
|
||
|
ImGui::Text("Set defaults in code:");
|
||
|
ImGui::SameLine(); HelpMarker(
|
||
|
"SetColorEditOptions() is designed to allow you to set boot-time default.\n"
|
||
|
"We don't have Push/Pop functions because you can force options on a per-widget basis if needed, "
|
||
|
"and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid "
|
||
|
"encouraging you to persistently save values that aren't forward-compatible.");
|
||
|
if (ImGui::Button("Default: Uint8 + HSV + Hue Bar"))
|
||
|
ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_PickerHueBar);
|
||
|
if (ImGui::Button("Default: Float + HDR + Hue Wheel"))
|
||
|
ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_PickerHueWheel);
|
||
|
|
||
|
// Draw actual text bounding box, following by marker of our expected limit (should not overlap!)
|
||
|
draw_list->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255));
|
||
|
draw_list->AddRectFilled(marker_min, marker_max, IM_COL32(255, 0, 255, 255));
|
||
|
ImGui::PopTextWrapPos();
|
||
|
}
|
||
|
// Always display a small version of both types of pickers
|
||
|
// (that's in order to make it more visible in the demo to people who are skimming quickly through it)
|
||
|
ImGui::Text("Both types:");
|
||
|
float w = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.y) * 0.40f;
|
||
|
ImGui::SetNextItemWidth(w);
|
||
|
ImGui::ColorPicker3("##MyColor##5", (float*)&color, ImGuiColorEditFlags_PickerHueBar | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoAlpha);
|
||
|
ImGui::SameLine();
|
||
|
ImGui::SetNextItemWidth(w);
|
||
|
ImGui::ColorPicker3("##MyColor##6", (float*)&color, ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoAlpha);
|
||
|
ImGui::PopID();
|
||
|
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
// HSV encoded support (to avoid RGB<>HSV round trips and singularities when S==0 or V==0)
|
||
|
static ImVec4 color_hsv(0.23f, 1.0f, 1.0f, 1.0f); // Stored as HSV!
|
||
|
ImGui::Spacing();
|
||
|
ImGui::Text("HSV encoded colors");
|
||
|
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.");
|
||
|
ImGui::Text("Color widget with InputHSV:");
|
||
|
ImGui::ColorEdit4("HSV shown as RGB##1", (float*)&color_hsv, ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float);
|
||
|
ImGui::ColorEdit4("HSV shown as HSV##1", (float*)&color_hsv, ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float);
|
||
|
ImGui::DragFloat4("Raw HSV values", (float*)&color_hsv, 0.01f, 0.0f, 1.0f);
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Text/UTF-8 Text");
|
||
|
if (ImGui::TreeNode("UTF-8 Text"))
|
||
|
{
|
||
|
// UTF-8 test with Japanese characters
|
||
|
// (Needs a suitable font? Try "Google Noto" or "Arial Unicode". See docs/FONTS.md for details.)
|
||
|
// - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8
|
||
|
// - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. in Visual Studio, you
|
||
|
// can save your source files as 'UTF-8 without signature').
|
||
|
// - FOR THIS DEMO FILE ONLY, BECAUSE WE WANT TO SUPPORT OLD COMPILERS, WE ARE *NOT* INCLUDING RAW UTF-8
|
||
|
// CHARACTERS IN THIS SOURCE FILE. Instead we are encoding a few strings with hexadecimal constants.
|
||
|
// Don't do this in your application! Please use u8"text in any language" in your application!
|
||
|
// Note that characters values are preserved even by InputText() if the font cannot be displayed,
|
||
|
// so you can safely copy & paste garbled characters into another application.
|
||
|
ImGui::TextWrapped(
|
||
|
"CJK text will only appear if the font was loaded with the appropriate CJK character ranges. "
|
||
|
"Call io.Fonts->AddFontFromFileTTF() manually to load extra character ranges. "
|
||
|
"Read docs/FONTS.md for details.");
|
||
|
ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)");
|
||
|
ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)");
|
||
|
static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e";
|
||
|
//static char buf[32] = u8"NIHONGO"; // <- this is how you would write it with C++11, using real kanjis
|
||
|
ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf));
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Images");
|
||
|
if (ImGui::TreeNode("Images"))
|
||
|
{
|
||
|
ImGuiIO& io = ImGui::GetIO();
|
||
|
ImGui::TextWrapped(
|
||
|
"Below we are displaying the font texture (which is the only texture we have access to in this demo). "
|
||
|
"Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. "
|
||
|
"Hover the texture for a zoomed view!");
|
||
|
|
||
|
// Below we are displaying the font texture because it is the only texture we have access to inside the demo!
|
||
|
// Remember that ImTextureID is just storage for whatever you want it to be. It is essentially a value that
|
||
|
// will be passed to the rendering backend via the ImDrawCmd structure.
|
||
|
// If you use one of the default imgui_impl_XXXX.cpp rendering backend, they all have comments at the top
|
||
|
// of their respective source file to specify what they expect to be stored in ImTextureID, for example:
|
||
|
// - The imgui_impl_dx11.cpp renderer expect a 'ID3D11ShaderResourceView*' pointer
|
||
|
// - The imgui_impl_opengl3.cpp renderer expect a GLuint OpenGL texture identifier, etc.
|
||
|
// More:
|
||
|
// - 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.
|
||
|
// - You can use ShowMetricsWindow() to inspect the draw data that are being passed to your renderer,
|
||
|
// it will help you debug issues if you are confused about it.
|
||
|
// - Consider using the lower-level ImDrawList::AddImage() API, via ImGui::GetWindowDrawList()->AddImage().
|
||
|
// - Read https://github.com/ocornut/imgui/blob/master/docs/FAQ.md
|
||
|
// - Read https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
|
||
|
ImTextureID my_tex_id = io.Fonts->TexID;
|
||
|
float my_tex_w = (float)io.Fonts->TexWidth;
|
||
|
float my_tex_h = (float)io.Fonts->TexHeight;
|
||
|
{
|
||
|
static bool use_text_color_for_tint = false;
|
||
|
ImGui::Checkbox("Use Text Color for Tint", &use_text_color_for_tint);
|
||
|
ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h);
|
||
|
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||
|
ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left
|
||
|
ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right
|
||
|
ImVec4 tint_col = use_text_color_for_tint ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
|
||
|
ImVec4 border_col = ImGui::GetStyleColorVec4(ImGuiCol_Border);
|
||
|
ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, tint_col, border_col);
|
||
|
if (ImGui::BeginItemTooltip())
|
||
|
{
|
||
|
float region_sz = 32.0f;
|
||
|
float region_x = io.MousePos.x - pos.x - region_sz * 0.5f;
|
||
|
float region_y = io.MousePos.y - pos.y - region_sz * 0.5f;
|
||
|
float zoom = 4.0f;
|
||
|
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; }
|
||
|
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; }
|
||
|
ImGui::Text("Min: (%.2f, %.2f)", region_x, region_y);
|
||
|
ImGui::Text("Max: (%.2f, %.2f)", region_x + region_sz, region_y + region_sz);
|
||
|
ImVec2 uv0 = ImVec2((region_x) / my_tex_w, (region_y) / my_tex_h);
|
||
|
ImVec2 uv1 = ImVec2((region_x + region_sz) / my_tex_w, (region_y + region_sz) / my_tex_h);
|
||
|
ImGui::Image(my_tex_id, ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, tint_col, border_col);
|
||
|
ImGui::EndTooltip();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Images/Textured buttons");
|
||
|
ImGui::TextWrapped("And now some textured buttons..");
|
||
|
static int pressed_count = 0;
|
||
|
for (int i = 0; i < 8; i++)
|
||
|
{
|
||
|
// UV coordinates are often (0.0f, 0.0f) and (1.0f, 1.0f) to display an entire textures.
|
||
|
// Here are trying to display only a 32x32 pixels area of the texture, hence the UV computation.
|
||
|
// Read about UV coordinates here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
|
||
|
ImGui::PushID(i);
|
||
|
if (i > 0)
|
||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(i - 1.0f, i - 1.0f));
|
||
|
ImVec2 size = ImVec2(32.0f, 32.0f); // Size of the image we want to make visible
|
||
|
ImVec2 uv0 = ImVec2(0.0f, 0.0f); // UV coordinates for lower-left
|
||
|
ImVec2 uv1 = ImVec2(32.0f / my_tex_w, 32.0f / my_tex_h); // UV coordinates for (32,32) in our texture
|
||
|
ImVec4 bg_col = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); // Black background
|
||
|
ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint
|
||
|
if (ImGui::ImageButton("", my_tex_id, size, uv0, uv1, bg_col, tint_col))
|
||
|
pressed_count += 1;
|
||
|
if (i > 0)
|
||
|
ImGui::PopStyleVar();
|
||
|
ImGui::PopID();
|
||
|
ImGui::SameLine();
|
||
|
}
|
||
|
ImGui::NewLine();
|
||
|
ImGui::Text("Pressed %d times.", pressed_count);
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] DemoWindowWidgetsComboBoxes()
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
static void DemoWindowWidgetsComboBoxes()
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets/Combo");
|
||
|
if (ImGui::TreeNode("Combo"))
|
||
|
{
|
||
| ... | ... | |
|
|
||
|
// Pass in the preview value visible before opening the combo (it could technically be different contents or not pulled from items[])
|
||
|
const char* combo_preview_value = items[item_selected_idx];
|
||
|
|
||
|
if (ImGui::BeginCombo("combo 1", combo_preview_value, flags))
|
||
|
{
|
||
|
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
|
||
| ... | ... | |
|
ImGui::EndCombo();
|
||
|
}
|
||
|
|
||
|
// Show case embedding a filter using a simple trick: displaying the filter inside combo contents.
|
||
|
// See https://github.com/ocornut/imgui/issues/718 for advanced/esoteric alternatives.
|
||
|
if (ImGui::BeginCombo("combo 2 (w/ filter)", combo_preview_value, flags))
|
||
|
{
|
||
|
static ImGuiTextFilter filter;
|
||
|
if (ImGui::IsWindowAppearing())
|
||
|
{
|
||
|
ImGui::SetKeyboardFocusHere();
|
||
|
filter.Clear();
|
||
|
}
|
||
|
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_F);
|
||
|
filter.Draw("##Filter", -FLT_MIN);
|
||
|
|
||
|
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
|
||
|
{
|
||
|
const bool is_selected = (item_selected_idx == n);
|
||
|
if (filter.PassFilter(items[n]))
|
||
|
if (ImGui::Selectable(items[n], is_selected))
|
||
|
item_selected_idx = n;
|
||
|
}
|
||
|
ImGui::EndCombo();
|
||
|
}
|
||
|
|
||
|
ImGui::Spacing();
|
||
|
ImGui::SeparatorText("One-liner variants");
|
||
|
HelpMarker("Flags above don't apply to this section.");
|
||
|
HelpMarker("The Combo() function is not greatly useful apart from cases were you want to embed all options in a single strings.\nFlags above don't apply to this section.");
|
||
|
|
||
|
// Simplified one-liner Combo() API, using values packed in a single constant string
|
||
|
// This is a convenience for when the selection set is small and known at compile-time.
|
||
|
static int item_current_2 = 0;
|
||
|
ImGui::Combo("combo 2 (one-liner)", &item_current_2, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
|
||
|
ImGui::Combo("combo 3 (one-liner)", &item_current_2, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
|
||
|
|
||
|
// Simplified one-liner Combo() using an array of const char*
|
||
|
// This is not very useful (may obsolete): prefer using BeginCombo()/EndCombo() for full control.
|
||
|
static int item_current_3 = -1; // If the selection isn't within 0..count, Combo won't display a preview
|
||
|
ImGui::Combo("combo 3 (array)", &item_current_3, items, IM_ARRAYSIZE(items));
|
||
|
ImGui::Combo("combo 4 (array)", &item_current_3, items, IM_ARRAYSIZE(items));
|
||
|
|
||
|
// Simplified one-liner Combo() using an accessor function
|
||
|
static int item_current_4 = 0;
|
||
|
ImGui::Combo("combo 4 (function)", &item_current_4, [](void* data, int n) { return ((const char**)data)[n]; }, items, IM_ARRAYSIZE(items));
|
||
|
ImGui::Combo("combo 5 (function)", &item_current_4, [](void* data, int n) { return ((const char**)data)[n]; }, items, IM_ARRAYSIZE(items));
|
||
|
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/List Boxes");
|
||
|
if (ImGui::TreeNode("List boxes"))
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] DemoWindowWidgetsDataTypes()
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
static void DemoWindowWidgetsDataTypes()
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets/Data Types");
|
||
|
if (ImGui::TreeNode("Data Types"))
|
||
|
{
|
||
|
// BeginListBox() is essentially a thin wrapper to using BeginChild()/EndChild()
|
||
|
// using the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
|
||
|
// You may be tempted to simply use BeginChild() directly. However note that BeginChild() requires EndChild()
|
||
|
// to always be called (inconsistent with BeginListBox()/EndListBox()).
|
||
|
// DragScalar/InputScalar/SliderScalar functions allow various data types
|
||
|
// - signed/unsigned
|
||
|
// - 8/16/32/64-bits
|
||
|
// - integer/float/double
|
||
|
// To avoid polluting the public API with all possible combinations, we use the ImGuiDataType enum
|
||
|
// to pass the type, and passing all arguments by pointer.
|
||
|
// This is the reason the test code below creates local variables to hold "zero" "one" etc. for each type.
|
||
|
// In practice, if you frequently use a given type that is not covered by the normal API entry points,
|
||
|
// you can wrap it yourself inside a 1 line function which can take typed argument as value instead of void*,
|
||
|
// and then pass their address to the generic function. For example:
|
||
|
// bool MySliderU64(const char *label, u64* value, u64 min = 0, u64 max = 0, const char* format = "%lld")
|
||
|
// {
|
||
|
// return SliderScalar(label, ImGuiDataType_U64, value, &min, &max, format);
|
||
|
// }
|
||
|
|
||
|
// Using the generic BeginListBox() API, you have full control over how to display the combo contents.
|
||
|
// (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively
|
||
|
// stored in the object itself, etc.)
|
||
|
const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" };
|
||
|
static int item_selected_idx = 0; // Here we store our selected data as an index.
|
||
|
// Setup limits (as helper variables so we can take their address, as explained above)
|
||
|
// Note: SliderScalar() functions have a maximum usable range of half the natural type maximum, hence the /2.
|
||
|
#ifndef LLONG_MIN
|
||
|
ImS64 LLONG_MIN = -9223372036854775807LL - 1;
|
||
|
ImS64 LLONG_MAX = 9223372036854775807LL;
|
||
|
ImU64 ULLONG_MAX = (2ULL * 9223372036854775807LL + 1);
|
||
|
#endif
|
||
|
const char s8_zero = 0, s8_one = 1, s8_fifty = 50, s8_min = -128, s8_max = 127;
|
||
|
const ImU8 u8_zero = 0, u8_one = 1, u8_fifty = 50, u8_min = 0, u8_max = 255;
|
||
|
const short s16_zero = 0, s16_one = 1, s16_fifty = 50, s16_min = -32768, s16_max = 32767;
|
||
|
const ImU16 u16_zero = 0, u16_one = 1, u16_fifty = 50, u16_min = 0, u16_max = 65535;
|
||
|
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;
|
||
|
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;
|
||
|
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;
|
||
|
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;
|
||
|
const float f32_zero = 0.f, f32_one = 1.f, f32_lo_a = -10000000000.0f, f32_hi_a = +10000000000.0f;
|
||
|
const double f64_zero = 0., f64_one = 1., f64_lo_a = -1000000000000000.0, f64_hi_a = +1000000000000000.0;
|
||
|
|
||
|
static bool item_highlight = false;
|
||
|
int item_highlighted_idx = -1; // Here we store our highlighted data as an index.
|
||
|
ImGui::Checkbox("Highlight hovered item in second listbox", &item_highlight);
|
||
|
|
||
|
if (ImGui::BeginListBox("listbox 1"))
|
||
|
{
|
||
|
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
|
||
|
{
|
||
|
const bool is_selected = (item_selected_idx == n);
|
||
|
if (ImGui::Selectable(items[n], is_selected))
|
||
|
item_selected_idx = n;
|
||
|
// State
|
||
|
static char s8_v = 127;
|
||
|
static ImU8 u8_v = 255;
|
||
|
static short s16_v = 32767;
|
||
|
static ImU16 u16_v = 65535;
|
||
|
static ImS32 s32_v = -1;
|
||
|
static ImU32 u32_v = (ImU32)-1;
|
||
|
static ImS64 s64_v = -1;
|
||
|
static ImU64 u64_v = (ImU64)-1;
|
||
|
static float f32_v = 0.123f;
|
||
|
static double f64_v = 90000.01234567890123456789;
|
||
|
|
||
|
if (item_highlight && ImGui::IsItemHovered())
|
||
|
item_highlighted_idx = n;
|
||
|
const float drag_speed = 0.2f;
|
||
|
static bool drag_clamp = false;
|
||
|
IMGUI_DEMO_MARKER("Widgets/Data Types/Drags");
|
||
|
ImGui::SeparatorText("Drags");
|
||
|
ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp);
|
||
|
ImGui::SameLine(); HelpMarker(
|
||
|
"As with every widget in dear imgui, we never modify values unless there is a user interaction.\n"
|
||
|
"You can override the clamping limits by using Ctrl+Click to input a value.");
|
||
|
ImGui::DragScalar("drag s8", ImGuiDataType_S8, &s8_v, drag_speed, drag_clamp ? &s8_zero : NULL, drag_clamp ? &s8_fifty : NULL);
|
||
|
ImGui::DragScalar("drag u8", ImGuiDataType_U8, &u8_v, drag_speed, drag_clamp ? &u8_zero : NULL, drag_clamp ? &u8_fifty : NULL, "%u ms");
|
||
|
ImGui::DragScalar("drag s16", ImGuiDataType_S16, &s16_v, drag_speed, drag_clamp ? &s16_zero : NULL, drag_clamp ? &s16_fifty : NULL);
|
||
|
ImGui::DragScalar("drag u16", ImGuiDataType_U16, &u16_v, drag_speed, drag_clamp ? &u16_zero : NULL, drag_clamp ? &u16_fifty : NULL, "%u ms");
|
||
|
ImGui::DragScalar("drag s32", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL);
|
||
|
ImGui::DragScalar("drag s32 hex", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL, "0x%08X");
|
||
|
ImGui::DragScalar("drag u32", ImGuiDataType_U32, &u32_v, drag_speed, drag_clamp ? &u32_zero : NULL, drag_clamp ? &u32_fifty : NULL, "%u ms");
|
||
|
ImGui::DragScalar("drag s64", ImGuiDataType_S64, &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL);
|
||
|
ImGui::DragScalar("drag u64", ImGuiDataType_U64, &u64_v, drag_speed, drag_clamp ? &u64_zero : NULL, drag_clamp ? &u64_fifty : NULL);
|
||
|
ImGui::DragScalar("drag float", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f");
|
||
|
ImGui::DragScalar("drag float log", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", ImGuiSliderFlags_Logarithmic);
|
||
|
ImGui::DragScalar("drag double", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, NULL, "%.10f grams");
|
||
|
ImGui::DragScalar("drag double log",ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", ImGuiSliderFlags_Logarithmic);
|
||
|
|
||
|
// Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
|
||
|
if (is_selected)
|
||
|
ImGui::SetItemDefaultFocus();
|
||
|
}
|
||
|
ImGui::EndListBox();
|
||
|
}
|
||
|
ImGui::SameLine(); HelpMarker("Here we are sharing selection state between both boxes.");
|
||
|
IMGUI_DEMO_MARKER("Widgets/Data Types/Sliders");
|
||
|
ImGui::SeparatorText("Sliders");
|
||
|
ImGui::SliderScalar("slider s8 full", ImGuiDataType_S8, &s8_v, &s8_min, &s8_max, "%d");
|
||
|
ImGui::SliderScalar("slider u8 full", ImGuiDataType_U8, &u8_v, &u8_min, &u8_max, "%u");
|
||
|
ImGui::SliderScalar("slider s16 full", ImGuiDataType_S16, &s16_v, &s16_min, &s16_max, "%d");
|
||
|
ImGui::SliderScalar("slider u16 full", ImGuiDataType_U16, &u16_v, &u16_min, &u16_max, "%u");
|
||
|
ImGui::SliderScalar("slider s32 low", ImGuiDataType_S32, &s32_v, &s32_zero, &s32_fifty,"%d");
|
||
|
ImGui::SliderScalar("slider s32 high", ImGuiDataType_S32, &s32_v, &s32_hi_a, &s32_hi_b, "%d");
|
||
|
ImGui::SliderScalar("slider s32 full", ImGuiDataType_S32, &s32_v, &s32_min, &s32_max, "%d");
|
||
|
ImGui::SliderScalar("slider s32 hex", ImGuiDataType_S32, &s32_v, &s32_zero, &s32_fifty, "0x%04X");
|
||
|
ImGui::SliderScalar("slider u32 low", ImGuiDataType_U32, &u32_v, &u32_zero, &u32_fifty,"%u");
|
||
|
ImGui::SliderScalar("slider u32 high", ImGuiDataType_U32, &u32_v, &u32_hi_a, &u32_hi_b, "%u");
|
||
|
ImGui::SliderScalar("slider u32 full", ImGuiDataType_U32, &u32_v, &u32_min, &u32_max, "%u");
|
||
|
ImGui::SliderScalar("slider s64 low", ImGuiDataType_S64, &s64_v, &s64_zero, &s64_fifty,"%" PRId64);
|
||
|
ImGui::SliderScalar("slider s64 high", ImGuiDataType_S64, &s64_v, &s64_hi_a, &s64_hi_b, "%" PRId64);
|
||
|
ImGui::SliderScalar("slider s64 full", ImGuiDataType_S64, &s64_v, &s64_min, &s64_max, "%" PRId64);
|
||
|
ImGui::SliderScalar("slider u64 low", ImGuiDataType_U64, &u64_v, &u64_zero, &u64_fifty,"%" PRIu64 " ms");
|
||
|
ImGui::SliderScalar("slider u64 high", ImGuiDataType_U64, &u64_v, &u64_hi_a, &u64_hi_b, "%" PRIu64 " ms");
|
||
|
ImGui::SliderScalar("slider u64 full", ImGuiDataType_U64, &u64_v, &u64_min, &u64_max, "%" PRIu64 " ms");
|
||
|
ImGui::SliderScalar("slider float low", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one);
|
||
|
ImGui::SliderScalar("slider float low log", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one, "%.10f", ImGuiSliderFlags_Logarithmic);
|
||
|
ImGui::SliderScalar("slider float high", ImGuiDataType_Float, &f32_v, &f32_lo_a, &f32_hi_a, "%e");
|
||
|
ImGui::SliderScalar("slider double low", ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f grams");
|
||
|
ImGui::SliderScalar("slider double low log",ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f", ImGuiSliderFlags_Logarithmic);
|
||
|
ImGui::SliderScalar("slider double high", ImGuiDataType_Double, &f64_v, &f64_lo_a, &f64_hi_a, "%e grams");
|
||
|
|
||
|
// Custom size: use all width, 5 items tall
|
||
|
ImGui::Text("Full-width:");
|
||
|
if (ImGui::BeginListBox("##listbox 2", ImVec2(-FLT_MIN, 5 * ImGui::GetTextLineHeightWithSpacing())))
|
||
|
{
|
||
|
for (int n = 0; n < IM_ARRAYSIZE(items); n++)
|
||
|
{
|
||
|
bool is_selected = (item_selected_idx == n);
|
||
|
ImGuiSelectableFlags flags = (item_highlighted_idx == n) ? ImGuiSelectableFlags_Highlight : 0;
|
||
|
if (ImGui::Selectable(items[n], is_selected, flags))
|
||
|
item_selected_idx = n;
|
||
|
ImGui::SeparatorText("Sliders (reverse)");
|
||
|
ImGui::SliderScalar("slider s8 reverse", ImGuiDataType_S8, &s8_v, &s8_max, &s8_min, "%d");
|
||
|
ImGui::SliderScalar("slider u8 reverse", ImGuiDataType_U8, &u8_v, &u8_max, &u8_min, "%u");
|
||
|
ImGui::SliderScalar("slider s32 reverse", ImGuiDataType_S32, &s32_v, &s32_fifty, &s32_zero, "%d");
|
||
|
ImGui::SliderScalar("slider u32 reverse", ImGuiDataType_U32, &u32_v, &u32_fifty, &u32_zero, "%u");
|
||
|
ImGui::SliderScalar("slider s64 reverse", ImGuiDataType_S64, &s64_v, &s64_fifty, &s64_zero, "%" PRId64);
|
||
|
ImGui::SliderScalar("slider u64 reverse", ImGuiDataType_U64, &u64_v, &u64_fifty, &u64_zero, "%" PRIu64 " ms");
|
||
|
|
||
|
// Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
|
||
|
if (is_selected)
|
||
|
ImGui::SetItemDefaultFocus();
|
||
|
}
|
||
|
ImGui::EndListBox();
|
||
|
}
|
||
|
IMGUI_DEMO_MARKER("Widgets/Data Types/Inputs");
|
||
|
static bool inputs_step = true;
|
||
|
static ImGuiInputTextFlags flags = ImGuiInputTextFlags_None;
|
||
|
ImGui::SeparatorText("Inputs");
|
||
|
ImGui::Checkbox("Show step buttons", &inputs_step);
|
||
|
ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
|
||
|
ImGui::CheckboxFlags("ImGuiInputTextFlags_ParseEmptyRefVal", &flags, ImGuiInputTextFlags_ParseEmptyRefVal);
|
||
|
ImGui::CheckboxFlags("ImGuiInputTextFlags_DisplayEmptyRefVal", &flags, ImGuiInputTextFlags_DisplayEmptyRefVal);
|
||
|
ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d", flags);
|
||
|
ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u", flags);
|
||
|
ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d", flags);
|
||
|
ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u", flags);
|
||
|
ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d", flags);
|
||
|
ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%04X", flags);
|
||
|
ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u", flags);
|
||
|
ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X", flags);
|
||
|
ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL, NULL, NULL, flags);
|
||
|
ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL, NULL, NULL, flags);
|
||
|
ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL, NULL, NULL, flags);
|
||
|
ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL, NULL, NULL, flags);
|
||
|
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Selectables");
|
||
|
//ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||
|
if (ImGui::TreeNode("Selectables"))
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] DemoWindowWidgetsDisableBlocks()
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
static void DemoWindowWidgetsDisableBlocks(ImGuiDemoWindowData* demo_data)
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets/Disable Blocks");
|
||
|
if (ImGui::TreeNode("Disable Blocks"))
|
||
|
{
|
||
|
// Selectable() has 2 overloads:
|
||
|
// - The one taking "bool selected" as a read-only selection information.
|
||
|
// When Selectable() has been clicked it returns true and you can alter selection state accordingly.
|
||
|
// - The one taking "bool* p_selected" as a read-write selection information (convenient in some cases)
|
||
|
// The earlier is more flexible, as in real application your selection may be stored in many different ways
|
||
|
// and not necessarily inside a bool value (e.g. in flags within objects, as an external list, etc).
|
||
|
IMGUI_DEMO_MARKER("Widgets/Selectables/Basic");
|
||
|
if (ImGui::TreeNode("Basic"))
|
||
|
{
|
||
|
static bool selection[5] = { false, true, false, false };
|
||
|
ImGui::Selectable("1. I am selectable", &selection[0]);
|
||
|
ImGui::Selectable("2. I am selectable", &selection[1]);
|
||
|
ImGui::Selectable("3. I am selectable", &selection[2]);
|
||
|
if (ImGui::Selectable("4. I am double clickable", selection[3], ImGuiSelectableFlags_AllowDoubleClick))
|
||
|
if (ImGui::IsMouseDoubleClicked(0))
|
||
|
selection[3] = !selection[3];
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
ImGui::Checkbox("Disable entire section above", &demo_data->DisableSections);
|
||
|
ImGui::SameLine(); HelpMarker("Demonstrate using BeginDisabled()/EndDisabled() across other sections.");
|
||
|
ImGui::TreePop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
IMGUI_DEMO_MARKER("Widgets/Selectables/Rendering more items on the same line");
|
||
|
if (ImGui::TreeNode("Rendering more items on the same line"))
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] DemoWindowWidgetsDragAndDrop()
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
static void DemoWindowWidgetsDragAndDrop()
|
||
|
{
|
||
|
IMGUI_DEMO_MARKER("Widgets/Drag and drop");
|
||
|
if (ImGui::TreeNode("Drag and Drop"))
|
||
Update Dear ImGui to version 1.92.5.