|
@@ -256,8 +256,11 @@ static void DemoWindowWidgetsCollapsingHeaders();
|
|
static void DemoWindowWidgetsComboBoxes();
|
|
static void DemoWindowWidgetsComboBoxes();
|
|
static void DemoWindowWidgetsImages();
|
|
static void DemoWindowWidgetsImages();
|
|
static void DemoWindowWidgetsListBoxes();
|
|
static void DemoWindowWidgetsListBoxes();
|
|
|
|
+static void DemoWindowWidgetsPlotting();
|
|
|
|
+static void DemoWindowWidgetsProgressBars();
|
|
static void DemoWindowWidgetsSelectables();
|
|
static void DemoWindowWidgetsSelectables();
|
|
static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_data);
|
|
static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_data);
|
|
|
|
+static void DemoWindowWidgetsTabs();
|
|
static void DemoWindowWidgetsText();
|
|
static void DemoWindowWidgetsText();
|
|
static void DemoWindowWidgetsTextFilter();
|
|
static void DemoWindowWidgetsTextFilter();
|
|
static void DemoWindowWidgetsTextInput();
|
|
static void DemoWindowWidgetsTextInput();
|
|
@@ -825,260 +828,17 @@ static void DemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|
DemoWindowWidgetsComboBoxes();
|
|
DemoWindowWidgetsComboBoxes();
|
|
DemoWindowWidgetsImages();
|
|
DemoWindowWidgetsImages();
|
|
DemoWindowWidgetsListBoxes();
|
|
DemoWindowWidgetsListBoxes();
|
|
|
|
+ DemoWindowWidgetsPlotting();
|
|
|
|
+ DemoWindowWidgetsProgressBars();
|
|
DemoWindowWidgetsSelectables();
|
|
DemoWindowWidgetsSelectables();
|
|
DemoWindowWidgetsSelectionAndMultiSelect(demo_data);
|
|
DemoWindowWidgetsSelectionAndMultiSelect(demo_data);
|
|
|
|
+ DemoWindowWidgetsTabs();
|
|
DemoWindowWidgetsText();
|
|
DemoWindowWidgetsText();
|
|
DemoWindowWidgetsTextFilter();
|
|
DemoWindowWidgetsTextFilter();
|
|
DemoWindowWidgetsTextInput();
|
|
DemoWindowWidgetsTextInput();
|
|
DemoWindowWidgetsTooltips();
|
|
DemoWindowWidgetsTooltips();
|
|
DemoWindowWidgetsTreeNodes();
|
|
DemoWindowWidgetsTreeNodes();
|
|
|
|
|
|
- // Tabs
|
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Tabs");
|
|
|
|
- if (ImGui::TreeNode("Tabs"))
|
|
|
|
- {
|
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Tabs/Basic");
|
|
|
|
- if (ImGui::TreeNode("Basic"))
|
|
|
|
- {
|
|
|
|
- ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
|
|
|
|
- if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
|
|
|
|
- {
|
|
|
|
- if (ImGui::BeginTabItem("Avocado"))
|
|
|
|
- {
|
|
|
|
- ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah");
|
|
|
|
- ImGui::EndTabItem();
|
|
|
|
- }
|
|
|
|
- if (ImGui::BeginTabItem("Broccoli"))
|
|
|
|
- {
|
|
|
|
- ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah");
|
|
|
|
- ImGui::EndTabItem();
|
|
|
|
- }
|
|
|
|
- if (ImGui::BeginTabItem("Cucumber"))
|
|
|
|
- {
|
|
|
|
- ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah");
|
|
|
|
- ImGui::EndTabItem();
|
|
|
|
- }
|
|
|
|
- ImGui::EndTabBar();
|
|
|
|
- }
|
|
|
|
- ImGui::Separator();
|
|
|
|
- ImGui::TreePop();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Tabs/Advanced & Close Button");
|
|
|
|
- if (ImGui::TreeNode("Advanced & Close Button"))
|
|
|
|
- {
|
|
|
|
- // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0).
|
|
|
|
- static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable;
|
|
|
|
- ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", &tab_bar_flags, ImGuiTabBarFlags_Reorderable);
|
|
|
|
- ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs);
|
|
|
|
- ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
|
|
|
|
- ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
|
|
|
|
- ImGui::CheckboxFlags("ImGuiTabBarFlags_DrawSelectedOverline", &tab_bar_flags, ImGuiTabBarFlags_DrawSelectedOverline);
|
|
|
|
- if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0)
|
|
|
|
- tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_;
|
|
|
|
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
|
|
|
|
- tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
|
|
|
|
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
|
|
|
|
- tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
|
|
|
|
-
|
|
|
|
- // Tab Bar
|
|
|
|
- ImGui::AlignTextToFramePadding();
|
|
|
|
- ImGui::Text("Opened:");
|
|
|
|
- const char* names[4] = { "Artichoke", "Beetroot", "Celery", "Daikon" };
|
|
|
|
- static bool opened[4] = { true, true, true, true }; // Persistent user state
|
|
|
|
- for (int n = 0; n < IM_ARRAYSIZE(opened); n++)
|
|
|
|
- {
|
|
|
|
- ImGui::SameLine();
|
|
|
|
- ImGui::Checkbox(names[n], &opened[n]);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Passing a bool* to BeginTabItem() is similar to passing one to Begin():
|
|
|
|
- // the underlying bool will be set to false when the tab is closed.
|
|
|
|
- if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
|
|
|
|
- {
|
|
|
|
- for (int n = 0; n < IM_ARRAYSIZE(opened); n++)
|
|
|
|
- if (opened[n] && ImGui::BeginTabItem(names[n], &opened[n], ImGuiTabItemFlags_None))
|
|
|
|
- {
|
|
|
|
- ImGui::Text("This is the %s tab!", names[n]);
|
|
|
|
- if (n & 1)
|
|
|
|
- ImGui::Text("I am an odd tab.");
|
|
|
|
- ImGui::EndTabItem();
|
|
|
|
- }
|
|
|
|
- ImGui::EndTabBar();
|
|
|
|
- }
|
|
|
|
- ImGui::Separator();
|
|
|
|
- ImGui::TreePop();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Tabs/TabItemButton & Leading-Trailing flags");
|
|
|
|
- if (ImGui::TreeNode("TabItemButton & Leading/Trailing flags"))
|
|
|
|
- {
|
|
|
|
- static ImVector<int> active_tabs;
|
|
|
|
- static int next_tab_id = 0;
|
|
|
|
- if (next_tab_id == 0) // Initialize with some default tabs
|
|
|
|
- for (int i = 0; i < 3; i++)
|
|
|
|
- active_tabs.push_back(next_tab_id++);
|
|
|
|
-
|
|
|
|
- // TabItemButton() and Leading/Trailing flags are distinct features which we will demo together.
|
|
|
|
- // (It is possible to submit regular tabs with Leading/Trailing flags, or TabItemButton tabs without Leading/Trailing flags...
|
|
|
|
- // but they tend to make more sense together)
|
|
|
|
- static bool show_leading_button = true;
|
|
|
|
- static bool show_trailing_button = true;
|
|
|
|
- ImGui::Checkbox("Show Leading TabItemButton()", &show_leading_button);
|
|
|
|
- ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button);
|
|
|
|
-
|
|
|
|
- // Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs
|
|
|
|
- static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown;
|
|
|
|
- ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
|
|
|
|
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
|
|
|
|
- tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
|
|
|
|
- if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
|
|
|
|
- tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
|
|
|
|
-
|
|
|
|
- if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
|
|
|
|
- {
|
|
|
|
- // Demo a Leading TabItemButton(): click the "?" button to open a menu
|
|
|
|
- if (show_leading_button)
|
|
|
|
- if (ImGui::TabItemButton("?", ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_NoTooltip))
|
|
|
|
- ImGui::OpenPopup("MyHelpMenu");
|
|
|
|
- if (ImGui::BeginPopup("MyHelpMenu"))
|
|
|
|
- {
|
|
|
|
- ImGui::Selectable("Hello!");
|
|
|
|
- ImGui::EndPopup();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Demo Trailing Tabs: click the "+" button to add a new tab.
|
|
|
|
- // (In your app you may want to use a font icon instead of the "+")
|
|
|
|
- // We submit it before the regular tabs, but thanks to the ImGuiTabItemFlags_Trailing flag it will always appear at the end.
|
|
|
|
- if (show_trailing_button)
|
|
|
|
- if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip))
|
|
|
|
- active_tabs.push_back(next_tab_id++); // Add new tab
|
|
|
|
-
|
|
|
|
- // Submit our regular tabs
|
|
|
|
- for (int n = 0; n < active_tabs.Size; )
|
|
|
|
- {
|
|
|
|
- bool open = true;
|
|
|
|
- char name[16];
|
|
|
|
- snprintf(name, IM_ARRAYSIZE(name), "%04d", active_tabs[n]);
|
|
|
|
- if (ImGui::BeginTabItem(name, &open, ImGuiTabItemFlags_None))
|
|
|
|
- {
|
|
|
|
- ImGui::Text("This is the %s tab!", name);
|
|
|
|
- ImGui::EndTabItem();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (!open)
|
|
|
|
- active_tabs.erase(active_tabs.Data + n);
|
|
|
|
- else
|
|
|
|
- n++;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ImGui::EndTabBar();
|
|
|
|
- }
|
|
|
|
- ImGui::Separator();
|
|
|
|
- ImGui::TreePop();
|
|
|
|
- }
|
|
|
|
- ImGui::TreePop();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Plot/Graph widgets are not very good.
|
|
|
|
- // Consider using a third-party library such as ImPlot: https://github.com/epezent/implot
|
|
|
|
- // (see others https://github.com/ocornut/imgui/wiki/Useful-Extensions)
|
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Plotting");
|
|
|
|
- if (ImGui::TreeNode("Plotting"))
|
|
|
|
- {
|
|
|
|
- static bool animate = true;
|
|
|
|
- ImGui::Checkbox("Animate", &animate);
|
|
|
|
-
|
|
|
|
- // Plot as lines and plot as histogram
|
|
|
|
- static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
|
|
|
|
- ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr));
|
|
|
|
- ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80.0f));
|
|
|
|
- //ImGui::SameLine(); HelpMarker("Consider using ImPlot instead!");
|
|
|
|
-
|
|
|
|
- // Fill an array of contiguous float values to plot
|
|
|
|
- // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float
|
|
|
|
- // and the sizeof() of your structure in the "stride" parameter.
|
|
|
|
- static float values[90] = {};
|
|
|
|
- static int values_offset = 0;
|
|
|
|
- static double refresh_time = 0.0;
|
|
|
|
- if (!animate || refresh_time == 0.0)
|
|
|
|
- refresh_time = ImGui::GetTime();
|
|
|
|
- while (refresh_time < ImGui::GetTime()) // Create data at fixed 60 Hz rate for the demo
|
|
|
|
- {
|
|
|
|
- static float phase = 0.0f;
|
|
|
|
- values[values_offset] = cosf(phase);
|
|
|
|
- values_offset = (values_offset + 1) % IM_ARRAYSIZE(values);
|
|
|
|
- phase += 0.10f * values_offset;
|
|
|
|
- refresh_time += 1.0f / 60.0f;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Plots can display overlay texts
|
|
|
|
- // (in this example, we will display an average value)
|
|
|
|
- {
|
|
|
|
- float average = 0.0f;
|
|
|
|
- for (int n = 0; n < IM_ARRAYSIZE(values); n++)
|
|
|
|
- average += values[n];
|
|
|
|
- average /= (float)IM_ARRAYSIZE(values);
|
|
|
|
- char overlay[32];
|
|
|
|
- sprintf(overlay, "avg %f", average);
|
|
|
|
- ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, overlay, -1.0f, 1.0f, ImVec2(0, 80.0f));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Use functions to generate output
|
|
|
|
- // FIXME: This is actually VERY awkward because current plot API only pass in indices.
|
|
|
|
- // We probably want an API passing floats and user provide sample rate/count.
|
|
|
|
- struct Funcs
|
|
|
|
- {
|
|
|
|
- static float Sin(void*, int i) { return sinf(i * 0.1f); }
|
|
|
|
- static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; }
|
|
|
|
- };
|
|
|
|
- static int func_type = 0, display_count = 70;
|
|
|
|
- ImGui::SeparatorText("Functions");
|
|
|
|
- ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
|
|
|
- ImGui::Combo("func", &func_type, "Sin\0Saw\0");
|
|
|
|
- ImGui::SameLine();
|
|
|
|
- ImGui::SliderInt("Sample count", &display_count, 1, 400);
|
|
|
|
- float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw;
|
|
|
|
- ImGui::PlotLines("Lines##2", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80));
|
|
|
|
- ImGui::PlotHistogram("Histogram##2", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80));
|
|
|
|
- ImGui::Separator();
|
|
|
|
-
|
|
|
|
- ImGui::Text("Need better plotting and graphing? Consider using ImPlot:");
|
|
|
|
- ImGui::TextLinkOpenURL("https://github.com/epezent/implot");
|
|
|
|
- ImGui::Separator();
|
|
|
|
-
|
|
|
|
- ImGui::TreePop();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Progress Bars");
|
|
|
|
- if (ImGui::TreeNode("Progress Bars"))
|
|
|
|
- {
|
|
|
|
- // Animate a simple progress bar
|
|
|
|
- static float progress = 0.0f, progress_dir = 1.0f;
|
|
|
|
- progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime;
|
|
|
|
- if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; }
|
|
|
|
- if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; }
|
|
|
|
-
|
|
|
|
- // Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width,
|
|
|
|
- // or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth.
|
|
|
|
- ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f));
|
|
|
|
- ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
|
|
- ImGui::Text("Progress Bar");
|
|
|
|
-
|
|
|
|
- float progress_saturated = IM_CLAMP(progress, 0.0f, 1.0f);
|
|
|
|
- char buf[32];
|
|
|
|
- sprintf(buf, "%d/%d", (int)(progress_saturated * 1753), 1753);
|
|
|
|
- ImGui::ProgressBar(progress, ImVec2(0.f, 0.f), buf);
|
|
|
|
-
|
|
|
|
- // Pass an animated negative value, e.g. -1.0f * (float)ImGui::GetTime() is the recommended value.
|
|
|
|
- // Adjust the factor if you want to adjust the animation speed.
|
|
|
|
- ImGui::ProgressBar(-1.0f * (float)ImGui::GetTime(), ImVec2(0.0f, 0.0f), "Searching..");
|
|
|
|
- ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
|
|
- ImGui::Text("Indeterminate");
|
|
|
|
-
|
|
|
|
- ImGui::TreePop();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
IMGUI_DEMO_MARKER("Widgets/Color");
|
|
IMGUI_DEMO_MARKER("Widgets/Color");
|
|
if (ImGui::TreeNode("Color/Picker Widgets"))
|
|
if (ImGui::TreeNode("Color/Picker Widgets"))
|
|
{
|
|
{
|
|
@@ -2455,10 +2215,114 @@ static void DemoWindowWidgetsListBoxes()
|
|
// [SECTION] DemoWindowWidgetsPlotting()
|
|
// [SECTION] DemoWindowWidgetsPlotting()
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
+static void DemoWindowWidgetsPlotting()
|
|
|
|
+{
|
|
|
|
+ // Plot/Graph widgets are not very good.
|
|
|
|
+// Consider using a third-party library such as ImPlot: https://github.com/epezent/implot
|
|
|
|
+// (see others https://github.com/ocornut/imgui/wiki/Useful-Extensions)
|
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Plotting");
|
|
|
|
+ if (ImGui::TreeNode("Plotting"))
|
|
|
|
+ {
|
|
|
|
+ ImGui::Text("Need better plotting and graphing? Consider using ImPlot:");
|
|
|
|
+ ImGui::TextLinkOpenURL("https://github.com/epezent/implot");
|
|
|
|
+ ImGui::Separator();
|
|
|
|
+
|
|
|
|
+ static bool animate = true;
|
|
|
|
+ ImGui::Checkbox("Animate", &animate);
|
|
|
|
+
|
|
|
|
+ // Plot as lines and plot as histogram
|
|
|
|
+ static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
|
|
|
|
+ ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr));
|
|
|
|
+ ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80.0f));
|
|
|
|
+ //ImGui::SameLine(); HelpMarker("Consider using ImPlot instead!");
|
|
|
|
+
|
|
|
|
+ // Fill an array of contiguous float values to plot
|
|
|
|
+ // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float
|
|
|
|
+ // and the sizeof() of your structure in the "stride" parameter.
|
|
|
|
+ static float values[90] = {};
|
|
|
|
+ static int values_offset = 0;
|
|
|
|
+ static double refresh_time = 0.0;
|
|
|
|
+ if (!animate || refresh_time == 0.0)
|
|
|
|
+ refresh_time = ImGui::GetTime();
|
|
|
|
+ while (refresh_time < ImGui::GetTime()) // Create data at fixed 60 Hz rate for the demo
|
|
|
|
+ {
|
|
|
|
+ static float phase = 0.0f;
|
|
|
|
+ values[values_offset] = cosf(phase);
|
|
|
|
+ values_offset = (values_offset + 1) % IM_ARRAYSIZE(values);
|
|
|
|
+ phase += 0.10f * values_offset;
|
|
|
|
+ refresh_time += 1.0f / 60.0f;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Plots can display overlay texts
|
|
|
|
+ // (in this example, we will display an average value)
|
|
|
|
+ {
|
|
|
|
+ float average = 0.0f;
|
|
|
|
+ for (int n = 0; n < IM_ARRAYSIZE(values); n++)
|
|
|
|
+ average += values[n];
|
|
|
|
+ average /= (float)IM_ARRAYSIZE(values);
|
|
|
|
+ char overlay[32];
|
|
|
|
+ sprintf(overlay, "avg %f", average);
|
|
|
|
+ ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, overlay, -1.0f, 1.0f, ImVec2(0, 80.0f));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Use functions to generate output
|
|
|
|
+ // FIXME: This is actually VERY awkward because current plot API only pass in indices.
|
|
|
|
+ // We probably want an API passing floats and user provide sample rate/count.
|
|
|
|
+ struct Funcs
|
|
|
|
+ {
|
|
|
|
+ static float Sin(void*, int i) { return sinf(i * 0.1f); }
|
|
|
|
+ static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; }
|
|
|
|
+ };
|
|
|
|
+ static int func_type = 0, display_count = 70;
|
|
|
|
+ ImGui::SeparatorText("Functions");
|
|
|
|
+ ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
|
|
|
+ ImGui::Combo("func", &func_type, "Sin\0Saw\0");
|
|
|
|
+ ImGui::SameLine();
|
|
|
|
+ ImGui::SliderInt("Sample count", &display_count, 1, 400);
|
|
|
|
+ float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw;
|
|
|
|
+ ImGui::PlotLines("Lines##2", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80));
|
|
|
|
+ ImGui::PlotHistogram("Histogram##2", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80));
|
|
|
|
+
|
|
|
|
+ ImGui::TreePop();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
// [SECTION] DemoWindowWidgetsProgressBars()
|
|
// [SECTION] DemoWindowWidgetsProgressBars()
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
+static void DemoWindowWidgetsProgressBars()
|
|
|
|
+{
|
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Progress Bars");
|
|
|
|
+ if (ImGui::TreeNode("Progress Bars"))
|
|
|
|
+ {
|
|
|
|
+ // Animate a simple progress bar
|
|
|
|
+ static float progress = 0.0f, progress_dir = 1.0f;
|
|
|
|
+ progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime;
|
|
|
|
+ if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; }
|
|
|
|
+ if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; }
|
|
|
|
+
|
|
|
|
+ // Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width,
|
|
|
|
+ // or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth.
|
|
|
|
+ ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f));
|
|
|
|
+ ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
|
|
+ ImGui::Text("Progress Bar");
|
|
|
|
+
|
|
|
|
+ float progress_saturated = IM_CLAMP(progress, 0.0f, 1.0f);
|
|
|
|
+ char buf[32];
|
|
|
|
+ sprintf(buf, "%d/%d", (int)(progress_saturated * 1753), 1753);
|
|
|
|
+ ImGui::ProgressBar(progress, ImVec2(0.f, 0.f), buf);
|
|
|
|
+
|
|
|
|
+ // Pass an animated negative value, e.g. -1.0f * (float)ImGui::GetTime() is the recommended value.
|
|
|
|
+ // Adjust the factor if you want to adjust the animation speed.
|
|
|
|
+ ImGui::ProgressBar(-1.0f * (float)ImGui::GetTime(), ImVec2(0.0f, 0.0f), "Searching..");
|
|
|
|
+ ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
|
|
+ ImGui::Text("Indeterminate");
|
|
|
|
+
|
|
|
|
+ ImGui::TreePop();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
// [SECTION] DemoWindowWidgetsQueryingStatuses()
|
|
// [SECTION] DemoWindowWidgetsQueryingStatuses()
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
@@ -3571,6 +3435,155 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
|
|
// [SECTION] DemoWindowWidgetsTabs()
|
|
// [SECTION] DemoWindowWidgetsTabs()
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
+static void DemoWindowWidgetsTabs()
|
|
|
|
+{
|
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Tabs");
|
|
|
|
+ if (ImGui::TreeNode("Tabs"))
|
|
|
|
+ {
|
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Tabs/Basic");
|
|
|
|
+ if (ImGui::TreeNode("Basic"))
|
|
|
|
+ {
|
|
|
|
+ ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
|
|
|
|
+ if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
|
|
|
|
+ {
|
|
|
|
+ if (ImGui::BeginTabItem("Avocado"))
|
|
|
|
+ {
|
|
|
|
+ ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah");
|
|
|
|
+ ImGui::EndTabItem();
|
|
|
|
+ }
|
|
|
|
+ if (ImGui::BeginTabItem("Broccoli"))
|
|
|
|
+ {
|
|
|
|
+ ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah");
|
|
|
|
+ ImGui::EndTabItem();
|
|
|
|
+ }
|
|
|
|
+ if (ImGui::BeginTabItem("Cucumber"))
|
|
|
|
+ {
|
|
|
|
+ ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah");
|
|
|
|
+ ImGui::EndTabItem();
|
|
|
|
+ }
|
|
|
|
+ ImGui::EndTabBar();
|
|
|
|
+ }
|
|
|
|
+ ImGui::Separator();
|
|
|
|
+ ImGui::TreePop();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Tabs/Advanced & Close Button");
|
|
|
|
+ if (ImGui::TreeNode("Advanced & Close Button"))
|
|
|
|
+ {
|
|
|
|
+ // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0).
|
|
|
|
+ static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable;
|
|
|
|
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", &tab_bar_flags, ImGuiTabBarFlags_Reorderable);
|
|
|
|
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs);
|
|
|
|
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
|
|
|
|
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
|
|
|
|
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_DrawSelectedOverline", &tab_bar_flags, ImGuiTabBarFlags_DrawSelectedOverline);
|
|
|
|
+ if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0)
|
|
|
|
+ tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_;
|
|
|
|
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
|
|
|
|
+ tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
|
|
|
|
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
|
|
|
|
+ tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
|
|
|
|
+
|
|
|
|
+ // Tab Bar
|
|
|
|
+ ImGui::AlignTextToFramePadding();
|
|
|
|
+ ImGui::Text("Opened:");
|
|
|
|
+ const char* names[4] = { "Artichoke", "Beetroot", "Celery", "Daikon" };
|
|
|
|
+ static bool opened[4] = { true, true, true, true }; // Persistent user state
|
|
|
|
+ for (int n = 0; n < IM_ARRAYSIZE(opened); n++)
|
|
|
|
+ {
|
|
|
|
+ ImGui::SameLine();
|
|
|
|
+ ImGui::Checkbox(names[n], &opened[n]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Passing a bool* to BeginTabItem() is similar to passing one to Begin():
|
|
|
|
+ // the underlying bool will be set to false when the tab is closed.
|
|
|
|
+ if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
|
|
|
|
+ {
|
|
|
|
+ for (int n = 0; n < IM_ARRAYSIZE(opened); n++)
|
|
|
|
+ if (opened[n] && ImGui::BeginTabItem(names[n], &opened[n], ImGuiTabItemFlags_None))
|
|
|
|
+ {
|
|
|
|
+ ImGui::Text("This is the %s tab!", names[n]);
|
|
|
|
+ if (n & 1)
|
|
|
|
+ ImGui::Text("I am an odd tab.");
|
|
|
|
+ ImGui::EndTabItem();
|
|
|
|
+ }
|
|
|
|
+ ImGui::EndTabBar();
|
|
|
|
+ }
|
|
|
|
+ ImGui::Separator();
|
|
|
|
+ ImGui::TreePop();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Tabs/TabItemButton & Leading-Trailing flags");
|
|
|
|
+ if (ImGui::TreeNode("TabItemButton & Leading/Trailing flags"))
|
|
|
|
+ {
|
|
|
|
+ static ImVector<int> active_tabs;
|
|
|
|
+ static int next_tab_id = 0;
|
|
|
|
+ if (next_tab_id == 0) // Initialize with some default tabs
|
|
|
|
+ for (int i = 0; i < 3; i++)
|
|
|
|
+ active_tabs.push_back(next_tab_id++);
|
|
|
|
+
|
|
|
|
+ // TabItemButton() and Leading/Trailing flags are distinct features which we will demo together.
|
|
|
|
+ // (It is possible to submit regular tabs with Leading/Trailing flags, or TabItemButton tabs without Leading/Trailing flags...
|
|
|
|
+ // but they tend to make more sense together)
|
|
|
|
+ static bool show_leading_button = true;
|
|
|
|
+ static bool show_trailing_button = true;
|
|
|
|
+ ImGui::Checkbox("Show Leading TabItemButton()", &show_leading_button);
|
|
|
|
+ ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button);
|
|
|
|
+
|
|
|
|
+ // Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs
|
|
|
|
+ static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown;
|
|
|
|
+ ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
|
|
|
|
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
|
|
|
|
+ tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
|
|
|
|
+ if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
|
|
|
|
+ tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
|
|
|
|
+
|
|
|
|
+ if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
|
|
|
|
+ {
|
|
|
|
+ // Demo a Leading TabItemButton(): click the "?" button to open a menu
|
|
|
|
+ if (show_leading_button)
|
|
|
|
+ if (ImGui::TabItemButton("?", ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_NoTooltip))
|
|
|
|
+ ImGui::OpenPopup("MyHelpMenu");
|
|
|
|
+ if (ImGui::BeginPopup("MyHelpMenu"))
|
|
|
|
+ {
|
|
|
|
+ ImGui::Selectable("Hello!");
|
|
|
|
+ ImGui::EndPopup();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Demo Trailing Tabs: click the "+" button to add a new tab.
|
|
|
|
+ // (In your app you may want to use a font icon instead of the "+")
|
|
|
|
+ // We submit it before the regular tabs, but thanks to the ImGuiTabItemFlags_Trailing flag it will always appear at the end.
|
|
|
|
+ if (show_trailing_button)
|
|
|
|
+ if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip))
|
|
|
|
+ active_tabs.push_back(next_tab_id++); // Add new tab
|
|
|
|
+
|
|
|
|
+ // Submit our regular tabs
|
|
|
|
+ for (int n = 0; n < active_tabs.Size; )
|
|
|
|
+ {
|
|
|
|
+ bool open = true;
|
|
|
|
+ char name[16];
|
|
|
|
+ snprintf(name, IM_ARRAYSIZE(name), "%04d", active_tabs[n]);
|
|
|
|
+ if (ImGui::BeginTabItem(name, &open, ImGuiTabItemFlags_None))
|
|
|
|
+ {
|
|
|
|
+ ImGui::Text("This is the %s tab!", name);
|
|
|
|
+ ImGui::EndTabItem();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!open)
|
|
|
|
+ active_tabs.erase(active_tabs.Data + n);
|
|
|
|
+ else
|
|
|
|
+ n++;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ImGui::EndTabBar();
|
|
|
|
+ }
|
|
|
|
+ ImGui::Separator();
|
|
|
|
+ ImGui::TreePop();
|
|
|
|
+ }
|
|
|
|
+ ImGui::TreePop();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
// [SECTION] DemoWindowWidgetsText()
|
|
// [SECTION] DemoWindowWidgetsText()
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|