diff --git a/implot.cpp b/implot.cpp index 5d3b635..3f5c699 100644 --- a/implot.cpp +++ b/implot.cpp @@ -31,6 +31,7 @@ Below is a change-log of API breaking changes only. If you are using one of the When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all implot files. You can read releases logs https://github.com/epezent/implot/releases for more details. +- 2020/08/28 (0.5) - ImPlotMarker_ can no longer be combined with bitwise OR, |. This features caused unecessary slow-down, and almost no one used it. - 2020/08/25 (0.5) - ImPlotAxisFlags_Scientific was removed. Logarithmic axes automatically uses scientific notation. - 2020/08/17 (0.5) - PlotText was changed so that text is centered horizontally and vertically about the desired point. - 2020/08/16 (0.5) - An ImPlotContext must be explicitly created and destroyed now with `CreateContext` and `DestroyContext`. Previously, the context was statically initialized in this source file. @@ -1433,24 +1434,26 @@ void EndPlot() { // render selection/query if (plot.Selecting) { ImRect select_bb(ImMin(IO.MousePos, plot.SelectStart), ImMax(IO.MousePos, plot.SelectStart)); - const bool select_big_enough = ImLengthSqr(select_bb.GetSize()) > 4; - if (plot.Selecting && !gp.LockPlot && ImHasFlag(plot.Flags, ImPlotFlags_BoxSelect) && select_big_enough) { + bool wide_enough = select_bb.GetWidth() > 2; + bool tall_enough = select_bb.GetWidth() > 2; + bool big_enough = wide_enough && tall_enough; + if (plot.Selecting && !gp.LockPlot && ImHasFlag(plot.Flags, ImPlotFlags_BoxSelect)) { const ImVec4 col = GetStyleColorVec4(ImPlotCol_Selection); const ImU32 col_bg = ImGui::GetColorU32(col * ImVec4(1,1,1,0.25f)); const ImU32 col_bd = ImGui::GetColorU32(col); - if (IO.KeyAlt && IO.KeyShift) { + if (IO.KeyMods == (gp.InputMap.HorizontalMod | gp.InputMap.VerticalMod) && big_enough) { DrawList.AddRectFilled(gp.BB_Plot.Min, gp.BB_Plot.Max, col_bg); DrawList.AddRect( gp.BB_Plot.Min, gp.BB_Plot.Max, col_bd); } - else if ((gp.X.Lock || IO.KeyAlt)) { + else if ((gp.X.Lock || IO.KeyMods == gp.InputMap.HorizontalMod) && big_enough) { DrawList.AddRectFilled(ImVec2(gp.BB_Plot.Min.x, select_bb.Min.y), ImVec2(gp.BB_Plot.Max.x, select_bb.Max.y), col_bg); DrawList.AddRect( ImVec2(gp.BB_Plot.Min.x, select_bb.Min.y), ImVec2(gp.BB_Plot.Max.x, select_bb.Max.y), col_bd); } - else if ((any_y_locked || IO.KeyShift)) { + else if ((any_y_locked || IO.KeyMods == gp.InputMap.VerticalMod) && big_enough) { DrawList.AddRectFilled(ImVec2(select_bb.Min.x, gp.BB_Plot.Min.y), ImVec2(select_bb.Max.x, gp.BB_Plot.Max.y), col_bg); DrawList.AddRect( ImVec2(select_bb.Min.x, gp.BB_Plot.Min.y), ImVec2(select_bb.Max.x, gp.BB_Plot.Max.y), col_bd); } - else { + else if (big_enough) { DrawList.AddRectFilled(select_bb.Min, select_bb.Max, col_bg); DrawList.AddRect( select_bb.Min, select_bb.Max, col_bd); } diff --git a/implot.h b/implot.h index 2635a26..378b45c 100644 --- a/implot.h +++ b/implot.h @@ -131,19 +131,20 @@ enum ImPlotStyleVar_ { ImPlotStyleVar_COUNT }; -// Marker specifications. You can combine these with binary OR, e.g. ImPlotMarker_Circle | ImPlotMarker_Cross. +// Marker specifications. enum ImPlotMarker_ { - ImPlotMarker_None = 1 << 0, // no marker - ImPlotMarker_Circle = 1 << 1, // a circle marker - ImPlotMarker_Square = 1 << 2, // a square maker - ImPlotMarker_Diamond = 1 << 3, // a diamond marker - ImPlotMarker_Up = 1 << 4, // an upward-pointing triangle marker - ImPlotMarker_Down = 1 << 5, // an downward-pointing triangle marker - ImPlotMarker_Left = 1 << 6, // an leftward-pointing triangle marker - ImPlotMarker_Right = 1 << 7, // an rightward-pointing triangle marker - ImPlotMarker_Cross = 1 << 8, // a cross marker (not fillable) - ImPlotMarker_Plus = 1 << 9, // a plus marker (not fillable) - ImPlotMarker_Asterisk = 1 << 10, // a asterisk marker (not fillable) + ImPlotMarker_None, // no marker + ImPlotMarker_Circle, // a circle marker + ImPlotMarker_Square, // a square maker + ImPlotMarker_Diamond, // a diamond marker + ImPlotMarker_Up, // an upward-pointing triangle marker + ImPlotMarker_Down, // an downward-pointing triangle marker + ImPlotMarker_Left, // an leftward-pointing triangle marker + ImPlotMarker_Right, // an rightward-pointing triangle marker + ImPlotMarker_Cross, // a cross marker (not fillable) + ImPlotMarker_Plus, // a plus marker (not fillable) + ImPlotMarker_Asterisk, // a asterisk marker (not fillable) + ImPlotMarker_COUNT }; // Built-in colormaps diff --git a/implot_demo.cpp b/implot_demo.cpp index fcc9b37..19211c1 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -537,10 +537,9 @@ void ShowDemoWindow(bool* p_open) { ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, mk_size); ImPlot::PushStyleVar(ImPlotStyleVar_MarkerWeight, mk_weight); // filled markers - for (int i = 1; i < 11; ++i) { - ImPlotMarker marker = 1 << i; // e.g. ImPlotMarkerCircle = 1 << 1 (see implot.h) - ImPlot::PushStyleVar(ImPlotStyleVar_Marker, marker); - ImGui::PushID(i); + for (int m = 1; m < ImPlotMarker_COUNT; ++m) { + ImPlot::PushStyleVar(ImPlotStyleVar_Marker, m); + ImGui::PushID(m); ImPlot::PlotLine("##Filled", xs, ys, 2); ImGui::PopID(); ImPlot::PopStyleVar(); @@ -549,10 +548,9 @@ void ShowDemoWindow(bool* p_open) { xs[0] = 6; xs[1] = 9; ys[0] = 10; ys[1] = 11; // open markers ImPlot::PushStyleColor(ImPlotCol_MarkerFill, ImVec4(0,0,0,0)); - for (int i = 1; i < 11; ++i) { - ImPlotMarker marker = 1 << i; // e.g. ImPlotMarkerCircle = 1 << 1 (see implot.h) - ImPlot::PushStyleVar(ImPlotStyleVar_Marker, marker); - ImGui::PushID(i); + for (int m = 1; m < ImPlotMarker_COUNT; ++m) { + ImPlot::PushStyleVar(ImPlotStyleVar_Marker, m); + ImGui::PushID(m); ImPlot::PlotLine("##Open", xs, ys, 2); ImGui::PopID(); ImPlot::PopStyleVar(); @@ -561,23 +559,11 @@ void ShowDemoWindow(bool* p_open) { ImPlot::PopStyleColor(); ImPlot::PopStyleVar(2); - xs[0] = 5; xs[1] = 5; ys[0] = 1; ys[1] = 11; - ImPlot::PushStyleVar(ImPlotStyleVar_LineWeight, 2); - ImPlot::PushStyleVar(ImPlotStyleVar_MarkerSize, 8); - ImPlot::PushStyleVar(ImPlotStyleVar_MarkerWeight, 2); - ImPlot::PushStyleVar(ImPlotStyleVar_Marker, ImPlotMarker_Circle | ImPlotMarker_Cross); - ImPlot::PushStyleColor(ImPlotCol_MarkerOutline, ImVec4(0,0,0,1)); - ImPlot::PushStyleColor(ImPlotCol_MarkerFill, ImVec4(1,1,1,1)); - ImPlot::PushStyleColor(ImPlotCol_Line, ImVec4(0,0,0,1)); - ImPlot::PlotLine("Circle|Cross", xs, ys, 2); - ImPlot::PopStyleVar(4); - ImPlot::PopStyleColor(3); - ImPlot::PlotText("Filled Markers", 2.5f, 6.0f); ImPlot::PlotText("Open Markers", 7.5f, 6.0f); ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1,0,1,1)); - ImPlot::PlotText("Fancy Markers", 5.0f, 6.0f, true); + ImPlot::PlotText("Vertical Magneta Text", 5.0f, 6.0f, true); ImGui::PopStyleColor(); ImPlot::EndPlot(); diff --git a/implot_internal.h b/implot_internal.h index 40f4907..294b454 100644 --- a/implot_internal.h +++ b/implot_internal.h @@ -283,20 +283,22 @@ struct ImPlotAxisColor // State information for Plot items struct ImPlotItem { - ImGuiID ID; - ImVec4 Color; - bool Show; - bool Highlight; - bool SeenThisFrame; - int NameOffset; + ImGuiID ID; + ImVec4 Color; + ImPlotMarker Marker; + int NameOffset; + bool Show; + bool Highlight; + bool SeenThisFrame; ImPlotItem() { ID = 0; Color = ImPlot::NextColormapColor(); + Marker = ImPlotMarker_None; + NameOffset = -1; Show = true; SeenThisFrame = false; Highlight = false; - NameOffset = -1; } ~ImPlotItem() { ID = 0; } @@ -319,6 +321,7 @@ struct ImPlotState bool Queried; bool DraggingQuery; int ColormapIdx; + int MarkerIdx; int CurrentYAxis; ImPlotState() { diff --git a/implot_items.cpp b/implot_items.cpp index 17af817..28192a2 100644 --- a/implot_items.cpp +++ b/implot_items.cpp @@ -506,7 +506,7 @@ inline void TransformMarker(ImVec2* points, int n, const ImVec2& c, float s) { } } -inline void MarkerGeneral(ImDrawList& DrawList, ImVec2* points, int n, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { +inline void RenderMarkerGeneral(ImDrawList& DrawList, ImVec2* points, int n, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { TransformMarker(points, n, c, s); if (fill) DrawList.AddConvexPolyFilled(points, n, col_fill); @@ -516,7 +516,7 @@ inline void MarkerGeneral(ImDrawList& DrawList, ImVec2* points, int n, const ImV } } -inline void MarkerCircle(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { +inline void RenderMarkerCircle(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { ImVec2 marker[10] = {ImVec2(1.0f, 0.0f), ImVec2(0.809017f, 0.58778524f), ImVec2(0.30901697f, 0.95105654f), @@ -527,40 +527,40 @@ inline void MarkerCircle(ImDrawList& DrawList, const ImVec2& c, float s, bool ou ImVec2(-0.3090171f, -0.9510565f), ImVec2(0.30901712f, -0.9510565f), ImVec2(0.80901694f, -0.5877853f)}; - MarkerGeneral(DrawList, marker, 10, c, s, outline, col_outline, fill, col_fill, weight); + RenderMarkerGeneral(DrawList, marker, 10, c, s, outline, col_outline, fill, col_fill, weight); } -inline void MarkerDiamond(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { +inline void RenderMarkerDiamond(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { ImVec2 marker[4] = {ImVec2(1, 0), ImVec2(0, -1), ImVec2(-1, 0), ImVec2(0, 1)}; - MarkerGeneral(DrawList, marker, 4, c, s, outline, col_outline, fill, col_fill, weight); + RenderMarkerGeneral(DrawList, marker, 4, c, s, outline, col_outline, fill, col_fill, weight); } -inline void MarkerSquare(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { +inline void RenderMarkerSquare(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { ImVec2 marker[4] = {ImVec2(SQRT_1_2,SQRT_1_2),ImVec2(SQRT_1_2,-SQRT_1_2),ImVec2(-SQRT_1_2,-SQRT_1_2),ImVec2(-SQRT_1_2,SQRT_1_2)}; - MarkerGeneral(DrawList, marker, 4, c, s, outline, col_outline, fill, col_fill, weight); + RenderMarkerGeneral(DrawList, marker, 4, c, s, outline, col_outline, fill, col_fill, weight); } -inline void MarkerUp(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { +inline void RenderMarkerUp(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { ImVec2 marker[3] = {ImVec2(SQRT_3_2,0.5f),ImVec2(0,-1),ImVec2(-SQRT_3_2,0.5f)}; - MarkerGeneral(DrawList, marker, 3, c, s, outline, col_outline, fill, col_fill, weight); + RenderMarkerGeneral(DrawList, marker, 3, c, s, outline, col_outline, fill, col_fill, weight); } -inline void MarkerDown(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { +inline void RenderMarkerDown(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { ImVec2 marker[3] = {ImVec2(SQRT_3_2,-0.5f),ImVec2(0,1),ImVec2(-SQRT_3_2,-0.5f)}; - MarkerGeneral(DrawList, marker, 3, c, s, outline, col_outline, fill, col_fill, weight); + RenderMarkerGeneral(DrawList, marker, 3, c, s, outline, col_outline, fill, col_fill, weight); } -inline void MarkerLeft(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { +inline void RenderMarkerLeft(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { ImVec2 marker[3] = {ImVec2(-1,0), ImVec2(0.5, SQRT_3_2), ImVec2(0.5, -SQRT_3_2)}; - MarkerGeneral(DrawList, marker, 3, c, s, outline, col_outline, fill, col_fill, weight); + RenderMarkerGeneral(DrawList, marker, 3, c, s, outline, col_outline, fill, col_fill, weight); } -inline void MarkerRight(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { +inline void RenderMarkerRight(ImDrawList& DrawList, const ImVec2& c, float s, bool outline, ImU32 col_outline, bool fill, ImU32 col_fill, float weight) { ImVec2 marker[3] = {ImVec2(1,0), ImVec2(-0.5, SQRT_3_2), ImVec2(-0.5, -SQRT_3_2)}; - MarkerGeneral(DrawList, marker, 3, c, s, outline, col_outline, fill, col_fill, weight); + RenderMarkerGeneral(DrawList, marker, 3, c, s, outline, col_outline, fill, col_fill, weight); } -inline void MarkerAsterisk(ImDrawList& DrawList, const ImVec2& c, float s, bool /*outline*/, ImU32 col_outline, bool /*fill*/, ImU32 /*col_fill*/, float weight) { +inline void RenderMarkerAsterisk(ImDrawList& DrawList, const ImVec2& c, float s, bool /*outline*/, ImU32 col_outline, bool /*fill*/, ImU32 /*col_fill*/, float weight) { ImVec2 marker[6] = {ImVec2(SQRT_3_2, 0.5f), ImVec2(0, -1), ImVec2(-SQRT_3_2, 0.5f), ImVec2(SQRT_3_2, -0.5f), ImVec2(0, 1), ImVec2(-SQRT_3_2, -0.5f)}; TransformMarker(marker, 6, c, s); DrawList.AddLine(marker[0], marker[5], col_outline, weight); @@ -568,14 +568,14 @@ inline void MarkerAsterisk(ImDrawList& DrawList, const ImVec2& c, float s, bool DrawList.AddLine(marker[2], marker[3], col_outline, weight); } -inline void MarkerPlus(ImDrawList& DrawList, const ImVec2& c, float s, bool /*outline*/, ImU32 col_outline, bool /*fill*/, ImU32 /*col_fill*/, float weight) { +inline void RenderMarkerPlus(ImDrawList& DrawList, const ImVec2& c, float s, bool /*outline*/, ImU32 col_outline, bool /*fill*/, ImU32 /*col_fill*/, float weight) { ImVec2 marker[4] = {ImVec2(1, 0), ImVec2(0, -1), ImVec2(-1, 0), ImVec2(0, 1)}; TransformMarker(marker, 4, c, s); DrawList.AddLine(marker[0], marker[2], col_outline, weight); DrawList.AddLine(marker[1], marker[3], col_outline, weight); } -inline void MarkerCross(ImDrawList& DrawList, const ImVec2& c, float s, bool /*outline*/, ImU32 col_outline, bool /*fill*/, ImU32 /*col_fill*/, float weight) { +inline void RenderMarkerCross(ImDrawList& DrawList, const ImVec2& c, float s, bool /*outline*/, ImU32 col_outline, bool /*fill*/, ImU32 /*col_fill*/, float weight) { ImVec2 marker[4] = {ImVec2(SQRT_1_2,SQRT_1_2),ImVec2(SQRT_1_2,-SQRT_1_2),ImVec2(-SQRT_1_2,-SQRT_1_2),ImVec2(-SQRT_1_2,SQRT_1_2)}; TransformMarker(marker, 4, c, s); DrawList.AddLine(marker[0], marker[2], col_outline, weight); @@ -584,32 +584,24 @@ inline void MarkerCross(ImDrawList& DrawList, const ImVec2& c, float s, bool /*o template inline void RenderMarkers(Getter getter, Transformer transformer, ImDrawList& DrawList, bool rend_mk_line, ImU32 col_mk_line, bool rend_mk_fill, ImU32 col_mk_fill) { + static void (*marker_table[])(ImDrawList&, const ImVec2&, float s, bool, ImU32, bool, ImU32, float) = { + NULL, + RenderMarkerCircle, + RenderMarkerSquare, + RenderMarkerDiamond , + RenderMarkerUp , + RenderMarkerDown , + RenderMarkerLeft, + RenderMarkerRight, + RenderMarkerCross, + RenderMarkerPlus, + RenderMarkerAsterisk + }; ImPlotContext& gp = *GImPlot; for (int i = 0; i < getter.Count; ++i) { ImVec2 c = transformer(getter(i)); - if (gp.BB_Plot.Contains(c)) { - // TODO: Optimize the loop and if statements, this is atrocious - if (ImHasFlag(gp.Style.Marker, ImPlotMarker_Circle)) - MarkerCircle(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); - if (ImHasFlag(gp.Style.Marker, ImPlotMarker_Square)) - MarkerSquare(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); - if (ImHasFlag(gp.Style.Marker, ImPlotMarker_Diamond)) - MarkerDiamond(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); - if (ImHasFlag(gp.Style.Marker, ImPlotMarker_Up)) - MarkerUp(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); - if (ImHasFlag(gp.Style.Marker, ImPlotMarker_Down)) - MarkerDown(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); - if (ImHasFlag(gp.Style.Marker, ImPlotMarker_Left)) - MarkerLeft(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); - if (ImHasFlag(gp.Style.Marker, ImPlotMarker_Right)) - MarkerRight(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); - if (ImHasFlag(gp.Style.Marker, ImPlotMarker_Cross)) - MarkerCross(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); - if (ImHasFlag(gp.Style.Marker, ImPlotMarker_Plus)) - MarkerPlus(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); - if (ImHasFlag(gp.Style.Marker, ImPlotMarker_Asterisk)) - MarkerAsterisk(DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); - } + if (gp.BB_Plot.Contains(c)) + marker_table[gp.Style.Marker](DrawList, c, gp.Style.MarkerSize, rend_mk_line, col_mk_line, rend_mk_fill, col_mk_fill, gp.Style.MarkerWeight); } }