1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-26 20:28:50 -05:00

finish guides

This commit is contained in:
epezent 2020-09-17 23:31:16 -05:00
parent c6aff1362c
commit 4ed7d01637
3 changed files with 75 additions and 29 deletions

View File

@ -2486,26 +2486,48 @@ 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 = 2*thickness; const float grab_size = ImMax(6.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 = PlotToPixels(0, *value).y; float y = IM_ROUND(PlotToPixels(0, *value).y);
ImU32 col32 = IsColorAuto(col) ? GetStyleColorU32(ImPlotCol_Query) : ImGui::ColorConvertFloat4ToU32(col);
PushPlotClipRect();
GetPlotDrawList()->AddLine(ImVec2(xl,y), ImVec2(xr,y), col32, thickness);
PopPlotClipRect();
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;
float len = gp.Style.MajorTickLen.y;
ImVec4 color = IsColorAuto(col) ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : col;
ImU32 col32 = ImGui::ColorConvertFloat4ToU32(color);
ImDrawList& DrawList = *GetPlotDrawList();
PushPlotClipRect();
DrawList.AddLine(ImVec2(xl,y), ImVec2(xr,y), col32, thickness);
DrawList.AddLine(ImVec2(xl,y), ImVec2(xl+len,y), col32, 3*thickness);
DrawList.AddLine(ImVec2(xr,y), ImVec2(xr-len,y), col32, 3*thickness);
ImVec2 old_cursor_pos = ImGui::GetCursorScreenPos(); ImVec2 old_cursor_pos = ImGui::GetCursorScreenPos();
ImVec2 new_cursor_pos = ImVec2(xl, y - grab_size / 2.0f); ImVec2 new_cursor_pos = ImVec2(xl, y - grab_size / 2.0f);
ImGui::SetItemAllowOverlap(); ImGui::SetItemAllowOverlap();
ImGui::SetCursorScreenPos(new_cursor_pos); ImGui::SetCursorScreenPos(new_cursor_pos);
ImGui::InvisibleButton(id, ImVec2(xr - xl, grab_size)); ImGui::InvisibleButton(id, ImVec2(xr - xl, grab_size));
ImGui::SetCursorScreenPos(old_cursor_pos); ImGui::SetCursorScreenPos(old_cursor_pos);
if (ImGui::IsItemHovered() || ImGui::IsItemActive()) { if (ImGui::IsItemHovered() || ImGui::IsItemActive()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS); ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
int yax = GetCurrentYAxis();
double range_y = gp.YTicks[yax].Size > 1 ? (gp.YTicks[yax].Ticks[1].PlotPos - gp.YTicks[yax].Ticks[0].PlotPos) : gp.CurrentPlot->YAxis[yax].Range.Size();
char buf[32];
snprintf(buf, 32, "%s = %.*f", id, Precision(range_y), *value);
ImVec2 size = ImGui::CalcTextSize(buf);
const int pad = 2;
if (yax == 0) {
DrawList.AddRectFilled(ImVec2(xl,y-pad-size.y/2), ImVec2(xl + size.x + 2 * pad, y+pad+size.y/2), col32);
DrawList.AddText(ImVec2(xl+pad,y-size.y/2),CalcTextColor(color),buf);
}
else {
DrawList.AddRectFilled(ImVec2(xr-size.x-2*pad,y-pad-size.y/2), ImVec2(xr, y+pad+size.y/2), col32);
DrawList.AddText(ImVec2(xr-size.x-pad,y-size.y/2),CalcTextColor(color),buf);
}
} }
PopPlotClipRect();
bool dragging = false; bool dragging = false;
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0)) { if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0)) {
*value = ImPlot::GetPlotMousePos().y; *value = ImPlot::GetPlotMousePos().y;
@ -2517,26 +2539,41 @@ 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 = 2*thickness; const float grab_size = ImMax(6.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 = PlotToPixels(*value,0).x; float x = IM_ROUND(PlotToPixels(*value,0).x);
ImU32 col32 = IsColorAuto(col) ? GetStyleColorU32(ImPlotCol_Query) : ImGui::ColorConvertFloat4ToU32(col);
PushPlotClipRect();
GetPlotDrawList()->AddLine(ImVec2(x,yt), ImVec2(x,yb), col32, thickness);
PopPlotClipRect();
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;
float len = gp.Style.MajorTickLen.x;
ImVec4 color = IsColorAuto(col) ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : col;
ImU32 col32 = ImGui::ColorConvertFloat4ToU32(color);
ImDrawList& DrawList = *GetPlotDrawList();
PushPlotClipRect();
DrawList.AddLine(ImVec2(x,yt), ImVec2(x,yb), col32, thickness);
DrawList.AddLine(ImVec2(x,yt), ImVec2(x,yt+len), col32, 3*thickness);
DrawList.AddLine(ImVec2(x,yb), ImVec2(x,yb-len), col32, 3*thickness);
ImVec2 old_cursor_pos = ImGui::GetCursorScreenPos(); ImVec2 old_cursor_pos = ImGui::GetCursorScreenPos();
ImVec2 new_cursor_pos = ImVec2(x - grab_size / 2.0f, yt); ImVec2 new_cursor_pos = ImVec2(x - grab_size / 2.0f, yt);
ImGui::SetItemAllowOverlap(); ImGui::SetItemAllowOverlap();
ImGui::SetCursorScreenPos(new_cursor_pos); ImGui::SetCursorScreenPos(new_cursor_pos);
ImGui::InvisibleButton(id, ImVec2(grab_size, yb-yt)); ImGui::InvisibleButton(id, ImVec2(grab_size, yb-yt));
ImGui::SetCursorScreenPos(old_cursor_pos); ImGui::SetCursorScreenPos(old_cursor_pos);
if (ImGui::IsItemHovered() || ImGui::IsItemActive()) { if (ImGui::IsItemHovered() || ImGui::IsItemActive()) {
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
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;
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; bool dragging = false;
if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0)) { if (ImGui::IsItemActive() && ImGui::IsMouseDragging(0)) {
*value = ImPlot::GetPlotMousePos().x; *value = ImPlot::GetPlotMousePos().x;

View File

@ -463,10 +463,10 @@ IMPLOT_API bool IsPlotQueried();
// Returns the current plot query bounds. // Returns the current plot query bounds.
IMPLOT_API ImPlotLimits GetPlotQuery(int y_axis = IMPLOT_AUTO); IMPLOT_API ImPlotLimits GetPlotQuery(int y_axis = IMPLOT_AUTO);
// Shows a draggable horizontal guide line. // Shows a draggable horizontal guide line. #col defaults to ImGuiCol_Text.
IMPLOT_API bool HorizontalGuide(const char* id, double* value, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 2); 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. // Shows a draggable vertical guide line. #col defaults to ImGuiCol_Text.
IMPLOT_API bool VerticalGuide(const char* id, double* value, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 2); IMPLOT_API bool VerticalGuide(const char* id, double* x_value, const ImVec4& col = IMPLOT_AUTO_COL, float thickness = 1);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Plot and Item Styling // Plot and Item Styling

View File

@ -806,18 +806,27 @@ void ShowDemoWindow(bool* p_open) {
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
if (ImGui::CollapsingHeader("Guide Lines")) { if (ImGui::CollapsingHeader("Guide Lines")) {
static double v1 = 0.2; ImGui::BulletText("Click and drag the horizontal and vertical guide lines.");
static double v2 = 0.6; static double x1 = 0.2;
static double h1 = 0.25; static double x2 = 0.8;
static double h2 = 0.75; static double y1 = 0.25;
static double h3 = 0.5; static double y2 = 0.75;
if (ImPlot::BeginPlot("##guides",0,0,ImVec2(-1,0),ImPlotFlags_YAxis2)) { static double f = 0.1;
ImPlot::VerticalGuide("v1",&v1, ImVec4(0,1,0,1)); if (ImPlot::BeginPlot("##guides",0,0,ImVec2(-1,0),ImPlotFlags_YAxis2)) {
ImPlot::VerticalGuide("v2",&v2, ImVec4(0,1,0,1)); ImPlot::VerticalGuide("x1",&x1);
ImPlot::HorizontalGuide("h1",&h1, ImVec4(1,0,0,1)); ImPlot::VerticalGuide("x2",&x2);
ImPlot::HorizontalGuide("h2",&h2, ImVec4(1,0,0,1)); ImPlot::HorizontalGuide("y1",&y1);
ImPlot::HorizontalGuide("y2",&y2);
ImPlot::SetPlotYAxis(1); ImPlot::SetPlotYAxis(1);
ImPlot::HorizontalGuide("h3",&h3, ImVec4(1,1,0,1)); ImPlot::HorizontalGuide("f",&f, ImVec4(1,0.5f,1,1));
ImPlot::SetPlotYAxis(0);
double xs[1000], ys[1000];
for (int i = 0; i < 1000; ++i) {
xs[i] = (x2+x1)/2+abs(x2-x1)*(i/990.0f - 0.5f);
ys[i] = (y1+y2)/2+abs(y2-y1)/2*sin(f*i/10);
}
ImPlot::PlotLine("Why Not?", xs, ys, 1000);
ImPlot::EndPlot(); ImPlot::EndPlot();
} }
} }