From 0e741036599a1d53b8b4e6f954567f1b3e5cf949 Mon Sep 17 00:00:00 2001 From: Ben Carter Date: Mon, 9 Dec 2019 15:13:24 +0900 Subject: [PATCH] ImDrawList: Add AddNgon(), AddNgonFilled() API. --- docs/CHANGELOG.txt | 4 ++++ imgui.h | 2 ++ imgui_demo.cpp | 6 ++++-- imgui_draw.cpp | 24 ++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 5cd00a75..0c43b000 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -60,6 +60,10 @@ Other Changes: - Inputs: Added ImGuiMouseButton enum for convenience (e.g. ImGuiMouseButton_Right=1). We forever guarantee that the existing value will not changes so existing code is free to use 0/1/2. - Misc: Added ImGuiMouseCursor_NotAllowed enum so it can be used by more shared widgets. [@rokups] +- ImDrawList: Add AddNgon(), AddNgonFilled() API with a guarantee on the explicit segment count. + In the current branch they are essentially the same as AddCircle(), AddCircleFilled() but as + we will rework the circle rendering functions to use textures and automatic segment count + selection, those new api can fill a gap. [@ShironekoBen] - Backends: GLFW, SDL, Win32, OSX, Allegro: Added support for ImGuiMouseCursor_NotAllowed. [@rokups] - Backends: GLFW: Added support for the missing mouse cursors newly added in GLFW 3.4+. [@rokups] - Examples: Explicitly adding -DIMGUI_IMPL_OPENGL_LOADER_GL3W to Makefile to match linking diff --git a/imgui.h b/imgui.h index 0eef98d9..f77adb4a 100644 --- a/imgui.h +++ b/imgui.h @@ -1934,6 +1934,8 @@ struct ImDrawList 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 AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 12); + 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 AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index af2e46cc..c15b5a63 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -4440,9 +4440,11 @@ static void ShowExampleAppCustomRendering(bool* p_open) { static float sz = 36.0f; static float thickness = 3.0f; + static int ngon_sides = 6; static ImVec4 colf = ImVec4(1.0f, 1.0f, 0.4f, 1.0f); ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f"); ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f"); + ImGui::SliderInt("n-gon sides", &ngon_sides, 3, 12); ImGui::ColorEdit4("Color", &colf.x); const ImVec2 p = ImGui::GetCursorScreenPos(); const ImU32 col = ImColor(colf); @@ -4455,7 +4457,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) { // First line uses a thickness of 1.0f, second line uses the configurable thickness float th = (n == 0) ? 1.0f : thickness; - draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, 6, th); x += sz + spacing; // Hexagon + draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // n-gon draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, 20, th); x += sz + spacing; // Circle draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, corners_none, th); x += sz + spacing; // Square draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_all, th); x += sz + spacing; // Square with all rounded corners @@ -4469,7 +4471,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) x = p.x + 4; y += sz + spacing; } - draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, 6); x += sz + spacing; // Hexagon + draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // n-gon draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, 32); x += sz + spacing; // Circle draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 18029f4d..9efb4731 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1104,6 +1104,30 @@ void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, PathFillConvex(col); } +// Guaranteed to honor 'num_segments' +void ImDrawList::AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0 || num_segments <= 2) + return; + + // Because we are filling a closed shape we remove 1 from the count of segments/points + const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments; + PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1); + PathStroke(col, true, thickness); +} + +// Guaranteed to honor 'num_segments' +void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments) +{ + if ((col & IM_COL32_A_MASK) == 0 || num_segments <= 2) + return; + + // Because we are filling a closed shape we remove 1 from the count of segments/points + const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments; + PathArcTo(center, radius, 0.0f, a_max, num_segments - 1); + PathFillConvex(col); +} + void ImDrawList::AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments) { if ((col & IM_COL32_A_MASK) == 0)