|
@@ -253,6 +253,9 @@ static void DemoWindowWidgets(ImGuiDemoWindowData* demo_data);
|
|
|
static void DemoWindowWidgetsBasic();
|
|
|
static void DemoWindowWidgetsBullets();
|
|
|
static void DemoWindowWidgetsCollapsingHeaders();
|
|
|
+static void DemoWindowWidgetsComboBoxes();
|
|
|
+static void DemoWindowWidgetsImages();
|
|
|
+static void DemoWindowWidgetsListBoxes();
|
|
|
static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_data);
|
|
|
static void DemoWindowWidgetsText();
|
|
|
static void DemoWindowWidgetsTooltips();
|
|
@@ -816,240 +819,13 @@ static void DemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|
|
DemoWindowWidgetsBasic();
|
|
|
DemoWindowWidgetsBullets();
|
|
|
DemoWindowWidgetsCollapsingHeaders();
|
|
|
+ DemoWindowWidgetsComboBoxes();
|
|
|
+ DemoWindowWidgetsImages();
|
|
|
+ DemoWindowWidgetsListBoxes();
|
|
|
DemoWindowWidgetsText();
|
|
|
DemoWindowWidgetsTooltips();
|
|
|
DemoWindowWidgetsTreeNodes();
|
|
|
|
|
|
- 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;
|
|
|
- {
|
|
|
- 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
|
|
|
- ImGui::PushStyleVar(ImGuiStyleVar_ImageBorderSize, IM_MAX(1.0f, ImGui::GetStyle().ImageBorderSize));
|
|
|
- ImGui::ImageWithBg(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
|
|
- 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::ImageWithBg(my_tex_id, ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
|
|
- ImGui::EndTooltip();
|
|
|
- }
|
|
|
- ImGui::PopStyleVar();
|
|
|
- }
|
|
|
-
|
|
|
- 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();
|
|
|
- }
|
|
|
-
|
|
|
- IMGUI_DEMO_MARKER("Widgets/Combo");
|
|
|
- if (ImGui::TreeNode("Combo"))
|
|
|
- {
|
|
|
- // Combo Boxes are also called "Dropdown" in other systems
|
|
|
- // Expose flags as checkbox for the demo
|
|
|
- static ImGuiComboFlags flags = 0;
|
|
|
- ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", &flags, ImGuiComboFlags_PopupAlignLeft);
|
|
|
- ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo");
|
|
|
- if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", &flags, ImGuiComboFlags_NoArrowButton))
|
|
|
- flags &= ~ImGuiComboFlags_NoPreview; // Clear incompatible flags
|
|
|
- if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", &flags, ImGuiComboFlags_NoPreview))
|
|
|
- flags &= ~(ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_WidthFitPreview); // Clear incompatible flags
|
|
|
- if (ImGui::CheckboxFlags("ImGuiComboFlags_WidthFitPreview", &flags, ImGuiComboFlags_WidthFitPreview))
|
|
|
- flags &= ~ImGuiComboFlags_NoPreview;
|
|
|
-
|
|
|
- // Override default popup height
|
|
|
- if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightSmall", &flags, ImGuiComboFlags_HeightSmall))
|
|
|
- flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightSmall);
|
|
|
- if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightRegular", &flags, ImGuiComboFlags_HeightRegular))
|
|
|
- flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightRegular);
|
|
|
- if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightLargest", &flags, ImGuiComboFlags_HeightLargest))
|
|
|
- flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightLargest);
|
|
|
-
|
|
|
- // Using the generic BeginCombo() 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 selection data as an index.
|
|
|
-
|
|
|
- // 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++)
|
|
|
- {
|
|
|
- const bool is_selected = (item_selected_idx == n);
|
|
|
- if (ImGui::Selectable(items[n], is_selected))
|
|
|
- item_selected_idx = n;
|
|
|
-
|
|
|
- // Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
|
|
|
- if (is_selected)
|
|
|
- ImGui::SetItemDefaultFocus();
|
|
|
- }
|
|
|
- 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("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 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 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 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"))
|
|
|
- {
|
|
|
- // 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()).
|
|
|
-
|
|
|
- // 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.
|
|
|
-
|
|
|
- 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;
|
|
|
-
|
|
|
- if (item_highlight && ImGui::IsItemHovered())
|
|
|
- item_highlighted_idx = n;
|
|
|
-
|
|
|
- // 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.");
|
|
|
-
|
|
|
- // 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;
|
|
|
-
|
|
|
- // Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
|
|
|
- if (is_selected)
|
|
|
- ImGui::SetItemDefaultFocus();
|
|
|
- }
|
|
|
- ImGui::EndListBox();
|
|
|
- }
|
|
|
-
|
|
|
- ImGui::TreePop();
|
|
|
- }
|
|
|
-
|
|
|
IMGUI_DEMO_MARKER("Widgets/Selectables");
|
|
|
//ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
|
|
if (ImGui::TreeNode("Selectables"))
|
|
@@ -2758,6 +2534,99 @@ static void DemoWindowWidgetsCollapsingHeaders()
|
|
|
// [SECTION] DemoWindowWidgetsComboBoxes()
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
+static void DemoWindowWidgetsComboBoxes()
|
|
|
+{
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/Combo");
|
|
|
+ if (ImGui::TreeNode("Combo"))
|
|
|
+ {
|
|
|
+ // Combo Boxes are also called "Dropdown" in other systems
|
|
|
+ // Expose flags as checkbox for the demo
|
|
|
+ static ImGuiComboFlags flags = 0;
|
|
|
+ ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", &flags, ImGuiComboFlags_PopupAlignLeft);
|
|
|
+ ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo");
|
|
|
+ if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", &flags, ImGuiComboFlags_NoArrowButton))
|
|
|
+ flags &= ~ImGuiComboFlags_NoPreview; // Clear incompatible flags
|
|
|
+ if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", &flags, ImGuiComboFlags_NoPreview))
|
|
|
+ flags &= ~(ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_WidthFitPreview); // Clear incompatible flags
|
|
|
+ if (ImGui::CheckboxFlags("ImGuiComboFlags_WidthFitPreview", &flags, ImGuiComboFlags_WidthFitPreview))
|
|
|
+ flags &= ~ImGuiComboFlags_NoPreview;
|
|
|
+
|
|
|
+ // Override default popup height
|
|
|
+ if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightSmall", &flags, ImGuiComboFlags_HeightSmall))
|
|
|
+ flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightSmall);
|
|
|
+ if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightRegular", &flags, ImGuiComboFlags_HeightRegular))
|
|
|
+ flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightRegular);
|
|
|
+ if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightLargest", &flags, ImGuiComboFlags_HeightLargest))
|
|
|
+ flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightLargest);
|
|
|
+
|
|
|
+ // Using the generic BeginCombo() 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 selection data as an index.
|
|
|
+
|
|
|
+ // 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++)
|
|
|
+ {
|
|
|
+ const bool is_selected = (item_selected_idx == n);
|
|
|
+ if (ImGui::Selectable(items[n], is_selected))
|
|
|
+ item_selected_idx = n;
|
|
|
+
|
|
|
+ // Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
|
|
|
+ if (is_selected)
|
|
|
+ ImGui::SetItemDefaultFocus();
|
|
|
+ }
|
|
|
+ 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("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 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 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 5 (function)", &item_current_4, [](void* data, int n) { return ((const char**)data)[n]; }, items, IM_ARRAYSIZE(items));
|
|
|
+
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// [SECTION] DemoWindowWidgetsDataTypes()
|
|
|
//-----------------------------------------------------------------------------
|
|
@@ -2778,10 +2647,156 @@ static void DemoWindowWidgetsCollapsingHeaders()
|
|
|
// [SECTION] DemoWindowWidgetsImages()
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
+static void DemoWindowWidgetsImages()
|
|
|
+{
|
|
|
+ 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;
|
|
|
+ {
|
|
|
+ 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
|
|
|
+ ImGui::PushStyleVar(ImGuiStyleVar_ImageBorderSize, IM_MAX(1.0f, ImGui::GetStyle().ImageBorderSize));
|
|
|
+ ImGui::ImageWithBg(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
|
|
+ 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::ImageWithBg(my_tex_id, ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
|
|
+ ImGui::EndTooltip();
|
|
|
+ }
|
|
|
+ ImGui::PopStyleVar();
|
|
|
+ }
|
|
|
+
|
|
|
+ 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] DemoWindowWidgetsListBoxes()
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
+static void DemoWindowWidgetsListBoxes()
|
|
|
+{
|
|
|
+ IMGUI_DEMO_MARKER("Widgets/List Boxes");
|
|
|
+ if (ImGui::TreeNode("List boxes"))
|
|
|
+ {
|
|
|
+ // 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()).
|
|
|
+
|
|
|
+ // 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.
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+ if (item_highlight && ImGui::IsItemHovered())
|
|
|
+ item_highlighted_idx = n;
|
|
|
+
|
|
|
+ // 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.");
|
|
|
+
|
|
|
+ // 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;
|
|
|
+
|
|
|
+ // Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
|
|
|
+ if (is_selected)
|
|
|
+ ImGui::SetItemDefaultFocus();
|
|
|
+ }
|
|
|
+ ImGui::EndListBox();
|
|
|
+ }
|
|
|
+
|
|
|
+ ImGui::TreePop();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// [SECTION] DemoWindowWidgetsMultiComponents()
|
|
|
//-----------------------------------------------------------------------------
|