1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-26 12:18:52 -05:00

anchor point prototype

This commit is contained in:
epezent 2020-09-18 13:37:55 -05:00
parent 297c69dae8
commit bbbf4e2a42
3 changed files with 91 additions and 10 deletions

View File

@ -2486,11 +2486,11 @@ ImPlotLimits GetPlotQuery(int y_axis_in) {
bool HorizontalGuide(const char* id, double* value, const ImVec4& col, float thickness) { bool HorizontalGuide(const char* id, double* value, const ImVec4& col, float thickness) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "HorizontalGuide() needs to be called between BeginPlot() and EndPlot()!"); IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "HorizontalGuide() needs to be called between BeginPlot() and EndPlot()!");
const float grab_size = ImMax(6.0f, thickness); const float grab_size = ImMax(5.0f, thickness);
float xl = gp.BB_Plot.Min.x; float xl = gp.BB_Plot.Min.x;
float xr = gp.BB_Plot.Max.x; float xr = gp.BB_Plot.Max.x;
float y = IM_ROUND(PlotToPixels(0, *value).y); float y = IM_ROUND(PlotToPixels(0, *value).y);
const bool outside = (y < gp.BB_Plot.Min.y - grab_size / 2 || y > gp.BB_Plot.Max.y + grab_size / 2); const bool outside = y < (gp.BB_Plot.Min.y - grab_size / 2) || y > (gp.BB_Plot.Max.y + grab_size / 2);
if (outside) if (outside)
return false; return false;
@ -2546,11 +2546,11 @@ bool HorizontalGuide(const char* id, double* value, const ImVec4& col, float thi
bool VerticalGuide(const char* id, double* value, const ImVec4& col, float thickness) { bool VerticalGuide(const char* id, double* value, const ImVec4& col, float thickness) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "VerticalGuide() needs to be called between BeginPlot() and EndPlot()!"); IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "VerticalGuide() needs to be called between BeginPlot() and EndPlot()!");
const float grab_size = ImMax(6.0f, thickness); const float grab_size = ImMax(5.0f, thickness);
float yt = gp.BB_Plot.Min.y; float yt = gp.BB_Plot.Min.y;
float yb = gp.BB_Plot.Max.y; float yb = gp.BB_Plot.Max.y;
float x = IM_ROUND(PlotToPixels(*value,0).x); float x = IM_ROUND(PlotToPixels(*value,0).x);
const bool outside = (x < gp.BB_Plot.Min.x - grab_size / 2 || x > gp.BB_Plot.Max.x + grab_size / 2); const bool outside = x < (gp.BB_Plot.Min.x - grab_size / 2) || x > (gp.BB_Plot.Max.x + grab_size / 2);
if (outside) if (outside)
return false; return false;
@ -2596,6 +2596,55 @@ bool VerticalGuide(const char* id, double* value, const ImVec4& col, float thick
return dragging; return dragging;
} }
bool AnchorPoint(const char* id, double* x, double* y, const ImVec4& col, float radius) {
ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "AnchorPoint() needs to be called between BeginPlot() and EndPlot()!");
const float grab_size = ImMax(5.0f, 2*radius);
const bool outside = !GetPlotLimits().Contains(*x,*y);
if (outside)
return false;
ImVec4 color = IsColorAuto(col) ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : col;
ImU32 col32 = ImGui::ColorConvertFloat4ToU32(color);
ImDrawList& DrawList = *GetPlotDrawList();
ImVec2 pos = PlotToPixels(*x,*y);
PushPlotClipRect();
DrawList.AddCircleFilled(pos, radius, col32);
PopPlotClipRect();
int yax = GetCurrentYAxis();
ImVec2 old_cursor_pos = ImGui::GetCursorScreenPos();
ImVec2 new_cursor_pos = ImVec2(pos - ImVec2(grab_size,grab_size)*0.5f);
ImGui::SetItemAllowOverlap();
ImGui::SetCursorScreenPos(new_cursor_pos);
ImGui::InvisibleButton(id, ImVec2(grab_size, grab_size));
ImGui::SetCursorScreenPos(old_cursor_pos);
if (ImGui::IsItemHovered() || ImGui::IsItemActive()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
// double range_x = gp.XTicks.Size > 1 ? (gp.XTicks.Ticks[1].PlotPos - gp.XTicks.Ticks[0].PlotPos) : gp.CurrentPlot->XAxis.Range.Size();
// char buf[32];
// snprintf(buf, 32, "%s = %.*f", id, Precision(range_x), *value);
// ImVec2 size = ImGui::CalcTextSize(buf);
// const int pad = 2;
// PushPlotClipRect();
// DrawList.AddRectFilled(ImVec2(x - size.x/2 - pad, yb - size.y - 2*pad), ImVec2(x + pad + size.x/2, yb), col32);
// DrawList.AddText(ImVec2(x - size.x/2, yb - size.y - pad), CalcTextColor(color), buf);
// PopPlotClipRect();
}
bool dragging = false;
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0)) {
*x = ImPlot::GetPlotMousePos().x;
*y = ImPlot::GetPlotMousePos().y;
*x = ImClamp(*x, gp.X.Axis->Range.Min, gp.X.Axis->Range.Max);
*y = ImClamp(*y, gp.Y[yax].Axis->Range.Min, gp.Y[yax].Axis->Range.Max);
dragging = true;
}
return dragging;
}
bool IsLegendEntryHovered(const char* label_id) { bool IsLegendEntryHovered(const char* label_id) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "IsPlotItemHighlight() needs to be called between BeginPlot() and EndPlot()!"); IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "IsPlotItemHighlight() needs to be called between BeginPlot() and EndPlot()!");

View File

@ -453,11 +453,6 @@ IMPLOT_API ImPlotPoint GetPlotMousePos(int y_axis = IMPLOT_AUTO);
// Returns the current plot axis range. A negative y_axis uses the current value of SetPlotYAxis (0 initially). // Returns the current plot axis range. A negative y_axis uses the current value of SetPlotYAxis (0 initially).
IMPLOT_API ImPlotLimits GetPlotLimits(int y_axis = IMPLOT_AUTO); IMPLOT_API ImPlotLimits GetPlotLimits(int y_axis = IMPLOT_AUTO);
// Returns true if the current plot is being queried.
IMPLOT_API bool IsPlotQueried();
// Returns the current plot query bounds.
IMPLOT_API ImPlotLimits GetPlotQuery(int y_axis = IMPLOT_AUTO);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Plot Tools // Plot Tools
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -466,6 +461,13 @@ IMPLOT_API ImPlotLimits GetPlotQuery(int y_axis = IMPLOT_AUTO);
IMPLOT_API bool HorizontalGuide(const char* id, double* y_value, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1); IMPLOT_API bool HorizontalGuide(const char* id, double* y_value, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1);
// Shows a draggable vertical guide line. #col defaults to ImGuiCol_Text. // Shows a draggable vertical guide line. #col defaults to ImGuiCol_Text.
IMPLOT_API bool VerticalGuide(const char* id, double* x_value, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1); IMPLOT_API bool VerticalGuide(const char* id, double* x_value, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1);
// Shows a draggable anchor point. #col defaults to ImGuiCol_Text.
IMPLOT_API bool AnchorPoint(const char* id, double* x, double* y, const ImVec4& col = IMPLOT_AUTO_COL, float radius = 5);
// Returns true if the current plot is being queried. Query must be enabled with ImPlotFlags_Query.
IMPLOT_API bool IsPlotQueried();
// Returns the current plot query bounds. Query must be enabled with ImPlotFlags_Query.
IMPLOT_API ImPlotLimits GetPlotQuery(int y_axis = IMPLOT_AUTO);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Legend Utils and Tools // Legend Utils and Tools

View File

@ -805,7 +805,7 @@ void ShowDemoWindow(bool* p_open) {
} }
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Guide Lines")) { if (ImGui::CollapsingHeader("Guides and Anchors")) {
ImGui::BulletText("Click and drag the horizontal and vertical guide lines."); ImGui::BulletText("Click and drag the horizontal and vertical guide lines.");
static double x1 = 0.2; static double x1 = 0.2;
static double x2 = 0.8; static double x2 = 0.8;
@ -829,6 +829,36 @@ void ShowDemoWindow(bool* p_open) {
ImPlot::PlotLine("Why Not?", xs, ys, 1000); ImPlot::PlotLine("Why Not?", xs, ys, 1000);
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
ImGui::BulletText("Click and drag the anchor points.");
ImPlotAxisFlags flags = ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoTickMarks;
ImPlot::SetNextPlotLimits(0,1,0,1,ImGuiCond_Always);
if (ImPlot::BeginPlot("##Bezier",0,0,ImVec2(-1,0),ImPlotFlags_CanvasOnly|ImPlotFlags_NoChild,flags,flags)) {
static ImPlotPoint P[] = {ImPlotPoint(0,0), ImPlotPoint(0.2,0.4), ImPlotPoint(0.8,0.6), ImPlotPoint(1,1)};
static ImPlotPoint B[100];
for (int i = 0; i < 100; ++i) {
double t = i / 99.0;
double u = 1 - t;
double w1 = u*u*u;
double w2 = 3*u*u*t;
double w3 = 3*u*t*t;
double w4 = t*t*t;
B[i] = ImPlotPoint(w1*P[0].x + w2*P[1].x + w3*P[2].x + w4*P[3].x, w1*P[0].y + w2*P[1].y + w3*P[2].y + w4*P[3].y);
}
static ImVec4 gray = ImVec4(0.5f,0.5f,0.5f,1.0f);
ImPlot::SetNextFillStyle(ImVec4(0,1,0,0.25f));
ImPlot::PlotShaded("##bez",&B[0].x, &B[0].y, 100, 0, 0, sizeof(ImPlotPoint));
ImPlot::SetNextLineStyle(ImVec4(0,1,0,1), 2);
ImPlot::PlotLine("##bez",&B[0].x, &B[0].y, 100, 0, sizeof(ImPlotPoint));
ImPlot::SetNextLineStyle(gray, 2);
ImPlot::PlotLine("##h1",&P[0].x, &P[0].y, 2, 0, sizeof(ImPlotPoint));
ImPlot::SetNextLineStyle(gray, 2);
ImPlot::PlotLine("##h2",&P[2].x, &P[2].y, 2, 0, sizeof(ImPlotPoint));
ImPlot::AnchorPoint("P0",&P[0].x,&P[0].y,gray);
ImPlot::AnchorPoint("P1",&P[1].x,&P[1].y,gray);
ImPlot::AnchorPoint("P2",&P[2].x,&P[2].y,gray);
ImPlot::AnchorPoint("P3",&P[3].x,&P[3].y,gray);
ImPlot::EndPlot();
}
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Drag and Drop")) { if (ImGui::CollapsingHeader("Drag and Drop")) {