|
@@ -256,8 +256,11 @@ static void DemoWindowWidgetsCollapsingHeaders();
|
|
|
static void DemoWindowWidgetsComboBoxes();
|
|
|
static void DemoWindowWidgetsImages();
|
|
|
static void DemoWindowWidgetsListBoxes();
|
|
|
+static void DemoWindowWidgetsSelectables();
|
|
|
static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_data);
|
|
|
static void DemoWindowWidgetsText();
|
|
|
+static void DemoWindowWidgetsTextFilter();
|
|
|
+static void DemoWindowWidgetsTextInput();
|
|
|
static void DemoWindowWidgetsTooltips();
|
|
|
static void DemoWindowWidgetsTreeNodes();
|
|
|
static void DemoWindowLayout();
|
|
@@ -822,347 +825,14 @@ static void DemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|
|
DemoWindowWidgetsComboBoxes();
|
|
|
DemoWindowWidgetsImages();
|
|
|
DemoWindowWidgetsListBoxes();
|
|
|
+ DemoWindowWidgetsSelectables();
|
|
|
+ DemoWindowWidgetsSelectionAndMultiSelect(demo_data);
|
|
|
DemoWindowWidgetsText();
|
|
|
+ DemoWindowWidgetsTextFilter();
|
|
|
+ DemoWindowWidgetsTextInput();
|
|
|
DemoWindowWidgetsTooltips();
|
|
|
DemoWindowWidgetsTreeNodes();
|
|
|
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Selectables");
|
|
|
- //ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
|
|
- if (ImGui::TreeNode("Selectables"))
|
|
|
- {
|
|
|
- // 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_DEMO_MARKER("Widgets/Selectables/Rendering more items on the same line");
|
|
|
- if (ImGui::TreeNode("Rendering more items on the same line"))
|
|
|
- {
|
|
|
- // (1) Using SetNextItemAllowOverlap()
|
|
|
- // (2) Using the Selectable() override that takes "bool* p_selected" parameter, the bool value is toggled automatically.
|
|
|
- static bool selected[3] = { false, false, false };
|
|
|
- ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(); ImGui::SmallButton("Link 1");
|
|
|
- ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(); ImGui::SmallButton("Link 2");
|
|
|
- ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(); ImGui::SmallButton("Link 3");
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Selectables/In Tables");
|
|
|
- if (ImGui::TreeNode("In Tables"))
|
|
|
- {
|
|
|
- static bool selected[10] = {};
|
|
|
-
|
|
|
- if (ImGui::BeginTable("split1", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders))
|
|
|
- {
|
|
|
- for (int i = 0; i < 10; i++)
|
|
|
- {
|
|
|
- char label[32];
|
|
|
- sprintf(label, "Item %d", i);
|
|
|
- ImGui::TableNextColumn();
|
|
|
- ImGui::Selectable(label, &selected[i]); // FIXME-TABLE: Selection overlap
|
|
|
- }
|
|
|
- ImGui::EndTable();
|
|
|
- }
|
|
|
- ImGui::Spacing();
|
|
|
- if (ImGui::BeginTable("split2", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders))
|
|
|
- {
|
|
|
- for (int i = 0; i < 10; i++)
|
|
|
- {
|
|
|
- char label[32];
|
|
|
- sprintf(label, "Item %d", i);
|
|
|
- ImGui::TableNextRow();
|
|
|
- ImGui::TableNextColumn();
|
|
|
- ImGui::Selectable(label, &selected[i], ImGuiSelectableFlags_SpanAllColumns);
|
|
|
- ImGui::TableNextColumn();
|
|
|
- ImGui::Text("Some other contents");
|
|
|
- ImGui::TableNextColumn();
|
|
|
- ImGui::Text("123456");
|
|
|
- }
|
|
|
- ImGui::EndTable();
|
|
|
- }
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Selectables/Grid");
|
|
|
- if (ImGui::TreeNode("Grid"))
|
|
|
- {
|
|
|
- static char selected[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
|
|
|
-
|
|
|
- // Add in a bit of silly fun...
|
|
|
- const float time = (float)ImGui::GetTime();
|
|
|
- const bool winning_state = memchr(selected, 0, sizeof(selected)) == NULL; // If all cells are selected...
|
|
|
- if (winning_state)
|
|
|
- ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f + 0.5f * cosf(time * 2.0f), 0.5f + 0.5f * sinf(time * 3.0f)));
|
|
|
-
|
|
|
- for (int y = 0; y < 4; y++)
|
|
|
- for (int x = 0; x < 4; x++)
|
|
|
- {
|
|
|
- if (x > 0)
|
|
|
- ImGui::SameLine();
|
|
|
- ImGui::PushID(y * 4 + x);
|
|
|
- if (ImGui::Selectable("Sailor", selected[y][x] != 0, 0, ImVec2(50, 50)))
|
|
|
- {
|
|
|
- // Toggle clicked cell + toggle neighbors
|
|
|
- selected[y][x] ^= 1;
|
|
|
- if (x > 0) { selected[y][x - 1] ^= 1; }
|
|
|
- if (x < 3) { selected[y][x + 1] ^= 1; }
|
|
|
- if (y > 0) { selected[y - 1][x] ^= 1; }
|
|
|
- if (y < 3) { selected[y + 1][x] ^= 1; }
|
|
|
- }
|
|
|
- ImGui::PopID();
|
|
|
- }
|
|
|
-
|
|
|
- if (winning_state)
|
|
|
- ImGui::PopStyleVar();
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Selectables/Alignment");
|
|
|
- if (ImGui::TreeNode("Alignment"))
|
|
|
- {
|
|
|
- HelpMarker(
|
|
|
- "By default, Selectables uses style.SelectableTextAlign but it can be overridden 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");
|
|
|
- static bool selected[3 * 3] = { true, false, true, false, true, false, true, false, true };
|
|
|
- for (int y = 0; y < 3; y++)
|
|
|
- {
|
|
|
- for (int x = 0; x < 3; x++)
|
|
|
- {
|
|
|
- ImVec2 alignment = ImVec2((float)x / 2.0f, (float)y / 2.0f);
|
|
|
- char name[32];
|
|
|
- sprintf(name, "(%.1f,%.1f)", alignment.x, alignment.y);
|
|
|
- if (x > 0) ImGui::SameLine();
|
|
|
- ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, alignment);
|
|
|
- ImGui::Selectable(name, &selected[3 * y + x], ImGuiSelectableFlags_None, ImVec2(80, 80));
|
|
|
- ImGui::PopStyleVar();
|
|
|
- }
|
|
|
- }
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
- DemoWindowWidgetsSelectionAndMultiSelect(demo_data);
|
|
|
-
|
|
|
- // 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.
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Text Input");
|
|
|
- if (ImGui::TreeNode("Text Input"))
|
|
|
- {
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Text Input/Multi-line Text Input");
|
|
|
- if (ImGui::TreeNode("Multi-line Text Input"))
|
|
|
- {
|
|
|
- // Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize
|
|
|
- // and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings.
|
|
|
- static char text[1024 * 16] =
|
|
|
- "/*\n"
|
|
|
- " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n"
|
|
|
- " the hexadecimal encoding of one offending instruction,\n"
|
|
|
- " more formally, the invalid operand with locked CMPXCHG8B\n"
|
|
|
- " instruction bug, is a design flaw in the majority of\n"
|
|
|
- " Intel Pentium, Pentium MMX, and Pentium OverDrive\n"
|
|
|
- " processors (all in the P5 microarchitecture).\n"
|
|
|
- "*/\n\n"
|
|
|
- "label:\n"
|
|
|
- "\tlock cmpxchg8b eax\n";
|
|
|
-
|
|
|
- static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput;
|
|
|
- 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)");
|
|
|
- ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
|
|
|
- ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput);
|
|
|
- ImGui::SameLine(); HelpMarker("When _AllowTabInput is set, passing through the widget with Tabbing doesn't automatically activate it, in order to also cycling through subsequent widgets.");
|
|
|
- ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
|
|
|
- ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags);
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Text Input/Filtered Text Input");
|
|
|
- if (ImGui::TreeNode("Filtered Text Input"))
|
|
|
- {
|
|
|
- struct TextFilters
|
|
|
- {
|
|
|
- // Modify character input by altering 'data->Eventchar' (ImGuiInputTextFlags_CallbackCharFilter callback)
|
|
|
- static int FilterCasingSwap(ImGuiInputTextCallbackData* data)
|
|
|
- {
|
|
|
- if (data->EventChar >= 'a' && data->EventChar <= 'z') { data->EventChar -= 'a' - 'A'; } // Lowercase becomes uppercase
|
|
|
- else if (data->EventChar >= 'A' && data->EventChar <= 'Z') { data->EventChar += 'a' - 'A'; } // Uppercase becomes lowercase
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- // Return 0 (pass) if the character is 'i' or 'm' or 'g' or 'u' or 'i', otherwise return 1 (filter out)
|
|
|
- static int FilterImGuiLetters(ImGuiInputTextCallbackData* data)
|
|
|
- {
|
|
|
- if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar))
|
|
|
- return 0;
|
|
|
- return 1;
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- static char buf1[32] = ""; ImGui::InputText("default", buf1, 32);
|
|
|
- static char buf2[32] = ""; ImGui::InputText("decimal", buf2, 32, ImGuiInputTextFlags_CharsDecimal);
|
|
|
- static char buf3[32] = ""; ImGui::InputText("hexadecimal", buf3, 32, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase);
|
|
|
- static char buf4[32] = ""; ImGui::InputText("uppercase", buf4, 32, ImGuiInputTextFlags_CharsUppercase);
|
|
|
- static char buf5[32] = ""; ImGui::InputText("no blank", buf5, 32, ImGuiInputTextFlags_CharsNoBlank);
|
|
|
- static char buf6[32] = ""; ImGui::InputText("casing swap", buf6, 32, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterCasingSwap); // Use CharFilter callback to replace characters.
|
|
|
- static char buf7[32] = ""; ImGui::InputText("\"imgui\"", buf7, 32, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); // Use CharFilter callback to disable some characters.
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Text Input/Password input");
|
|
|
- if (ImGui::TreeNode("Password Input"))
|
|
|
- {
|
|
|
- static char password[64] = "password123";
|
|
|
- ImGui::InputText("password", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password);
|
|
|
- ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n");
|
|
|
- ImGui::InputTextWithHint("password (w/ hint)", "<password>", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password);
|
|
|
- ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password));
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Text Input/Completion, History, Edit Callbacks");
|
|
|
- if (ImGui::TreeNode("Completion, History, Edit Callbacks"))
|
|
|
- {
|
|
|
- struct Funcs
|
|
|
- {
|
|
|
- static int MyCallback(ImGuiInputTextCallbackData* data)
|
|
|
- {
|
|
|
- if (data->EventFlag == ImGuiInputTextFlags_CallbackCompletion)
|
|
|
- {
|
|
|
- data->InsertChars(data->CursorPos, "..");
|
|
|
- }
|
|
|
- else if (data->EventFlag == ImGuiInputTextFlags_CallbackHistory)
|
|
|
- {
|
|
|
- if (data->EventKey == ImGuiKey_UpArrow)
|
|
|
- {
|
|
|
- data->DeleteChars(0, data->BufTextLen);
|
|
|
- data->InsertChars(0, "Pressed Up!");
|
|
|
- data->SelectAll();
|
|
|
- }
|
|
|
- else if (data->EventKey == ImGuiKey_DownArrow)
|
|
|
- {
|
|
|
- data->DeleteChars(0, data->BufTextLen);
|
|
|
- data->InsertChars(0, "Pressed Down!");
|
|
|
- data->SelectAll();
|
|
|
- }
|
|
|
- }
|
|
|
- else if (data->EventFlag == ImGuiInputTextFlags_CallbackEdit)
|
|
|
- {
|
|
|
- // Toggle casing of first character
|
|
|
- char c = data->Buf[0];
|
|
|
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) data->Buf[0] ^= 32;
|
|
|
- data->BufDirty = true;
|
|
|
-
|
|
|
- // Increment a counter
|
|
|
- int* p_int = (int*)data->UserData;
|
|
|
- *p_int = *p_int + 1;
|
|
|
- }
|
|
|
- return 0;
|
|
|
- }
|
|
|
- };
|
|
|
- static char buf1[64];
|
|
|
- ImGui::InputText("Completion", buf1, 64, ImGuiInputTextFlags_CallbackCompletion, Funcs::MyCallback);
|
|
|
- ImGui::SameLine(); HelpMarker(
|
|
|
- "Here we append \"..\" each time Tab is pressed. "
|
|
|
- "See 'Examples>Console' for a more meaningful demonstration of using this callback.");
|
|
|
-
|
|
|
- static char buf2[64];
|
|
|
- ImGui::InputText("History", buf2, 64, ImGuiInputTextFlags_CallbackHistory, Funcs::MyCallback);
|
|
|
- ImGui::SameLine(); HelpMarker(
|
|
|
- "Here we replace and select text each time Up/Down are pressed. "
|
|
|
- "See 'Examples>Console' for a more meaningful demonstration of using this callback.");
|
|
|
-
|
|
|
- static char buf3[64];
|
|
|
- static int edit_count = 0;
|
|
|
- ImGui::InputText("Edit", buf3, 64, ImGuiInputTextFlags_CallbackEdit, Funcs::MyCallback, (void*)&edit_count);
|
|
|
- ImGui::SameLine(); HelpMarker(
|
|
|
- "Here we toggle the casing of the first character on every edit + count edits.");
|
|
|
- ImGui::SameLine(); ImGui::Text("(%d)", edit_count);
|
|
|
-
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Text Input/Resize Callback");
|
|
|
- if (ImGui::TreeNode("Resize Callback"))
|
|
|
- {
|
|
|
- // To wire InputText() with std::string or any other custom string type,
|
|
|
- // you can use the ImGuiInputTextFlags_CallbackResize flag + create a custom ImGui::InputText() wrapper
|
|
|
- // using your preferred type. See misc/cpp/imgui_stdlib.h for an implementation of this using std::string.
|
|
|
- HelpMarker(
|
|
|
- "Using ImGuiInputTextFlags_CallbackResize to wire your custom string type to InputText().\n\n"
|
|
|
- "See misc/cpp/imgui_stdlib.h for an implementation of this for std::string.");
|
|
|
- struct Funcs
|
|
|
- {
|
|
|
- static int MyResizeCallback(ImGuiInputTextCallbackData* data)
|
|
|
- {
|
|
|
- if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
|
|
|
- {
|
|
|
- ImVector<char>* my_str = (ImVector<char>*)data->UserData;
|
|
|
- IM_ASSERT(my_str->begin() == data->Buf);
|
|
|
- my_str->resize(data->BufSize); // NB: On resizing calls, generally data->BufSize == data->BufTextLen + 1
|
|
|
- data->Buf = my_str->begin();
|
|
|
- }
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- // Note: Because ImGui:: is a namespace you would typically add your own function into the namespace.
|
|
|
- // For example, you code may declare a function 'ImGui::InputText(const char* label, MyString* my_str)'
|
|
|
- static bool MyInputTextMultiline(const char* label, ImVector<char>* my_str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0)
|
|
|
- {
|
|
|
- IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
|
|
|
- return ImGui::InputTextMultiline(label, my_str->begin(), (size_t)my_str->size(), size, flags | ImGuiInputTextFlags_CallbackResize, Funcs::MyResizeCallback, (void*)my_str);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- // For this demo we are using ImVector as a string container.
|
|
|
- // 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.
|
|
|
- static ImVector<char> my_str;
|
|
|
- if (my_str.empty())
|
|
|
- my_str.push_back(0);
|
|
|
- Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16));
|
|
|
- ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity());
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Text Input/Eliding, Alignment");
|
|
|
- if (ImGui::TreeNode("Eliding, Alignment"))
|
|
|
- {
|
|
|
- static char buf1[128] = "/path/to/some/folder/with/long/filename.cpp";
|
|
|
- static ImGuiInputTextFlags flags = ImGuiInputTextFlags_ElideLeft;
|
|
|
- ImGui::CheckboxFlags("ImGuiInputTextFlags_ElideLeft", &flags, ImGuiInputTextFlags_ElideLeft);
|
|
|
- ImGui::InputText("Path", buf1, IM_ARRAYSIZE(buf1), flags);
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Text Input/Miscellaneous");
|
|
|
- if (ImGui::TreeNode("Miscellaneous"))
|
|
|
- {
|
|
|
- static char buf1[16];
|
|
|
- static ImGuiInputTextFlags flags = ImGuiInputTextFlags_EscapeClearsAll;
|
|
|
- ImGui::CheckboxFlags("ImGuiInputTextFlags_EscapeClearsAll", &flags, ImGuiInputTextFlags_EscapeClearsAll);
|
|
|
- ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
|
|
|
- ImGui::CheckboxFlags("ImGuiInputTextFlags_NoUndoRedo", &flags, ImGuiInputTextFlags_NoUndoRedo);
|
|
|
- ImGui::InputText("Hello", buf1, IM_ARRAYSIZE(buf1), flags);
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
// Tabs
|
|
|
IMGUI_DEMO_MARKER("Widgets/Tabs");
|
|
|
if (ImGui::TreeNode("Tabs"))
|
|
@@ -2240,26 +1910,6 @@ static void DemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|
|
ImGui::SameLine(); HelpMarker("Demonstrate using BeginDisabled()/EndDisabled() across this section.");
|
|
|
ImGui::TreePop();
|
|
|
}
|
|
|
-
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Text Filter");
|
|
|
- if (ImGui::TreeNode("Text Filter"))
|
|
|
- {
|
|
|
- // Helper class to easy setup a text filter.
|
|
|
- // You may want to implement a more feature-full filtering scheme in your own application.
|
|
|
- HelpMarker("Not a widget per-se, but ImGuiTextFilter is a helper to perform simple filtering on text strings.");
|
|
|
- static ImGuiTextFilter filter;
|
|
|
- ImGui::Text("Filter usage:\n"
|
|
|
- " \"\" display all lines\n"
|
|
|
- " \"xxx\" display lines containing \"xxx\"\n"
|
|
|
- " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n"
|
|
|
- " \"-xxx\" hide lines containing \"xxx\"");
|
|
|
- filter.Draw();
|
|
|
- const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" };
|
|
|
- for (int i = 0; i < IM_ARRAYSIZE(lines); i++)
|
|
|
- if (filter.PassFilter(lines[i]))
|
|
|
- ImGui::BulletText("%s", lines[i]);
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
@@ -2790,31 +2440,171 @@ static void DemoWindowWidgetsListBoxes()
|
|
|
if (is_selected)
|
|
|
ImGui::SetItemDefaultFocus();
|
|
|
}
|
|
|
- ImGui::EndListBox();
|
|
|
+ ImGui::EndListBox();
|
|
|
+ }
|
|
|
+
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+// [SECTION] DemoWindowWidgetsMultiComponents()
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+// [SECTION] DemoWindowWidgetsPlotting()
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+// [SECTION] DemoWindowWidgetsProgressBars()
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+// [SECTION] DemoWindowWidgetsQueryingStatuses()
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+// [SECTION] DemoWindowWidgetsSelectables()
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+
|
|
|
+static void DemoWindowWidgetsSelectables()
|
|
|
+{
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Selectables");
|
|
|
+ //ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
|
|
+ if (ImGui::TreeNode("Selectables"))
|
|
|
+ {
|
|
|
+ // 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_DEMO_MARKER("Widgets/Selectables/Rendering more items on the same line");
|
|
|
+ if (ImGui::TreeNode("Rendering more items on the same line"))
|
|
|
+ {
|
|
|
+ // (1) Using SetNextItemAllowOverlap()
|
|
|
+ // (2) Using the Selectable() override that takes "bool* p_selected" parameter, the bool value is toggled automatically.
|
|
|
+ static bool selected[3] = { false, false, false };
|
|
|
+ ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(); ImGui::SmallButton("Link 1");
|
|
|
+ ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(); ImGui::SmallButton("Link 2");
|
|
|
+ ImGui::SetNextItemAllowOverlap(); ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(); ImGui::SmallButton("Link 3");
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Selectables/In Tables");
|
|
|
+ if (ImGui::TreeNode("In Tables"))
|
|
|
+ {
|
|
|
+ static bool selected[10] = {};
|
|
|
+
|
|
|
+ if (ImGui::BeginTable("split1", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders))
|
|
|
+ {
|
|
|
+ for (int i = 0; i < 10; i++)
|
|
|
+ {
|
|
|
+ char label[32];
|
|
|
+ sprintf(label, "Item %d", i);
|
|
|
+ ImGui::TableNextColumn();
|
|
|
+ ImGui::Selectable(label, &selected[i]); // FIXME-TABLE: Selection overlap
|
|
|
+ }
|
|
|
+ ImGui::EndTable();
|
|
|
+ }
|
|
|
+ ImGui::Spacing();
|
|
|
+ if (ImGui::BeginTable("split2", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders))
|
|
|
+ {
|
|
|
+ for (int i = 0; i < 10; i++)
|
|
|
+ {
|
|
|
+ char label[32];
|
|
|
+ sprintf(label, "Item %d", i);
|
|
|
+ ImGui::TableNextRow();
|
|
|
+ ImGui::TableNextColumn();
|
|
|
+ ImGui::Selectable(label, &selected[i], ImGuiSelectableFlags_SpanAllColumns);
|
|
|
+ ImGui::TableNextColumn();
|
|
|
+ ImGui::Text("Some other contents");
|
|
|
+ ImGui::TableNextColumn();
|
|
|
+ ImGui::Text("123456");
|
|
|
+ }
|
|
|
+ ImGui::EndTable();
|
|
|
+ }
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Selectables/Grid");
|
|
|
+ if (ImGui::TreeNode("Grid"))
|
|
|
+ {
|
|
|
+ static char selected[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } };
|
|
|
+
|
|
|
+ // Add in a bit of silly fun...
|
|
|
+ const float time = (float)ImGui::GetTime();
|
|
|
+ const bool winning_state = memchr(selected, 0, sizeof(selected)) == NULL; // If all cells are selected...
|
|
|
+ if (winning_state)
|
|
|
+ ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f + 0.5f * cosf(time * 2.0f), 0.5f + 0.5f * sinf(time * 3.0f)));
|
|
|
+
|
|
|
+ for (int y = 0; y < 4; y++)
|
|
|
+ for (int x = 0; x < 4; x++)
|
|
|
+ {
|
|
|
+ if (x > 0)
|
|
|
+ ImGui::SameLine();
|
|
|
+ ImGui::PushID(y * 4 + x);
|
|
|
+ if (ImGui::Selectable("Sailor", selected[y][x] != 0, 0, ImVec2(50, 50)))
|
|
|
+ {
|
|
|
+ // Toggle clicked cell + toggle neighbors
|
|
|
+ selected[y][x] ^= 1;
|
|
|
+ if (x > 0) { selected[y][x - 1] ^= 1; }
|
|
|
+ if (x < 3) { selected[y][x + 1] ^= 1; }
|
|
|
+ if (y > 0) { selected[y - 1][x] ^= 1; }
|
|
|
+ if (y < 3) { selected[y + 1][x] ^= 1; }
|
|
|
+ }
|
|
|
+ ImGui::PopID();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (winning_state)
|
|
|
+ ImGui::PopStyleVar();
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Selectables/Alignment");
|
|
|
+ if (ImGui::TreeNode("Alignment"))
|
|
|
+ {
|
|
|
+ HelpMarker(
|
|
|
+ "By default, Selectables uses style.SelectableTextAlign but it can be overridden 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");
|
|
|
+ static bool selected[3 * 3] = { true, false, true, false, true, false, true, false, true };
|
|
|
+ for (int y = 0; y < 3; y++)
|
|
|
+ {
|
|
|
+ for (int x = 0; x < 3; x++)
|
|
|
+ {
|
|
|
+ ImVec2 alignment = ImVec2((float)x / 2.0f, (float)y / 2.0f);
|
|
|
+ char name[32];
|
|
|
+ sprintf(name, "(%.1f,%.1f)", alignment.x, alignment.y);
|
|
|
+ if (x > 0) ImGui::SameLine();
|
|
|
+ ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, alignment);
|
|
|
+ ImGui::Selectable(name, &selected[3 * y + x], ImGuiSelectableFlags_None, ImVec2(80, 80));
|
|
|
+ ImGui::PopStyleVar();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ImGui::TreePop();
|
|
|
}
|
|
|
-
|
|
|
ImGui::TreePop();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
-// [SECTION] DemoWindowWidgetsMultiComponents()
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// [SECTION] DemoWindowWidgetsPlotting()
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// [SECTION] DemoWindowWidgetsProgressBars()
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// [SECTION] DemoWindowWidgetsQueryingStatuses()
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-
|
|
|
+// [SECTION] DemoWindowWidgetsSelectionAndMultiSelect()
|
|
|
//-----------------------------------------------------------------------------
|
|
|
-// [SECTION] DemoWindowWidgetsSelectables()
|
|
|
+// Multi-selection demos
|
|
|
+// Also read: https://github.com/ocornut/imgui/wiki/Multi-Select
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
static const char* ExampleNames[] =
|
|
@@ -3042,13 +2832,6 @@ struct ExampleDualListBox
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// [SECTION] DemoWindowWidgetsSelectionAndMultiSelect()
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-// Multi-selection demos
|
|
|
-// Also read: https://github.com/ocornut/imgui/wiki/Multi-Select
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-
|
|
|
static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_data)
|
|
|
{
|
|
|
IMGUI_DEMO_MARKER("Widgets/Selection State & Multi-Select");
|
|
@@ -3874,10 +3657,242 @@ static void DemoWindowWidgetsText()
|
|
|
// [SECTION] DemoWindowWidgetsTextFilter()
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
+static void DemoWindowWidgetsTextFilter()
|
|
|
+{
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Text Filter");
|
|
|
+ if (ImGui::TreeNode("Text Filter"))
|
|
|
+ {
|
|
|
+ // Helper class to easy setup a text filter.
|
|
|
+ // You may want to implement a more feature-full filtering scheme in your own application.
|
|
|
+ HelpMarker("Not a widget per-se, but ImGuiTextFilter is a helper to perform simple filtering on text strings.");
|
|
|
+ static ImGuiTextFilter filter;
|
|
|
+ ImGui::Text("Filter usage:\n"
|
|
|
+ " \"\" display all lines\n"
|
|
|
+ " \"xxx\" display lines containing \"xxx\"\n"
|
|
|
+ " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n"
|
|
|
+ " \"-xxx\" hide lines containing \"xxx\"");
|
|
|
+ filter.Draw();
|
|
|
+ const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" };
|
|
|
+ for (int i = 0; i < IM_ARRAYSIZE(lines); i++)
|
|
|
+ if (filter.PassFilter(lines[i]))
|
|
|
+ ImGui::BulletText("%s", lines[i]);
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// [SECTION] DemoWindowWidgetsTextInput()
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
+static void DemoWindowWidgetsTextInput()
|
|
|
+{
|
|
|
+ // 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.
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Text Input");
|
|
|
+ if (ImGui::TreeNode("Text Input"))
|
|
|
+ {
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Text Input/Multi-line Text Input");
|
|
|
+ if (ImGui::TreeNode("Multi-line Text Input"))
|
|
|
+ {
|
|
|
+ // Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize
|
|
|
+ // and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings.
|
|
|
+ static char text[1024 * 16] =
|
|
|
+ "/*\n"
|
|
|
+ " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n"
|
|
|
+ " the hexadecimal encoding of one offending instruction,\n"
|
|
|
+ " more formally, the invalid operand with locked CMPXCHG8B\n"
|
|
|
+ " instruction bug, is a design flaw in the majority of\n"
|
|
|
+ " Intel Pentium, Pentium MMX, and Pentium OverDrive\n"
|
|
|
+ " processors (all in the P5 microarchitecture).\n"
|
|
|
+ "*/\n\n"
|
|
|
+ "label:\n"
|
|
|
+ "\tlock cmpxchg8b eax\n";
|
|
|
+
|
|
|
+ static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput;
|
|
|
+ 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)");
|
|
|
+ ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
|
|
|
+ ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput);
|
|
|
+ ImGui::SameLine(); HelpMarker("When _AllowTabInput is set, passing through the widget with Tabbing doesn't automatically activate it, in order to also cycling through subsequent widgets.");
|
|
|
+ ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
|
|
|
+ ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags);
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Text Input/Filtered Text Input");
|
|
|
+ if (ImGui::TreeNode("Filtered Text Input"))
|
|
|
+ {
|
|
|
+ struct TextFilters
|
|
|
+ {
|
|
|
+ // Modify character input by altering 'data->Eventchar' (ImGuiInputTextFlags_CallbackCharFilter callback)
|
|
|
+ static int FilterCasingSwap(ImGuiInputTextCallbackData* data)
|
|
|
+ {
|
|
|
+ if (data->EventChar >= 'a' && data->EventChar <= 'z') { data->EventChar -= 'a' - 'A'; } // Lowercase becomes uppercase
|
|
|
+ else if (data->EventChar >= 'A' && data->EventChar <= 'Z') { data->EventChar += 'a' - 'A'; } // Uppercase becomes lowercase
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Return 0 (pass) if the character is 'i' or 'm' or 'g' or 'u' or 'i', otherwise return 1 (filter out)
|
|
|
+ static int FilterImGuiLetters(ImGuiInputTextCallbackData* data)
|
|
|
+ {
|
|
|
+ if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar))
|
|
|
+ return 0;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ static char buf1[32] = ""; ImGui::InputText("default", buf1, 32);
|
|
|
+ static char buf2[32] = ""; ImGui::InputText("decimal", buf2, 32, ImGuiInputTextFlags_CharsDecimal);
|
|
|
+ static char buf3[32] = ""; ImGui::InputText("hexadecimal", buf3, 32, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase);
|
|
|
+ static char buf4[32] = ""; ImGui::InputText("uppercase", buf4, 32, ImGuiInputTextFlags_CharsUppercase);
|
|
|
+ static char buf5[32] = ""; ImGui::InputText("no blank", buf5, 32, ImGuiInputTextFlags_CharsNoBlank);
|
|
|
+ static char buf6[32] = ""; ImGui::InputText("casing swap", buf6, 32, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterCasingSwap); // Use CharFilter callback to replace characters.
|
|
|
+ static char buf7[32] = ""; ImGui::InputText("\"imgui\"", buf7, 32, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); // Use CharFilter callback to disable some characters.
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Text Input/Password input");
|
|
|
+ if (ImGui::TreeNode("Password Input"))
|
|
|
+ {
|
|
|
+ static char password[64] = "password123";
|
|
|
+ ImGui::InputText("password", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password);
|
|
|
+ ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n");
|
|
|
+ ImGui::InputTextWithHint("password (w/ hint)", "<password>", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password);
|
|
|
+ ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password));
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Text Input/Completion, History, Edit Callbacks");
|
|
|
+ if (ImGui::TreeNode("Completion, History, Edit Callbacks"))
|
|
|
+ {
|
|
|
+ struct Funcs
|
|
|
+ {
|
|
|
+ static int MyCallback(ImGuiInputTextCallbackData* data)
|
|
|
+ {
|
|
|
+ if (data->EventFlag == ImGuiInputTextFlags_CallbackCompletion)
|
|
|
+ {
|
|
|
+ data->InsertChars(data->CursorPos, "..");
|
|
|
+ }
|
|
|
+ else if (data->EventFlag == ImGuiInputTextFlags_CallbackHistory)
|
|
|
+ {
|
|
|
+ if (data->EventKey == ImGuiKey_UpArrow)
|
|
|
+ {
|
|
|
+ data->DeleteChars(0, data->BufTextLen);
|
|
|
+ data->InsertChars(0, "Pressed Up!");
|
|
|
+ data->SelectAll();
|
|
|
+ }
|
|
|
+ else if (data->EventKey == ImGuiKey_DownArrow)
|
|
|
+ {
|
|
|
+ data->DeleteChars(0, data->BufTextLen);
|
|
|
+ data->InsertChars(0, "Pressed Down!");
|
|
|
+ data->SelectAll();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (data->EventFlag == ImGuiInputTextFlags_CallbackEdit)
|
|
|
+ {
|
|
|
+ // Toggle casing of first character
|
|
|
+ char c = data->Buf[0];
|
|
|
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) data->Buf[0] ^= 32;
|
|
|
+ data->BufDirty = true;
|
|
|
+
|
|
|
+ // Increment a counter
|
|
|
+ int* p_int = (int*)data->UserData;
|
|
|
+ *p_int = *p_int + 1;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ static char buf1[64];
|
|
|
+ ImGui::InputText("Completion", buf1, 64, ImGuiInputTextFlags_CallbackCompletion, Funcs::MyCallback);
|
|
|
+ ImGui::SameLine(); HelpMarker(
|
|
|
+ "Here we append \"..\" each time Tab is pressed. "
|
|
|
+ "See 'Examples>Console' for a more meaningful demonstration of using this callback.");
|
|
|
+
|
|
|
+ static char buf2[64];
|
|
|
+ ImGui::InputText("History", buf2, 64, ImGuiInputTextFlags_CallbackHistory, Funcs::MyCallback);
|
|
|
+ ImGui::SameLine(); HelpMarker(
|
|
|
+ "Here we replace and select text each time Up/Down are pressed. "
|
|
|
+ "See 'Examples>Console' for a more meaningful demonstration of using this callback.");
|
|
|
+
|
|
|
+ static char buf3[64];
|
|
|
+ static int edit_count = 0;
|
|
|
+ ImGui::InputText("Edit", buf3, 64, ImGuiInputTextFlags_CallbackEdit, Funcs::MyCallback, (void*)&edit_count);
|
|
|
+ ImGui::SameLine(); HelpMarker(
|
|
|
+ "Here we toggle the casing of the first character on every edit + count edits.");
|
|
|
+ ImGui::SameLine(); ImGui::Text("(%d)", edit_count);
|
|
|
+
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Text Input/Resize Callback");
|
|
|
+ if (ImGui::TreeNode("Resize Callback"))
|
|
|
+ {
|
|
|
+ // To wire InputText() with std::string or any other custom string type,
|
|
|
+ // you can use the ImGuiInputTextFlags_CallbackResize flag + create a custom ImGui::InputText() wrapper
|
|
|
+ // using your preferred type. See misc/cpp/imgui_stdlib.h for an implementation of this using std::string.
|
|
|
+ HelpMarker(
|
|
|
+ "Using ImGuiInputTextFlags_CallbackResize to wire your custom string type to InputText().\n\n"
|
|
|
+ "See misc/cpp/imgui_stdlib.h for an implementation of this for std::string.");
|
|
|
+ struct Funcs
|
|
|
+ {
|
|
|
+ static int MyResizeCallback(ImGuiInputTextCallbackData* data)
|
|
|
+ {
|
|
|
+ if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
|
|
|
+ {
|
|
|
+ ImVector<char>* my_str = (ImVector<char>*)data->UserData;
|
|
|
+ IM_ASSERT(my_str->begin() == data->Buf);
|
|
|
+ my_str->resize(data->BufSize); // NB: On resizing calls, generally data->BufSize == data->BufTextLen + 1
|
|
|
+ data->Buf = my_str->begin();
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Note: Because ImGui:: is a namespace you would typically add your own function into the namespace.
|
|
|
+ // For example, you code may declare a function 'ImGui::InputText(const char* label, MyString* my_str)'
|
|
|
+ static bool MyInputTextMultiline(const char* label, ImVector<char>* my_str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0)
|
|
|
+ {
|
|
|
+ IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
|
|
|
+ return ImGui::InputTextMultiline(label, my_str->begin(), (size_t)my_str->size(), size, flags | ImGuiInputTextFlags_CallbackResize, Funcs::MyResizeCallback, (void*)my_str);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // For this demo we are using ImVector as a string container.
|
|
|
+ // 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.
|
|
|
+ static ImVector<char> my_str;
|
|
|
+ if (my_str.empty())
|
|
|
+ my_str.push_back(0);
|
|
|
+ Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16));
|
|
|
+ ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity());
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Text Input/Eliding, Alignment");
|
|
|
+ if (ImGui::TreeNode("Eliding, Alignment"))
|
|
|
+ {
|
|
|
+ static char buf1[128] = "/path/to/some/folder/with/long/filename.cpp";
|
|
|
+ static ImGuiInputTextFlags flags = ImGuiInputTextFlags_ElideLeft;
|
|
|
+ ImGui::CheckboxFlags("ImGuiInputTextFlags_ElideLeft", &flags, ImGuiInputTextFlags_ElideLeft);
|
|
|
+ ImGui::InputText("Path", buf1, IM_ARRAYSIZE(buf1), flags);
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Text Input/Miscellaneous");
|
|
|
+ if (ImGui::TreeNode("Miscellaneous"))
|
|
|
+ {
|
|
|
+ static char buf1[16];
|
|
|
+ static ImGuiInputTextFlags flags = ImGuiInputTextFlags_EscapeClearsAll;
|
|
|
+ ImGui::CheckboxFlags("ImGuiInputTextFlags_EscapeClearsAll", &flags, ImGuiInputTextFlags_EscapeClearsAll);
|
|
|
+ ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
|
|
|
+ ImGui::CheckboxFlags("ImGuiInputTextFlags_NoUndoRedo", &flags, ImGuiInputTextFlags_NoUndoRedo);
|
|
|
+ ImGui::InputText("Hello", buf1, IM_ARRAYSIZE(buf1), flags);
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// [SECTION] DemoWindowWidgetsTooltips()
|
|
|
//-----------------------------------------------------------------------------
|