Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui_demo.cpp
#	imgui_draw.cpp
#	imgui_internal.h
This commit is contained in:
omar 2020-07-29 15:15:14 +02:00
commit 70fa37527d
7 changed files with 117 additions and 62 deletions

View File

@ -106,9 +106,11 @@ Other changes:
Other Changes: Other Changes:
- Nav: Fixed clicking on void from not clearing focused window. - Nav: Fixed clicking on void (behind any windows) from not clearing the focused window.
This would be problematic e.g. in situation where the application relies on io.WantCaptureKeyboard This would be problematic e.g. in situation where the application relies on io.WantCaptureKeyboard
flag being cleared accordingly. (bug introduced in 1.77 WIP on 2020/06/16) (#3344, #2880) flag being cleared accordingly. (bug introduced in 1.77 WIP on 2020/06/16) (#3344, #2880)
- DragFloatRange2, DragIntRange2: Fixed an issue allowing to drag out of bounds when both
min and max value are on the same value. (#1441)
- InputText, ImDrawList: Fixed assert triggering when drawing single line of text with more - InputText, ImDrawList: Fixed assert triggering when drawing single line of text with more
than ~16 KB characters. (Note that current code is going to show corrupted display if after than ~16 KB characters. (Note that current code is going to show corrupted display if after
clipping, more than 16 KB characters are visible in the same low-level ImDrawList::RenderText clipping, more than 16 KB characters are visible in the same low-level ImDrawList::RenderText
@ -120,8 +122,13 @@ Other Changes:
- Requires an extra bit of texture space (~64x64 by default), relies on GPU bilinear filtering. - Requires an extra bit of texture space (~64x64 by default), relies on GPU bilinear filtering.
- Clear io.AntiAliasedLinesUseTex = false; to disable rendering using this method. - Clear io.AntiAliasedLinesUseTex = false; to disable rendering using this method.
- Clear ImFontAtlasFlags_NoBakedLines in ImFontAtlas::Flags to disable baking data in texture. - Clear ImFontAtlasFlags_NoBakedLines in ImFontAtlas::Flags to disable baking data in texture.
- ImDrawList: changed AddCircle(), AddCircleFilled() default num_segments from 12 to 0, effectively
enabling auto-tessellation by default. Tweak tessellation in Style Editor->Rendering section, or
by modifying the 'style.CircleSegmentMaxError' value. [@ShironekoBen]
- ImDrawList: Fixed minor bug introduced in 1.75 where AddCircle() with 12 segments would generate - ImDrawList: Fixed minor bug introduced in 1.75 where AddCircle() with 12 segments would generate
an extra vertex. (This bug was mistakenly marked as fixed in earlier 1.77 release). [@ShironekoBen] an extra vertex. (This bug was mistakenly marked as fixed in earlier 1.77 release). [@ShironekoBen]
- Demo: Tweak "Child Windows" section.
- Style Editor: Added preview of circle auto-tessellation when editing the corresponding value.
- Backends: OpenGL3: Added support for glad2 loader. (#3330) [@moritz-h] - Backends: OpenGL3: Added support for glad2 loader. (#3330) [@moritz-h]
>>>>>>> master >>>>>>> master
@ -198,7 +205,7 @@ Other Changes:
Updated various links/wiki accordingly. Added FAQ entry about DPI. (#2861) [@ButternCream, @ocornut] Updated various links/wiki accordingly. Added FAQ entry about DPI. (#2861) [@ButternCream, @ocornut]
- CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups, - CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups,
static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns). static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns).
Fixed a static constructor which led to this dependency on some compiler setups. Fixed a static constructor which led to this dependency on some compiler setups. [@rokups]
- Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) - Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327)
- Backends: Win32: Fix _WIN32_WINNT < 0x0600 (MinGW defaults to 0x502 == Windows 2003). (#3183) - Backends: Win32: Fix _WIN32_WINNT < 0x0600 (MinGW defaults to 0x502 == Windows 2003). (#3183)
- Backends: SDL: Report a zero display-size when window is minimized, consistent with other backends, - Backends: SDL: Report a zero display-size when window is minimized, consistent with other backends,

View File

@ -4369,6 +4369,8 @@ static void ImGui::EndFrameDrawDimmedBackgrounds()
draw_list->PushClipRectFullScreen(); draw_list->PushClipRectFullScreen();
// Docking: draw modal whitening background on other nodes of a same dock tree // Docking: draw modal whitening background on other nodes of a same dock tree
// For CTRL+TAB within a docking node we need to render the dimming background in 8 steps
// (Because the root node renders the background in one shot, in order to avoid flickering when a child dock node is not submitted)
if (window->RootWindowDockStop->DockIsActive) if (window->RootWindowDockStop->DockIsActive)
if (window->RootWindow != window->RootWindowDockStop) if (window->RootWindow != window->RootWindowDockStop)
RenderRectFilledWithHole(draw_list, window->RootWindow->Rect(), window->RootWindowDockStop->Rect(), GetColorU32(ImGuiCol_NavWindowingDimBg, g.DimBgRatio), g.Style.WindowRounding); RenderRectFilledWithHole(draw_list, window->RootWindow->Rect(), window->RootWindowDockStop->Rect(), GetColorU32(ImGuiCol_NavWindowingDimBg, g.DimBgRatio), g.Style.WindowRounding);
@ -4609,12 +4611,13 @@ static void FindHoveredWindow()
if (!bb.Contains(g.IO.MousePos)) if (!bb.Contains(g.IO.MousePos))
continue; continue;
// Support for one rectangular hole in any given window
// FIXME: Consider generalizing hit-testing override (with more generic data, callback, etc.) (#1512)
if (window->HitTestHoleSize.x != 0) if (window->HitTestHoleSize.x != 0)
{ {
// FIXME: Consider generalizing hit-testing override (with more generic data, callback, etc.) (#1512) ImVec2 hole_pos(window->Pos.x + (float)window->HitTestHoleOffset.x, window->Pos.y + (float)window->HitTestHoleOffset.y);
ImRect hole_bb((float)(window->HitTestHoleOffset.x), (float)(window->HitTestHoleOffset.y), ImVec2 hole_size((float)window->HitTestHoleSize.x, (float)window->HitTestHoleSize.y);
(float)(window->HitTestHoleOffset.x + window->HitTestHoleSize.x), (float)(window->HitTestHoleOffset.y + window->HitTestHoleSize.y)); if (ImRect(hole_pos, hole_pos + hole_size).Contains(g.IO.MousePos))
if (hole_bb.Contains(g.IO.MousePos - window->Pos))
continue; continue;
} }
@ -6034,6 +6037,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x); window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y; window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
// Lock menu offset so size calculation can use it as menu-bar windows need a minimum size.
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
// Collapse window by double-clicking on title bar // Collapse window by double-clicking on title bar
// At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing // At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing
if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse) && !window->DockIsActive) if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse) && !window->DockIsActive)
@ -10680,14 +10687,14 @@ static void WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*,
int x, y; int x, y;
int i; int i;
ImU32 u1; ImU32 u1;
if (sscanf(line, "Pos=%i,%i", &x, &y) == 2) { settings->Pos = ImVec2ih((short)x, (short)y); } if (sscanf(line, "Pos=%i,%i", &x, &y) == 2) { settings->Pos = ImVec2ih((short)x, (short)y); }
else if (sscanf(line, "Size=%i,%i", &x, &y) == 2) { settings->Size = ImVec2ih((short)x, (short)y); } else if (sscanf(line, "Size=%i,%i", &x, &y) == 2) { settings->Size = ImVec2ih((short)x, (short)y); }
else if (sscanf(line, "ViewportId=0x%08X", &u1) == 1) { settings->ViewportId = u1; } else if (sscanf(line, "ViewportId=0x%08X", &u1) == 1) { settings->ViewportId = u1; }
else if (sscanf(line, "ViewportPos=%i,%i", &x, &y) == 2) { settings->ViewportPos = ImVec2ih((short)x, (short)y); } else if (sscanf(line, "ViewportPos=%i,%i", &x, &y) == 2){ settings->ViewportPos = ImVec2ih((short)x, (short)y); }
else if (sscanf(line, "Collapsed=%d", &i) == 1) { settings->Collapsed = (i != 0); } else if (sscanf(line, "Collapsed=%d", &i) == 1) { settings->Collapsed = (i != 0); }
else if (sscanf(line, "DockId=0x%X,%d", &u1, &i) == 2) { settings->DockId = u1; settings->DockOrder = (short)i; } else if (sscanf(line, "DockId=0x%X,%d", &u1, &i) == 2) { settings->DockId = u1; settings->DockOrder = (short)i; }
else if (sscanf(line, "DockId=0x%X", &u1) == 1) { settings->DockId = u1; settings->DockOrder = -1; } else if (sscanf(line, "DockId=0x%X", &u1) == 1) { settings->DockId = u1; settings->DockOrder = -1; }
else if (sscanf(line, "ClassId=0x%X", &u1) == 1) { settings->ClassId = u1; } else if (sscanf(line, "ClassId=0x%X", &u1) == 1) { settings->ClassId = u1; }
} }
// Apply to existing windows (if any) // Apply to existing windows (if any)

View File

@ -476,7 +476,6 @@ namespace ImGui
// - Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision). // - Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision).
// - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits. // - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits.
// - Use v_max = FLT_MAX / INT_MAX etc to avoid clamping to a maximum, same with v_min = -FLT_MAX / INT_MIN to avoid clamping to a minimum. // - Use v_max = FLT_MAX / INT_MAX etc to avoid clamping to a maximum, same with v_min = -FLT_MAX / INT_MIN to avoid clamping to a minimum.
// - Use v_min > v_max to lock edits.
IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound
IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f); IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f);
IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f); IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f);
@ -2156,6 +2155,7 @@ struct ImDrawList
// Primitives // Primitives
// - For rectangular primitives, "p_min" and "p_max" represent the upper-left and lower-right corners. // - For rectangular primitives, "p_min" and "p_max" represent the upper-left and lower-right corners.
// - For circle primitives, use "num_segments == 0" to automatically calculate tessellation (preferred). // - For circle primitives, use "num_segments == 0" to automatically calculate tessellation (preferred).
// In older versions (until Dear ImGui 1.77) the AddCircle functions defaulted to num_segments == 12.
// In future versions we will use textures to provide cheaper and higher-quality circles. // In future versions we will use textures to provide cheaper and higher-quality circles.
// Use AddNgon() and AddNgonFilled() functions if you need to guaranteed a specific number of sides. // Use AddNgon() and AddNgonFilled() functions if you need to guaranteed a specific number of sides.
IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f); IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f);
@ -2166,8 +2166,8 @@ struct ImDrawList
IMGUI_API void AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col); IMGUI_API void AddQuadFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col);
IMGUI_API void AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness = 1.0f); IMGUI_API void AddTriangle(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness = 1.0f);
IMGUI_API void AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col); IMGUI_API void AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col);
IMGUI_API void AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f); IMGUI_API void AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments = 0, float thickness = 1.0f);
IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0);
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f); IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f);
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments); IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);

View File

@ -243,6 +243,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
static bool show_app_main_menu_bar = false; static bool show_app_main_menu_bar = false;
static bool show_app_dockspace = false; static bool show_app_dockspace = false;
static bool show_app_documents = false; static bool show_app_documents = false;
static bool show_app_console = false; static bool show_app_console = false;
static bool show_app_log = false; static bool show_app_log = false;
static bool show_app_layout = false; static bool show_app_layout = false;
@ -257,6 +258,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
if (show_app_main_menu_bar) ShowExampleAppMainMenuBar(); if (show_app_main_menu_bar) ShowExampleAppMainMenuBar();
if (show_app_dockspace) ShowExampleAppDockSpace(&show_app_dockspace); // Process the Docking app first, as explicit DockSpace() nodes needs to be submitted early (read comments near the DockSpace function) if (show_app_dockspace) ShowExampleAppDockSpace(&show_app_dockspace); // Process the Docking app first, as explicit DockSpace() nodes needs to be submitted early (read comments near the DockSpace function)
if (show_app_documents) ShowExampleAppDocuments(&show_app_documents); // Process the Document app next, as it may also use a DockSpace() if (show_app_documents) ShowExampleAppDocuments(&show_app_documents); // Process the Document app next, as it may also use a DockSpace()
if (show_app_console) ShowExampleAppConsole(&show_app_console); if (show_app_console) ShowExampleAppConsole(&show_app_console);
if (show_app_log) ShowExampleAppLog(&show_app_log); if (show_app_log) ShowExampleAppLog(&show_app_log);
if (show_app_layout) ShowExampleAppLayout(&show_app_layout); if (show_app_layout) ShowExampleAppLayout(&show_app_layout);
@ -1545,7 +1547,8 @@ static void ShowDemoWindowWidgets()
{ {
static float begin = 10, end = 90; static float begin = 10, end = 90;
static int begin_i = 100, end_i = 1000; static int begin_i = 100, end_i = 1000;
ImGui::DragFloatRange2("range", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%"); ImGui::DragFloatRange2("range float", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%");
ImGui::DragIntRange2("range int", &begin_i, &end_i, 5, 0, 1000, "Min: %d units", "Max: %d units");
ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %d units", "Max: %d units"); ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %d units", "Max: %d units");
ImGui::TreePop(); ImGui::TreePop();
} }
@ -2026,12 +2029,6 @@ static void ShowDemoWindowLayout()
ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel); ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel);
ImGui::Checkbox("Disable Menu", &disable_menu); ImGui::Checkbox("Disable Menu", &disable_menu);
static int line = 50;
bool goto_line = ImGui::Button("Goto");
ImGui::SameLine();
ImGui::SetNextItemWidth(100);
goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue);
// Child 1: no border, enable horizontal scrollbar // Child 1: no border, enable horizontal scrollbar
{ {
ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar; ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar;
@ -2039,13 +2036,7 @@ static void ShowDemoWindowLayout()
window_flags |= ImGuiWindowFlags_NoScrollWithMouse; window_flags |= ImGuiWindowFlags_NoScrollWithMouse;
ImGui::BeginChild("ChildL", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 260), false, window_flags); ImGui::BeginChild("ChildL", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 260), false, window_flags);
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{
ImGui::Text("%04d: scrollable region", i); ImGui::Text("%04d: scrollable region", i);
if (goto_line && line == i)
ImGui::SetScrollHereY();
}
if (goto_line && line >= 100)
ImGui::SetScrollHereY();
ImGui::EndChild(); ImGui::EndChild();
} }
@ -2091,15 +2082,21 @@ static void ShowDemoWindowLayout()
// - Using ImGui::GetItemRectMin/Max() to query the "item" state (because the child window is an item from // - Using ImGui::GetItemRectMin/Max() to query the "item" state (because the child window is an item from
// the POV of the parent window). See 'Demo->Querying Status (Active/Focused/Hovered etc.)' for details. // the POV of the parent window). See 'Demo->Querying Status (Active/Focused/Hovered etc.)' for details.
{ {
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 10); static int offset_x = 0;
ImGui::SetNextItemWidth(100);
ImGui::DragInt("Offset X", &offset_x, 1.0f, -1000, 1000);
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (float)offset_x);
ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(255, 0, 0, 100)); ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(255, 0, 0, 100));
ImGui::BeginChild("Red", ImVec2(200, 100), true, ImGuiWindowFlags_None); ImGui::BeginChild("Red", ImVec2(200, 100), true, ImGuiWindowFlags_None);
for (int n = 0; n < 50; n++) for (int n = 0; n < 50; n++)
ImGui::Text("Some test %d", n); ImGui::Text("Some test %d", n);
ImGui::EndChild(); ImGui::EndChild();
bool child_is_hovered = ImGui::IsItemHovered();
ImVec2 child_rect_min = ImGui::GetItemRectMin(); ImVec2 child_rect_min = ImGui::GetItemRectMin();
ImVec2 child_rect_max = ImGui::GetItemRectMax(); ImVec2 child_rect_max = ImGui::GetItemRectMax();
ImGui::PopStyleColor(); ImGui::PopStyleColor();
ImGui::Text("Hovered: %d", child_is_hovered);
ImGui::Text("Rect of child window is: (%.0f,%.0f) (%.0f,%.0f)", child_rect_min.x, child_rect_min.y, child_rect_max.x, child_rect_max.y); ImGui::Text("Rect of child window is: (%.0f,%.0f) (%.0f,%.0f)", child_rect_min.x, child_rect_min.y, child_rect_max.x, child_rect_max.y);
} }
@ -2485,8 +2482,6 @@ static void ShowDemoWindowLayout()
static float scroll_to_pos_px = 200.0f; static float scroll_to_pos_px = 200.0f;
ImGui::Checkbox("Decoration", &enable_extra_decorations); ImGui::Checkbox("Decoration", &enable_extra_decorations);
ImGui::SameLine();
HelpMarker("We expose this for testing because scrolling sometimes had issues with window decoration such as menu-bars.");
ImGui::Checkbox("Track", &enable_track); ImGui::Checkbox("Track", &enable_track);
ImGui::PushItemWidth(100); ImGui::PushItemWidth(100);
@ -3918,7 +3913,28 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::PushItemWidth(100); ImGui::PushItemWidth(100);
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f"); ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f");
if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f; if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f;
ImGui::DragFloat("Circle segment Max Error", &style.CircleSegmentMaxError, 0.01f, 0.10f, 10.0f, "%.2f");
// When editing the "Circle Segment Max Error" value, draw a preview of its effect on auto-tessellated circles.
ImGui::DragFloat("Circle Segment Max Error", &style.CircleSegmentMaxError, 0.01f, 0.10f, 10.0f, "%.2f");
if (ImGui::IsItemActive())
{
ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos());
ImGui::BeginTooltip();
ImVec2 p = ImGui::GetCursorScreenPos();
float RAD_MIN = 10.0f, RAD_MAX = 80.0f;
float off_x = 10.0f;
for (int n = 0; n < 7; n++)
{
const float rad = RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (7.0f - 1.0f);
ImGui::GetWindowDrawList()->AddCircle(ImVec2(p.x + off_x + rad, p.y + RAD_MAX), rad, ImGui::GetColorU32(ImGuiCol_Text), 0);
off_x += 10.0f + rad * 2.0f;
}
ImGui::Dummy(ImVec2(off_x, RAD_MAX * 2.0f));
ImGui::EndTooltip();
}
ImGui::SameLine();
HelpMarker("When drawing circle primitives with \"num_segments == 0\" tesselation will be calculated automatically.");
ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero. ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
ImGui::PopItemWidth(); ImGui::PopItemWidth();

View File

@ -1673,10 +1673,10 @@ ImFontConfig::ImFontConfig()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// A work of art lies ahead! (. = white layer, X = black layer, others are blank) // A work of art lies ahead! (. = white layer, X = black layer, others are blank)
// The white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes. // The 2x2 white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes.
const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 108; const int FONT_ATLAS_DEFAULT_TEX_DATA_W = 108; // Actual texture will be 2 times that + 1 spacing.
const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27; const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27;
static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] = static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] =
{ {
"..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX- XX " "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX- XX "
"..- -X.....X- X.X - X.X -X.....X - X.....X- X..X " "..- -X.....X- X.X - X.X -X.....X - X.....X- X..X "
@ -2009,7 +2009,7 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou
*out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2]; *out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2];
out_uv_border[0] = (pos) * TexUvScale; out_uv_border[0] = (pos) * TexUvScale;
out_uv_border[1] = (pos + size) * TexUvScale; out_uv_border[1] = (pos + size) * TexUvScale;
pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W + 1;
out_uv_fill[0] = (pos) * TexUvScale; out_uv_fill[0] = (pos) * TexUvScale;
out_uv_fill[1] = (pos + size) * TexUvScale; out_uv_fill[1] = (pos + size) * TexUvScale;
return true; return true;
@ -2372,6 +2372,16 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa
} }
} }
void ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value)
{
IM_ASSERT(x >= 0 && x + w <= atlas->TexWidth);
IM_ASSERT(y >= 0 && y + h <= atlas->TexHeight);
unsigned char* out_pixel = atlas->TexPixelsAlpha8 + x + (y * atlas->TexWidth);
for (int off_y = 0; off_y < h; off_y++, out_pixel += atlas->TexWidth, in_str += w)
for (int off_x = 0; off_x < w; off_x++)
out_pixel[off_x] = (in_str[off_x] == in_marker_char) ? in_marker_pixel_value : 0x00;
}
static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
{ {
ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors); ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(atlas->PackIdMouseCursors);
@ -2381,15 +2391,11 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors))
{ {
// Render/copy pixels // Render/copy pixels
IM_ASSERT(r->Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1 && r->Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); IM_ASSERT(r->Width == FONT_ATLAS_DEFAULT_TEX_DATA_W * 2 + 1 && r->Height == FONT_ATLAS_DEFAULT_TEX_DATA_H);
for (int y = 0, n = 0; y < FONT_ATLAS_DEFAULT_TEX_DATA_H; y++) const int x_for_white = r->X;
for (int x = 0; x < FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF; x++, n++) const int x_for_black = r->X + FONT_ATLAS_DEFAULT_TEX_DATA_W + 1;
{ ImFontAtlasBuildRender1bppRectFromString(atlas, x_for_white, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, '.', 0xFF);
const int offset0 = (int)(r->X + x) + (int)(r->Y + y) * w; ImFontAtlasBuildRender1bppRectFromString(atlas, x_for_black, r->Y, FONT_ATLAS_DEFAULT_TEX_DATA_W, FONT_ATLAS_DEFAULT_TEX_DATA_H, FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS, 'X', 0xFF);
const int offset1 = offset0 + FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1;
atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00;
atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00;
}
} }
else else
{ {
@ -2439,7 +2445,7 @@ void ImFontAtlasBuildInit(ImFontAtlas* atlas)
if (atlas->PackIdMouseCursors < 0) if (atlas->PackIdMouseCursors < 0)
{ {
if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors))
atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1, FONT_ATLAS_DEFAULT_TEX_DATA_H); atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_W * 2 + 1, FONT_ATLAS_DEFAULT_TEX_DATA_H);
else else
atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(2, 2); atlas->PackIdMouseCursors = atlas->AddCustomRectRegular(2, 2);
} }
@ -3511,8 +3517,6 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
draw_list->PathFillConvex(col); draw_list->PathFillConvex(col);
} }
// For CTRL+TAB within a docking node we need to render the dimming background in 8 steps
// (Because the root node renders the background in one shot, in order to avoid flickering when a child dock node is not submitted)
void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect inner, ImU32 col, float rounding) void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect inner, ImU32 col, float rounding)
{ {
const bool fill_L = (inner.Min.x > outer.Min.x); const bool fill_L = (inner.Min.x > outer.Min.x);

View File

@ -591,6 +591,7 @@ enum ImGuiItemFlags_
ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false
ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window
ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets) ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets)
ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
ImGuiItemFlags_Default_ = 0 ImGuiItemFlags_Default_ = 0
}; };
@ -1809,7 +1810,8 @@ struct IMGUI_API ImGuiWindow
ImRect WorkRect; // Cover the whole scrolling region, shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect over time (from 1.71+ onward). ImRect WorkRect; // Cover the whole scrolling region, shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect over time (from 1.71+ onward).
ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back(). ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back().
ImRect ContentRegionRect; // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not handling of scrolling. We currently rely on it as right/bottom aligned sizing operation need some size to rely on. ImRect ContentRegionRect; // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not handling of scrolling. We currently rely on it as right/bottom aligned sizing operation need some size to rely on.
ImVec2ih HitTestHoleSize, HitTestHoleOffset; ImVec2ih HitTestHoleSize; // Define an optional rectangular hole where mouse will pass-through the window.
ImVec2ih HitTestHoleOffset;
int LastFrameActive; // Last frame number the window was Active. int LastFrameActive; // Last frame number the window was Active.
int LastFrameJustFocused; // Last frame number the window was made Focused. int LastFrameJustFocused; // Last frame number the window was made Focused.
@ -2295,6 +2297,7 @@ IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent);
IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque); IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque);
IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRender1bppRectFromString(ImFontAtlas* atlas, int atlas_x, int atlas_y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor); IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride); IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);

View File

@ -2120,6 +2120,8 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v
} }
if (g.ActiveId != id) if (g.ActiveId != id)
return false; return false;
if (g.CurrentWindow->DC.ItemFlags & ImGuiItemFlags_ReadOnly)
return false;
switch (data_type) switch (data_type)
{ {
@ -2171,7 +2173,6 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
// Tabbing or CTRL-clicking on Drag turns it into an input box // Tabbing or CTRL-clicking on Drag turns it into an input box
const bool hovered = ItemHoverable(frame_bb, id); const bool hovered = ItemHoverable(frame_bb, id);
bool temp_input_is_active = TempInputIsActive(id); bool temp_input_is_active = TempInputIsActive(id);
bool temp_input_start = false;
if (!temp_input_is_active) if (!temp_input_is_active)
{ {
const bool focus_requested = FocusableItemRegister(window, id); const bool focus_requested = FocusableItemRegister(window, id);
@ -2185,14 +2186,14 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
if (focus_requested || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavInputId == id) if (focus_requested || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavInputId == id)
{ {
temp_input_start = true; temp_input_is_active = true;
FocusableItemUnregister(window); FocusableItemUnregister(window);
} }
} }
} }
// Our current specs do NOT clamp when using CTRL+Click manual input, but we should eventually add a flag for that.. // Our current specs do NOT clamp when using CTRL+Click manual input, but we should eventually add a flag for that..
if (temp_input_is_active || temp_input_start) if (temp_input_is_active)
return TempInputScalar(frame_bb, id, label, data_type, p_data, format);// , p_min, p_max); return TempInputScalar(frame_bb, id, label, data_type, p_data, format);// , p_min, p_max);
// Draw frame // Draw frame
@ -2283,10 +2284,17 @@ bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_cu
BeginGroup(); BeginGroup();
PushMultiItemsWidths(2, CalcItemWidth()); PushMultiItemsWidths(2, CalcItemWidth());
bool value_changed = DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), format, power); float min = (v_min >= v_max) ? -FLT_MAX : v_min;
float max = (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max);
if (min == max) { min = FLT_MAX; max = -FLT_MAX; } // Lock edit
bool value_changed = DragScalar("##min", ImGuiDataType_Float, v_current_min, v_speed, &min, &max, format, power);
PopItemWidth(); PopItemWidth();
SameLine(0, g.Style.ItemInnerSpacing.x); SameLine(0, g.Style.ItemInnerSpacing.x);
value_changed |= DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, format_max ? format_max : format, power);
min = (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min);
max = (v_min >= v_max) ? FLT_MAX : v_max;
if (min == max) { min = FLT_MAX; max = -FLT_MAX; } // Lock edit
value_changed |= DragScalar("##max", ImGuiDataType_Float, v_current_max, v_speed, &min, &max, format_max ? format_max : format, power);
PopItemWidth(); PopItemWidth();
SameLine(0, g.Style.ItemInnerSpacing.x); SameLine(0, g.Style.ItemInnerSpacing.x);
@ -2328,10 +2336,17 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_
BeginGroup(); BeginGroup();
PushMultiItemsWidths(2, CalcItemWidth()); PushMultiItemsWidths(2, CalcItemWidth());
bool value_changed = DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), format); int min = (v_min >= v_max) ? INT_MIN : v_min;
int max = (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max);
if (min == max) { min = INT_MAX; max = INT_MIN; } // Lock edit
bool value_changed = DragInt("##min", v_current_min, v_speed, min, max, format);
PopItemWidth(); PopItemWidth();
SameLine(0, g.Style.ItemInnerSpacing.x); SameLine(0, g.Style.ItemInnerSpacing.x);
value_changed |= DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? INT_MAX : v_max, format_max ? format_max : format);
min = (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min);
max = (v_min >= v_max) ? INT_MAX : v_max;
if (min == max) { min = INT_MAX; max = INT_MIN; } // Lock edit
value_changed |= DragInt("##max", v_current_max, v_speed, min, max, format_max ? format_max : format);
PopItemWidth(); PopItemWidth();
SameLine(0, g.Style.ItemInnerSpacing.x); SameLine(0, g.Style.ItemInnerSpacing.x);
@ -2565,6 +2580,10 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
// It would be possible to lift that limitation with some work but it doesn't seem to be worth it for sliders. // It would be possible to lift that limitation with some work but it doesn't seem to be worth it for sliders.
bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb) bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb)
{ {
ImGuiContext& g = *GImGui;
if (g.CurrentWindow->DC.ItemFlags & ImGuiItemFlags_ReadOnly)
return false;
switch (data_type) switch (data_type)
{ {
case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)p_v; bool r = SliderBehaviorT<ImS32, ImS32, float>(bb, id, ImGuiDataType_S32, &v32, *(const ImS8*)p_min, *(const ImS8*)p_max, format, power, flags, out_grab_bb); if (r) *(ImS8*)p_v = (ImS8)v32; return r; } case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)p_v; bool r = SliderBehaviorT<ImS32, ImS32, float>(bb, id, ImGuiDataType_S32, &v32, *(const ImS8*)p_min, *(const ImS8*)p_max, format, power, flags, out_grab_bb); if (r) *(ImS8*)p_v = (ImS8)v32; return r; }
@ -2625,7 +2644,6 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
// Tabbing or CTRL-clicking on Slider turns it into an input box // Tabbing or CTRL-clicking on Slider turns it into an input box
const bool hovered = ItemHoverable(frame_bb, id); const bool hovered = ItemHoverable(frame_bb, id);
bool temp_input_is_active = TempInputIsActive(id); bool temp_input_is_active = TempInputIsActive(id);
bool temp_input_start = false;
if (!temp_input_is_active) if (!temp_input_is_active)
{ {
const bool focus_requested = FocusableItemRegister(window, id); const bool focus_requested = FocusableItemRegister(window, id);
@ -2638,14 +2656,14 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
if (focus_requested || (clicked && g.IO.KeyCtrl) || g.NavInputId == id) if (focus_requested || (clicked && g.IO.KeyCtrl) || g.NavInputId == id)
{ {
temp_input_start = true; temp_input_is_active = true;
FocusableItemUnregister(window); FocusableItemUnregister(window);
} }
} }
} }
// Our current specs do NOT clamp when using CTRL+Click manual input, but we should eventually add a flag for that.. // Our current specs do NOT clamp when using CTRL+Click manual input, but we should eventually add a flag for that..
if (temp_input_is_active || temp_input_start) if (temp_input_is_active)
return TempInputScalar(frame_bb, id, label, data_type, p_data, format);// , p_min, p_max); return TempInputScalar(frame_bb, id, label, data_type, p_data, format);// , p_min, p_max);
// Draw frame // Draw frame