Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 76 additions & 55 deletions implot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3973,6 +3973,7 @@ bool DragPoint(int n_id, double* x, double* y, const ImVec4& col, float radius,
const bool input = !ImHasFlag(flags, ImPlotDragToolFlags_NoInputs);
const bool show_curs = !ImHasFlag(flags, ImPlotDragToolFlags_NoCursors);
const bool no_delay = !ImHasFlag(flags, ImPlotDragToolFlags_Delayed);
const bool move_allowed = !ImHasFlag(flags, ImPlotDragToolFlags_NoMove);
const float grab_half_size = ImMax(DRAG_GRAB_HALF_SIZE, radius);
const ImVec4 color = IsColorAuto(col) ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : col;
const ImU32 col32 = ImGui::ColorConvertFloat4ToU32(color);
Expand All @@ -3984,14 +3985,15 @@ bool DragPoint(int n_id, double* x, double* y, const ImVec4& col, float radius,

ImGui::KeepAliveID(id);
if (input) {
rect.ClipWithFull(GImPlot->CurrentPlot->PlotRect);
bool clicked = ImGui::ButtonBehavior(rect,id,&hovered,&held);
if (out_clicked) *out_clicked = clicked;
if (out_hovered) *out_hovered = hovered;
if (out_held) *out_held = held;
}

bool modified = false;
if (held && ImGui::IsMouseDragging(0)) {
if (move_allowed && held && ImGui::IsMouseDragging(0)) {
*x = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).x;
*y = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).y;
modified = true;
Expand Down Expand Up @@ -4023,6 +4025,8 @@ bool DragLineX(int n_id, double* value, const ImVec4& col, float thickness, ImPl
const bool input = !ImHasFlag(flags, ImPlotDragToolFlags_NoInputs);
const bool show_curs = !ImHasFlag(flags, ImPlotDragToolFlags_NoCursors);
const bool no_delay = !ImHasFlag(flags, ImPlotDragToolFlags_Delayed);
const bool move_allowed = !ImHasFlag(flags, ImPlotDragToolFlags_NoMove);

const float grab_half_size = ImMax(DRAG_GRAB_HALF_SIZE, thickness/2);
float yt = gp.CurrentPlot->PlotRect.Min.y;
float yb = gp.CurrentPlot->PlotRect.Max.y;
Expand All @@ -4033,6 +4037,7 @@ bool DragLineX(int n_id, double* value, const ImVec4& col, float thickness, ImPl

ImGui::KeepAliveID(id);
if (input) {
rect.ClipWithFull(GImPlot->CurrentPlot->PlotRect);
bool clicked = ImGui::ButtonBehavior(rect,id,&hovered,&held);
if (out_clicked) *out_clicked = clicked;
if (out_hovered) *out_hovered = hovered;
Expand All @@ -4047,7 +4052,7 @@ bool DragLineX(int n_id, double* value, const ImVec4& col, float thickness, ImPl
ImU32 col32 = ImGui::ColorConvertFloat4ToU32(color);

bool modified = false;
if (held && ImGui::IsMouseDragging(0)) {
if (move_allowed && held && ImGui::IsMouseDragging(0)) {
*value = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).x;
modified = true;
}
Expand Down Expand Up @@ -4078,6 +4083,8 @@ bool DragLineY(int n_id, double* value, const ImVec4& col, float thickness, ImPl
const bool input = !ImHasFlag(flags, ImPlotDragToolFlags_NoInputs);
const bool show_curs = !ImHasFlag(flags, ImPlotDragToolFlags_NoCursors);
const bool no_delay = !ImHasFlag(flags, ImPlotDragToolFlags_Delayed);
const bool move_allowed = !ImHasFlag(flags, ImPlotDragToolFlags_NoMove);

const float grab_half_size = ImMax(DRAG_GRAB_HALF_SIZE, thickness/2);
float xl = gp.CurrentPlot->PlotRect.Min.x;
float xr = gp.CurrentPlot->PlotRect.Max.x;
Expand All @@ -4089,6 +4096,7 @@ bool DragLineY(int n_id, double* value, const ImVec4& col, float thickness, ImPl

ImGui::KeepAliveID(id);
if (input) {
rect.ClipWithFull(GImPlot->CurrentPlot->PlotRect);
bool clicked = ImGui::ButtonBehavior(rect,id,&hovered,&held);
if (out_clicked) *out_clicked = clicked;
if (out_hovered) *out_hovered = hovered;
Expand All @@ -4103,7 +4111,7 @@ bool DragLineY(int n_id, double* value, const ImVec4& col, float thickness, ImPl
ImU32 col32 = ImGui::ColorConvertFloat4ToU32(color);

bool modified = false;
if (held && ImGui::IsMouseDragging(0)) {
if (move_allowed && held && ImGui::IsMouseDragging(0)) {
*value = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).y;
modified = true;
}
Expand Down Expand Up @@ -4134,6 +4142,9 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
const bool input = !ImHasFlag(flags, ImPlotDragToolFlags_NoInputs);
const bool show_curs = !ImHasFlag(flags, ImPlotDragToolFlags_NoCursors);
const bool no_delay = !ImHasFlag(flags, ImPlotDragToolFlags_Delayed);
const bool move_allowed = !ImHasFlag(flags, ImPlotDragToolFlags_NoMove);
const bool resize_allowed = !ImHasFlag(flags, ImPlotDragToolFlags_NoResize);

bool h[] = {true,false,true,false};
double* x[] = {x_min,x_max,x_max,x_min};
double* y[] = {y_min,y_min,y_max,y_max};
Expand All @@ -4143,6 +4154,7 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
ImVec2 pc = PlotToPixels((*x_min+*x_max)/2,(*y_min+*y_max)/2,IMPLOT_AUTO,IMPLOT_AUTO);
ImRect rect(ImMin(p[0],p[2]),ImMax(p[0],p[2]));
ImRect rect_grab = rect; rect_grab.Expand(DRAG_GRAB_HALF_SIZE);
rect_grab.ClipWithFull(GImPlot->CurrentPlot->PlotRect);

ImGuiMouseCursor cur[4];
if (show_curs) {
Expand All @@ -4162,11 +4174,12 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
bool clicked = false, hovered = false, held = false;

const bool is_movable = *x_min != *x_max || *y_min != *y_max;
if (is_movable) {
if (is_movable && move_allowed) {
ImGui::KeepAliveID(id);
if (input) {
// middle point
ImRect b_rect(pc.x-DRAG_GRAB_HALF_SIZE,pc.y-DRAG_GRAB_HALF_SIZE,pc.x+DRAG_GRAB_HALF_SIZE,pc.y+DRAG_GRAB_HALF_SIZE);
b_rect.ClipWithFull(GImPlot->CurrentPlot->PlotRect);
clicked = ImGui::ButtonBehavior(b_rect,id,&hovered,&held);
if (out_clicked) *out_clicked = clicked;
if (out_hovered) *out_hovered = hovered;
Expand All @@ -4185,56 +4198,60 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
}
}

for (int i = 0; i < 4; ++i) {
// points
ImRect b_rect(p[i].x - DRAG_GRAB_HALF_SIZE, p[i].y - DRAG_GRAB_HALF_SIZE, p[i].x + DRAG_GRAB_HALF_SIZE, p[i].y + DRAG_GRAB_HALF_SIZE);
ImGuiID p_id = id + i + 1;
ImGui::KeepAliveID(p_id);
if (input) {
clicked = ImGui::ButtonBehavior(b_rect,p_id,&hovered,&held);
if (out_clicked) *out_clicked = *out_clicked || clicked;
if (out_hovered) *out_hovered = *out_hovered || hovered;
if (out_held) *out_held = *out_held || held;
}
if ((hovered || held) && show_curs)
ImGui::SetMouseCursor(cur[i]);

if (held && ImGui::IsMouseDragging(0)) {
*x[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).x;
*y[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).y;
modified = true;
}
if (resize_allowed) {
for (int i = 0; i < 4; ++i) {
// points
ImRect b_rect(p[i].x - DRAG_GRAB_HALF_SIZE, p[i].y - DRAG_GRAB_HALF_SIZE, p[i].x + DRAG_GRAB_HALF_SIZE, p[i].y + DRAG_GRAB_HALF_SIZE);
b_rect.ClipWithFull(GImPlot->CurrentPlot->PlotRect);
ImGuiID p_id = id + i + 1;
ImGui::KeepAliveID(p_id);
if (input) {
clicked = ImGui::ButtonBehavior(b_rect,p_id,&hovered,&held);
if (out_clicked) *out_clicked = *out_clicked || clicked;
if (out_hovered) *out_hovered = *out_hovered || hovered;
if (out_held) *out_held = *out_held || held;
}
if ((hovered || held) && show_curs)
ImGui::SetMouseCursor(cur[i]);

// edges
ImVec2 e_min = ImMin(p[i],p[(i+1)%4]);
ImVec2 e_max = ImMax(p[i],p[(i+1)%4]);
b_rect = h[i] ? ImRect(e_min.x + DRAG_GRAB_HALF_SIZE, e_min.y - DRAG_GRAB_HALF_SIZE, e_max.x - DRAG_GRAB_HALF_SIZE, e_max.y + DRAG_GRAB_HALF_SIZE)
: ImRect(e_min.x - DRAG_GRAB_HALF_SIZE, e_min.y + DRAG_GRAB_HALF_SIZE, e_max.x + DRAG_GRAB_HALF_SIZE, e_max.y - DRAG_GRAB_HALF_SIZE);
ImGuiID e_id = id + i + 5;
ImGui::KeepAliveID(e_id);
if (input) {
clicked = ImGui::ButtonBehavior(b_rect,e_id,&hovered,&held);
if (out_clicked) *out_clicked = *out_clicked || clicked;
if (out_hovered) *out_hovered = *out_hovered || hovered;
if (out_held) *out_held = *out_held || held;
}
if ((hovered || held) && show_curs)
h[i] ? ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS) : ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
if (held && ImGui::IsMouseDragging(0)) {
if (h[i])
*y[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).y;
else
if (held && ImGui::IsMouseDragging(0)) {
*x[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).x;
modified = true;
}
if (hovered && ImGui::IsMouseDoubleClicked(0))
{
ImPlotRect b = GetPlotLimits(IMPLOT_AUTO,IMPLOT_AUTO);
if (h[i])
*y[i] = ((y[i] == y_min && *y_min < *y_max) || (y[i] == y_max && *y_max < *y_min)) ? b.Y.Min : b.Y.Max;
else
*x[i] = ((x[i] == x_min && *x_min < *x_max) || (x[i] == x_max && *x_max < *x_min)) ? b.X.Min : b.X.Max;
modified = true;
*y[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).y;
modified = true;
}

// edges
ImVec2 e_min = ImMin(p[i],p[(i+1)%4]);
ImVec2 e_max = ImMax(p[i],p[(i+1)%4]);
b_rect = h[i] ? ImRect(e_min.x + DRAG_GRAB_HALF_SIZE, e_min.y - DRAG_GRAB_HALF_SIZE, e_max.x - DRAG_GRAB_HALF_SIZE, e_max.y + DRAG_GRAB_HALF_SIZE)
: ImRect(e_min.x - DRAG_GRAB_HALF_SIZE, e_min.y + DRAG_GRAB_HALF_SIZE, e_max.x + DRAG_GRAB_HALF_SIZE, e_max.y - DRAG_GRAB_HALF_SIZE);
b_rect.ClipWithFull(GImPlot->CurrentPlot->PlotRect);
ImGuiID e_id = id + i + 5;
ImGui::KeepAliveID(e_id);
if (input) {
clicked = ImGui::ButtonBehavior(b_rect,e_id,&hovered,&held);
if (out_clicked) *out_clicked = *out_clicked || clicked;
if (out_hovered) *out_hovered = *out_hovered || hovered;
if (out_held) *out_held = *out_held || held;
}
if ((hovered || held) && show_curs)
h[i] ? ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS) : ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
if (held && ImGui::IsMouseDragging(0)) {
if (h[i])
*y[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).y;
else
*x[i] = ImPlot::GetPlotMousePos(IMPLOT_AUTO,IMPLOT_AUTO).x;
modified = true;
}
if (hovered && ImGui::IsMouseDoubleClicked(0))
{
ImPlotRect b = GetPlotLimits(IMPLOT_AUTO,IMPLOT_AUTO);
if (h[i])
*y[i] = ((y[i] == y_min && *y_min < *y_max) || (y[i] == y_max && *y_max < *y_min)) ? b.Y.Min : b.Y.Max;
else
*x[i] = ((x[i] == x_min && *x_min < *x_max) || (x[i] == x_max && *x_max < *x_min)) ? b.X.Min : b.X.Max;
modified = true;
}
}
}

Expand All @@ -4258,9 +4275,13 @@ bool DragRect(int n_id, double* x_min, double* y_min, double* x_max, double* y_m
DrawList.AddRectFilled(rect.Min, rect.Max, col32_a);
DrawList.AddRect(rect.Min, rect.Max, col32);
if (input && (modified || mouse_inside)) {
DrawList.AddCircleFilled(pc,DRAG_GRAB_HALF_SIZE,col32);
for (int i = 0; i < 4; ++i)
DrawList.AddCircleFilled(p[i],DRAG_GRAB_HALF_SIZE,col32);
if (move_allowed) {
DrawList.AddCircleFilled(pc,DRAG_GRAB_HALF_SIZE,col32);
}
if (resize_allowed) {
for (int i = 0; i < 4; ++i)
DrawList.AddCircleFilled(p[i],DRAG_GRAB_HALF_SIZE,col32);
}
}
PopPlotClipRect();
ImGui::PopID();
Expand Down
2 changes: 2 additions & 0 deletions implot.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ enum ImPlotDragToolFlags_ {
ImPlotDragToolFlags_NoFit = 1 << 1, // the drag tool won't be considered for plot fits
ImPlotDragToolFlags_NoInputs = 1 << 2, // lock the tool from user inputs
ImPlotDragToolFlags_Delayed = 1 << 3, // tool rendering will be delayed one frame; useful when applying position-constraints
ImPlotDragToolFlags_NoMove = 1 << 4, // lock the tool from user inputs
ImPlotDragToolFlags_NoResize = 1 << 5, // lock the tool from user inputs
};

// Flags for ColormapScale
Expand Down
10 changes: 7 additions & 3 deletions implot_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,8 @@ void Demo_DragPoints() {
static ImPlotDragToolFlags flags = ImPlotDragToolFlags_None;
ImGui::CheckboxFlags("NoCursors", (unsigned int*)&flags, ImPlotDragToolFlags_NoCursors); ImGui::SameLine();
ImGui::CheckboxFlags("NoFit", (unsigned int*)&flags, ImPlotDragToolFlags_NoFit); ImGui::SameLine();
ImGui::CheckboxFlags("NoInput", (unsigned int*)&flags, ImPlotDragToolFlags_NoInputs);
ImGui::CheckboxFlags("NoInput", (unsigned int*)&flags, ImPlotDragToolFlags_NoInputs); ImGui::SameLine();
ImGui::CheckboxFlags("NoMove", (unsigned int*)&flags, ImPlotDragToolFlags_NoMove);
ImPlotAxisFlags ax_flags = ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoTickMarks;
bool clicked[4] = {false, false, false, false};
bool hovered[4] = {false, false, false, false};
Expand Down Expand Up @@ -1973,7 +1974,8 @@ void Demo_DragLines() {
static ImPlotDragToolFlags flags = ImPlotDragToolFlags_None;
ImGui::CheckboxFlags("NoCursors", (unsigned int*)&flags, ImPlotDragToolFlags_NoCursors); ImGui::SameLine();
ImGui::CheckboxFlags("NoFit", (unsigned int*)&flags, ImPlotDragToolFlags_NoFit); ImGui::SameLine();
ImGui::CheckboxFlags("NoInput", (unsigned int*)&flags, ImPlotDragToolFlags_NoInputs);
ImGui::CheckboxFlags("NoInput", (unsigned int*)&flags, ImPlotDragToolFlags_NoInputs); ImGui::SameLine();
ImGui::CheckboxFlags("NoMove", (unsigned int*)&flags, ImPlotDragToolFlags_NoMove);
if (ImPlot::BeginPlot("##lines",ImVec2(-1,0))) {
ImPlot::SetupAxesLimits(0,1,0,1);
ImPlot::DragLineX(0,&x1,ImVec4(1,1,1,1),1,flags);
Expand Down Expand Up @@ -2019,7 +2021,9 @@ void Demo_DragRects() {
static ImPlotDragToolFlags flags = ImPlotDragToolFlags_None;
ImGui::CheckboxFlags("NoCursors", (unsigned int*)&flags, ImPlotDragToolFlags_NoCursors); ImGui::SameLine();
ImGui::CheckboxFlags("NoFit", (unsigned int*)&flags, ImPlotDragToolFlags_NoFit); ImGui::SameLine();
ImGui::CheckboxFlags("NoInput", (unsigned int*)&flags, ImPlotDragToolFlags_NoInputs);
ImGui::CheckboxFlags("NoInput", (unsigned int*)&flags, ImPlotDragToolFlags_NoInputs); ImGui::SameLine();
ImGui::CheckboxFlags("NoMove", (unsigned int*)&flags, ImPlotDragToolFlags_NoMove); ImGui::SameLine();
ImGui::CheckboxFlags("NoResize", (unsigned int*)&flags, ImPlotDragToolFlags_NoResize);

if (ImPlot::BeginPlot("##Main",ImVec2(-1,ImGui::GetTextLineHeight()*10))) {
ImPlot::SetupAxes(nullptr,nullptr,ImPlotAxisFlags_NoTickLabels,ImPlotAxisFlags_NoTickLabels);
Expand Down