mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-13 00:09:55 +02:00
Merge branch 'master' into docking
# Conflicts: # docs/CHANGELOG.txt # examples/example_glfw_vulkan/main.cpp # examples/example_sdl_vulkan/main.cpp # imgui.cpp
This commit is contained in:
164
imgui_demo.cpp
164
imgui_demo.cpp
@ -1298,7 +1298,7 @@ static void ShowDemoWindowWidgets()
|
||||
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));
|
||||
|
||||
// Create a dummy array of contiguous float values to plot
|
||||
// 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] = {};
|
||||
@ -1306,7 +1306,7 @@ static void ShowDemoWindowWidgets()
|
||||
static double refresh_time = 0.0;
|
||||
if (!animate || refresh_time == 0.0)
|
||||
refresh_time = ImGui::GetTime();
|
||||
while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 Hz rate for the demo
|
||||
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);
|
||||
@ -1406,7 +1406,7 @@ static void ShowDemoWindowWidgets()
|
||||
|
||||
ImGui::Text("Color button with Custom Picker Popup:");
|
||||
|
||||
// Generate a dummy default palette. The palette will persist and can be edited.
|
||||
// Generate a default palette. The palette will persist and can be edited.
|
||||
static bool saved_palette_init = true;
|
||||
static ImVec4 saved_palette[32] = {};
|
||||
if (saved_palette_init)
|
||||
@ -1987,8 +1987,8 @@ static void ShowDemoWindowWidgets()
|
||||
if (embed_all_inside_a_child_window)
|
||||
ImGui::EndChild();
|
||||
|
||||
static char dummy_str[] = "This is a dummy field to be able to tab-out of the widgets above.";
|
||||
ImGui::InputText("dummy", dummy_str, IM_ARRAYSIZE(dummy_str), ImGuiInputTextFlags_ReadOnly);
|
||||
static char unused_str[] = "This widget is only here to be able to tab-out of the widgets above.";
|
||||
ImGui::InputText("unused", unused_str, IM_ARRAYSIZE(unused_str), ImGuiInputTextFlags_ReadOnly);
|
||||
|
||||
// Calling IsItemHovered() after begin returns the hovered status of the title bar.
|
||||
// This is useful in particular if you want to create a context menu associated to the title bar of a window.
|
||||
@ -2018,7 +2018,7 @@ static void ShowDemoWindowWidgets()
|
||||
|
||||
static void ShowDemoWindowLayout()
|
||||
{
|
||||
if (!ImGui::CollapsingHeader("Layout"))
|
||||
if (!ImGui::CollapsingHeader("Layout & Scrolling"))
|
||||
return;
|
||||
|
||||
if (ImGui::TreeNode("Child windows"))
|
||||
@ -2434,7 +2434,7 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::SameLine(0.0f, spacing);
|
||||
if (ImGui::TreeNode("Node##1"))
|
||||
{
|
||||
// Dummy tree data
|
||||
// Placeholder tree data
|
||||
for (int i = 0; i < 6; i++)
|
||||
ImGui::BulletText("Item %d..", i);
|
||||
ImGui::TreePop();
|
||||
@ -2450,7 +2450,7 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2");
|
||||
if (node_open)
|
||||
{
|
||||
// Dummy tree data
|
||||
// Placeholder tree data
|
||||
for (int i = 0; i < 6; i++)
|
||||
ImGui::BulletText("Item %d..", i);
|
||||
ImGui::TreePop();
|
||||
@ -2548,11 +2548,9 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::Spacing();
|
||||
HelpMarker(
|
||||
"Use SetScrollHereX() or SetScrollFromPosX() to scroll to a given horizontal position.\n\n"
|
||||
"Using the \"Scroll To Pos\" button above will make the discontinuity at edges visible: "
|
||||
"scrolling to the top/bottom/left/right-most item will add an additional WindowPadding to reflect "
|
||||
"on reaching the edge of the list.\n\nBecause the clipping rectangle of most window hides half "
|
||||
"worth of WindowPadding on the left/right, using SetScrollFromPosX(+1) will usually result in "
|
||||
"clipped text whereas the equivalent SetScrollFromPosY(+1) wouldn't.");
|
||||
"Because the clipping rectangle of most window hides half worth of WindowPadding on the "
|
||||
"left/right, using SetScrollFromPosX(+1) will usually result in clipped text whereas the "
|
||||
"equivalent SetScrollFromPosY(+1) wouldn't.");
|
||||
ImGui::PushID("##HorizontalScrolling");
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
@ -2742,23 +2740,66 @@ static void ShowDemoWindowLayout()
|
||||
|
||||
if (ImGui::TreeNode("Clipping"))
|
||||
{
|
||||
static ImVec2 size(100, 100), offset(50, 20);
|
||||
ImGui::TextWrapped(
|
||||
"On a per-widget basis we are occasionally clipping text CPU-side if it won't fit in its frame. "
|
||||
"Otherwise we are doing coarser clipping + passing a scissor rectangle to the renderer. "
|
||||
"The system is designed to try minimizing both execution and CPU/GPU rendering cost.");
|
||||
static ImVec2 size(100.0f, 100.0f);
|
||||
static ImVec2 offset(30.0f, 30.0f);
|
||||
ImGui::DragFloat2("size", (float*)&size, 0.5f, 1.0f, 200.0f, "%.0f");
|
||||
ImGui::TextWrapped("(Click and drag)");
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
ImVec4 clip_rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y);
|
||||
ImGui::InvisibleButton("##dummy", size);
|
||||
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0))
|
||||
ImGui::TextWrapped("(Click and drag to scroll)");
|
||||
|
||||
for (int n = 0; n < 3; n++)
|
||||
{
|
||||
offset.x += ImGui::GetIO().MouseDelta.x;
|
||||
offset.y += ImGui::GetIO().MouseDelta.y;
|
||||
if (n > 0)
|
||||
ImGui::SameLine();
|
||||
ImGui::PushID(n);
|
||||
ImGui::BeginGroup(); // Lock X position
|
||||
|
||||
ImGui::InvisibleButton("##empty", size);
|
||||
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left))
|
||||
{
|
||||
offset.x += ImGui::GetIO().MouseDelta.x;
|
||||
offset.y += ImGui::GetIO().MouseDelta.y;
|
||||
}
|
||||
const ImVec2 p0 = ImGui::GetItemRectMin();
|
||||
const ImVec2 p1 = ImGui::GetItemRectMax();
|
||||
const char* text_str = "Line 1 hello\nLine 2 clip me!";
|
||||
const ImVec2 text_pos = ImVec2(p0.x + offset.x, p0.y + offset.y);
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case 0:
|
||||
HelpMarker(
|
||||
"Using ImGui::PushClipRect():\n"
|
||||
"Will alter ImGui hit-testing logic + ImDrawList rendering.\n"
|
||||
"(use this if you want your clipping rectangle to affect interactions)");
|
||||
ImGui::PushClipRect(p0, p1, true);
|
||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||
draw_list->AddText(text_pos, IM_COL32_WHITE, text_str);
|
||||
ImGui::PopClipRect();
|
||||
break;
|
||||
case 1:
|
||||
HelpMarker(
|
||||
"Using ImDrawList::PushClipRect():\n"
|
||||
"Will alter ImDrawList rendering only.\n"
|
||||
"(use this as a shortcut if you are only using ImDrawList calls)");
|
||||
draw_list->PushClipRect(p0, p1, true);
|
||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||
draw_list->AddText(text_pos, IM_COL32_WHITE, text_str);
|
||||
draw_list->PopClipRect();
|
||||
break;
|
||||
case 2:
|
||||
HelpMarker(
|
||||
"Using ImDrawList::AddText() with a fine ClipRect:\n"
|
||||
"Will alter only this specific ImDrawList::AddText() rendering.\n"
|
||||
"(this is often used internally to avoid altering the clipping rectangle and minimize draw calls)");
|
||||
ImVec4 clip_rect(p0.x, p0.y, p1.x, p1.y); // AddText() takes a ImVec4* here so let's convert.
|
||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||
draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(), text_pos, IM_COL32_WHITE, text_str, NULL, 0.0f, &clip_rect);
|
||||
break;
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x + size.x, pos.y + size.y), IM_COL32(90, 90, 120, 255));
|
||||
ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*2.0f, ImVec2(pos.x + offset.x, pos.y + offset.y), IM_COL32_WHITE, "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect);
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
@ -2930,8 +2971,8 @@ static void ShowDemoWindowPopups()
|
||||
ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n");
|
||||
ImGui::Separator();
|
||||
|
||||
//static int dummy_i = 0;
|
||||
//ImGui::Combo("Combo", &dummy_i, "Delete\0Delete harder\0");
|
||||
//static int unused_i = 0;
|
||||
//ImGui::Combo("Combo", &unused_i, "Delete\0Delete harder\0");
|
||||
|
||||
static bool dont_ask_me_next_time = false;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
@ -2953,7 +2994,7 @@ static void ShowDemoWindowPopups()
|
||||
{
|
||||
if (ImGui::BeginMenu("File"))
|
||||
{
|
||||
if (ImGui::MenuItem("Dummy menu item")) {}
|
||||
if (ImGui::MenuItem("Some menu item")) {}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
@ -2972,8 +3013,8 @@ static void ShowDemoWindowPopups()
|
||||
// Also demonstrate passing a bool* to BeginPopupModal(), this will create a regular close button which
|
||||
// will close the popup. Note that the visibility state of popups is owned by imgui, so the input value
|
||||
// of the bool actually doesn't matter here.
|
||||
bool dummy_open = true;
|
||||
if (ImGui::BeginPopupModal("Stacked 2", &dummy_open))
|
||||
bool unused_open = true;
|
||||
if (ImGui::BeginPopupModal("Stacked 2", &unused_open))
|
||||
{
|
||||
ImGui::Text("Hello from Stacked The Second!");
|
||||
if (ImGui::Button("Close"))
|
||||
@ -3308,7 +3349,7 @@ static void ShowDemoWindowMisc()
|
||||
if (ImGui::TreeNode("Tabbing"))
|
||||
{
|
||||
ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields.");
|
||||
static char buf[32] = "dummy";
|
||||
static char buf[32] = "hello";
|
||||
ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
|
||||
ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
|
||||
ImGui::InputText("3", buf, IM_ARRAYSIZE(buf));
|
||||
@ -3985,7 +4026,7 @@ static void ShowExampleAppMainMenuBar()
|
||||
// (future version will add explicit flags to BeginMenu() to request processing shortcuts)
|
||||
static void ShowExampleMenuFile()
|
||||
{
|
||||
ImGui::MenuItem("(dummy menu)", NULL, false, false);
|
||||
ImGui::MenuItem("(demo menu)", NULL, false, false);
|
||||
if (ImGui::MenuItem("New")) {}
|
||||
if (ImGui::MenuItem("Open", "Ctrl+O")) {}
|
||||
if (ImGui::BeginMenu("Open Recent"))
|
||||
@ -4149,8 +4190,8 @@ struct ExampleAppConsole
|
||||
|
||||
// TODO: display items starting from the bottom
|
||||
|
||||
if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Add Dummy Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Add Debug Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Add Debug Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine();
|
||||
if (ImGui::SmallButton("Clear")) { ClearLog(); } ImGui::SameLine();
|
||||
bool copy_to_clipboard = ImGui::SmallButton("Copy");
|
||||
//static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); }
|
||||
@ -4640,7 +4681,7 @@ static void ShowExampleAppLayout(bool* p_open)
|
||||
// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void ShowDummyObject(const char* prefix, int uid)
|
||||
static void ShowPlaceholderObject(const char* prefix, int uid)
|
||||
{
|
||||
// Use object uid as identifier. Most commonly you could also use the object pointer as a base ID.
|
||||
ImGui::PushID(uid);
|
||||
@ -4652,13 +4693,13 @@ static void ShowDummyObject(const char* prefix, int uid)
|
||||
ImGui::NextColumn();
|
||||
if (node_open)
|
||||
{
|
||||
static float dummy_members[8] = { 0.0f, 0.0f, 1.0f, 3.1416f, 100.0f, 999.0f };
|
||||
static float placeholder_members[8] = { 0.0f, 0.0f, 1.0f, 3.1416f, 100.0f, 999.0f };
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
ImGui::PushID(i); // Use field index as identifier.
|
||||
if (i < 2)
|
||||
{
|
||||
ShowDummyObject("Child", 424242);
|
||||
ShowPlaceholderObject("Child", 424242);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4669,9 +4710,9 @@ static void ShowDummyObject(const char* prefix, int uid)
|
||||
ImGui::NextColumn();
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
if (i >= 5)
|
||||
ImGui::InputFloat("##value", &dummy_members[i], 1.0f);
|
||||
ImGui::InputFloat("##value", &placeholder_members[i], 1.0f);
|
||||
else
|
||||
ImGui::DragFloat("##value", &dummy_members[i], 0.01f);
|
||||
ImGui::DragFloat("##value", &placeholder_members[i], 0.01f);
|
||||
ImGui::NextColumn();
|
||||
}
|
||||
ImGui::PopID();
|
||||
@ -4701,9 +4742,9 @@ static void ShowExampleAppPropertyEditor(bool* p_open)
|
||||
ImGui::Columns(2);
|
||||
ImGui::Separator();
|
||||
|
||||
// Iterate dummy objects with dummy members (all the same data)
|
||||
// Iterate placeholder objects (all the same data)
|
||||
for (int obj_i = 0; obj_i < 3; obj_i++)
|
||||
ShowDummyObject("Object", obj_i);
|
||||
ShowPlaceholderObject("Object", obj_i);
|
||||
|
||||
ImGui::Columns(1);
|
||||
ImGui::Separator();
|
||||
@ -5041,13 +5082,14 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
|
||||
if (ImGui::BeginTabItem("Canvas"))
|
||||
{
|
||||
struct ItemLine { ImVec2 p0, p1; ItemLine(const ImVec2& _p0, const ImVec2& _p1) { p0 = _p0; p1 = _p1; } };
|
||||
static ImVector<ItemLine> lines;
|
||||
static ImVector<ImVec2> points;
|
||||
static ImVec2 scrolling(0.0f, 0.0f);
|
||||
static bool show_grid = true;
|
||||
static bool opt_enable_grid = true;
|
||||
static bool opt_enable_context_menu = true;
|
||||
static bool adding_line = false;
|
||||
|
||||
ImGui::Checkbox("Show grid", &show_grid);
|
||||
ImGui::Checkbox("Enable grid", &opt_enable_grid);
|
||||
ImGui::Checkbox("Enable context menu", &opt_enable_context_menu);
|
||||
ImGui::Text("Mouse Left: drag to add lines,\nMouse Right: drag to scroll, click for context menu.");
|
||||
|
||||
// Typically you would use a BeginChild()/EndChild() pair to benefit from a clipping region + own scrolling.
|
||||
@ -5084,41 +5126,43 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
// Add first and second point
|
||||
if (is_hovered && !adding_line && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
|
||||
{
|
||||
lines.push_back(ItemLine(mouse_pos_in_canvas, mouse_pos_in_canvas));
|
||||
points.push_back(mouse_pos_in_canvas);
|
||||
points.push_back(mouse_pos_in_canvas);
|
||||
adding_line = true;
|
||||
}
|
||||
if (adding_line)
|
||||
{
|
||||
lines.back().p1 = mouse_pos_in_canvas;
|
||||
points.back() = mouse_pos_in_canvas;
|
||||
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left))
|
||||
adding_line = false;
|
||||
}
|
||||
|
||||
// Pan (using zero mouse threshold)
|
||||
if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right, 0.0f))
|
||||
// Pan (we use a zero mouse threshold when there's no context menu)
|
||||
// You may decide to make that threshold dynamic based on whether the mouse is hovering something etc.
|
||||
const float mouse_threshold_for_pan = opt_enable_context_menu ? -1.0f : 0.0f;
|
||||
if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right, mouse_threshold_for_pan))
|
||||
{
|
||||
scrolling.x += io.MouseDelta.x;
|
||||
scrolling.y += io.MouseDelta.y;
|
||||
}
|
||||
|
||||
// Context menu (under default mouse threshold)
|
||||
// We intentionally use the same button to demonstrate using mouse drag threshold. Some may feel panning should rely on same threshold.
|
||||
ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
|
||||
if (drag_delta.x == 0.0f && drag_delta.y == 0.0f)
|
||||
if (opt_enable_context_menu && ImGui::IsMouseReleased(ImGuiMouseButton_Right) && drag_delta.x == 0.0f && drag_delta.y == 0.0f)
|
||||
ImGui::OpenPopupContextItem("context");
|
||||
if (ImGui::BeginPopup("context"))
|
||||
{
|
||||
if (adding_line)
|
||||
lines.pop_back();
|
||||
points.resize(points.size() - 2);
|
||||
adding_line = false;
|
||||
if (ImGui::MenuItem("Remove one", NULL, false, lines.Size > 0)) { lines.pop_back(); }
|
||||
if (ImGui::MenuItem("Remove all", NULL, false, lines.Size > 0)) { lines.clear(); }
|
||||
if (ImGui::MenuItem("Remove one", NULL, false, points.Size > 0)) { points.resize(points.size() - 2); }
|
||||
if (ImGui::MenuItem("Remove all", NULL, false, points.Size > 0)) { points.clear(); }
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Draw grid + all lines in the canvas
|
||||
draw_list->PushClipRect(canvas_p0, canvas_p1, true);
|
||||
if (show_grid)
|
||||
if (opt_enable_grid)
|
||||
{
|
||||
const float GRID_STEP = 64.0f;
|
||||
for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x; x += GRID_STEP)
|
||||
@ -5126,8 +5170,8 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; y += GRID_STEP)
|
||||
draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y), IM_COL32(200, 200, 200, 40));
|
||||
}
|
||||
for (int n = 0; n < lines.Size; n++)
|
||||
draw_list->AddLine(ImVec2(origin.x + lines[n].p0.x, origin.y + lines[n].p0.y), ImVec2(origin.x + lines[n].p1.x, origin.y + lines[n].p1.y), IM_COL32(255, 255, 0, 255), 2.0f);
|
||||
for (int n = 0; n < points.Size; n += 2)
|
||||
draw_list->AddLine(ImVec2(origin.x + points[n].x, origin.y + points[n].y), ImVec2(origin.x + points[n + 1].x, origin.y + points[n + 1].y), IM_COL32(255, 255, 0, 255), 2.0f);
|
||||
draw_list->PopClipRect();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
@ -5278,7 +5322,7 @@ struct MyDocument
|
||||
void DoForceClose() { Open = false; Dirty = false; }
|
||||
void DoSave() { Dirty = false; }
|
||||
|
||||
// Display dummy contents for the Document
|
||||
// Display placeholder contents for the Document
|
||||
static void DisplayContents(MyDocument* doc)
|
||||
{
|
||||
ImGui::PushID(doc);
|
||||
|
Reference in New Issue
Block a user