1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-10-09 23:57:26 -04:00
This commit is contained in:
Evan Pezent 2020-06-15 21:00:45 -05:00
commit 8d205530cd
2 changed files with 70 additions and 25 deletions

View File

@ -133,6 +133,21 @@ bool ImPlotLimits::Contains(double x, double y) const {
return X.Contains(x) && Y.Contains(y); return X.Contains(x) && Y.Contains(y);
} }
ImPlotInputMap::ImPlotInputMap() {
PanButton = ImGuiMouseButton_Left;
PanMod = ImGuiKeyModFlags_None;
FitButton = ImGuiMouseButton_Left;
ContextMenuButton = ImGuiMouseButton_Right;
BoxSelectButton = ImGuiMouseButton_Right;
BoxSelectMod = ImGuiKeyModFlags_None;
BoxSelectCancelButton = ImGuiMouseButton_Left;
QueryButton = ImGuiMouseButton_Middle;
QueryMod = ImGuiKeyModFlags_None;
QueryToggleMod = ImGuiKeyModFlags_Ctrl;
HorizontalMod = ImGuiKeyModFlags_Alt;
VerticalMod = ImGuiKeyModFlags_Shift;
}
namespace ImPlot { namespace ImPlot {
namespace { namespace {
@ -496,6 +511,7 @@ struct ImPlotContext {
ImVec4* Colormap; ImVec4* Colormap;
int ColormapSize; int ColormapSize;
ImPlotStyle Style; ImPlotStyle Style;
ImPlotInputMap InputMap;
ImVector<ImGuiColorMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector<ImGuiColorMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor()
ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar()
ImPlotNextPlotData NextPlotData; ImPlotNextPlotData NextPlotData;
@ -511,6 +527,10 @@ static ImPlotContext gp;
// Context Utils // Context Utils
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ImPlotInputMap& GetInputMap() {
return gp.InputMap;
}
// Returns the next unused default plot color // Returns the next unused default plot color
ImVec4 NextColor() { ImVec4 NextColor() {
ImVec4 col = gp.Colormap[gp.CurrentPlot->ColorIdx % gp.ColormapSize]; ImVec4 col = gp.Colormap[gp.CurrentPlot->ColorIdx % gp.ColormapSize];
@ -1040,7 +1060,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
} }
// QUERY DRAG ------------------------------------------------------------- // QUERY DRAG -------------------------------------------------------------
if (plot.DraggingQuery && (IO.MouseReleased[0] || !IO.MouseDown[0])) { if (plot.DraggingQuery && (IO.MouseReleased[gp.InputMap.PanButton] || !IO.MouseDown[gp.InputMap.PanButton])) {
plot.DraggingQuery = false; plot.DraggingQuery = false;
} }
if (plot.DraggingQuery) { if (plot.DraggingQuery) {
@ -1051,7 +1071,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
if (gp.Hov_Frame && gp.Hov_Plot && hov_query && !plot.DraggingQuery && !plot.Selecting && !hov_legend) { if (gp.Hov_Frame && gp.Hov_Plot && hov_query && !plot.DraggingQuery && !plot.Selecting && !hov_legend) {
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll); ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll);
const bool any_y_dragging = plot.YAxis[0].Dragging || plot.YAxis[1].Dragging || plot.YAxis[2].Dragging; const bool any_y_dragging = plot.YAxis[0].Dragging || plot.YAxis[1].Dragging || plot.YAxis[2].Dragging;
if (IO.MouseDown[0] && !plot.XAxis.Dragging && !any_y_dragging) { if (IO.MouseDown[gp.InputMap.PanButton] && !plot.XAxis.Dragging && !any_y_dragging) {
plot.DraggingQuery = true; plot.DraggingQuery = true;
} }
} }
@ -1059,12 +1079,12 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// DRAG INPUT ------------------------------------------------------------- // DRAG INPUT -------------------------------------------------------------
// end drags // end drags
if (plot.XAxis.Dragging && (IO.MouseReleased[0] || !IO.MouseDown[0])) { if (plot.XAxis.Dragging && (IO.MouseReleased[gp.InputMap.PanButton] || !IO.MouseDown[gp.InputMap.PanButton])) {
plot.XAxis.Dragging = false; plot.XAxis.Dragging = false;
G.IO.MouseDragMaxDistanceSqr[0] = 0; G.IO.MouseDragMaxDistanceSqr[0] = 0;
} }
for (int i = 0; i < MAX_Y_AXES; i++) { for (int i = 0; i < MAX_Y_AXES; i++) {
if (plot.YAxis[i].Dragging && (IO.MouseReleased[0] || !IO.MouseDown[0])) { if (plot.YAxis[i].Dragging && (IO.MouseReleased[gp.InputMap.PanButton] || !IO.MouseDown[gp.InputMap.PanButton])) {
plot.YAxis[i].Dragging = false; plot.YAxis[i].Dragging = false;
G.IO.MouseDragMaxDistanceSqr[0] = 0; G.IO.MouseDragMaxDistanceSqr[0] = 0;
} }
@ -1121,7 +1141,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
} }
} }
// start drag // start drag
if (!drag_in_progress && gp.Hov_Frame && IO.MouseClicked[0] && !plot.Selecting && !hov_legend && !hov_query && !plot.DraggingQuery) { if (!drag_in_progress && gp.Hov_Frame && IO.MouseClicked[gp.InputMap.PanButton] && HasFlag(IO.KeyMods, gp.InputMap.PanMod) && !plot.Selecting && !hov_legend && !hov_query && !plot.DraggingQuery) {
if (hov_x_axis_region) { if (hov_x_axis_region) {
plot.XAxis.Dragging = true; plot.XAxis.Dragging = true;
} }
@ -1167,22 +1187,22 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// BOX-SELECTION AND QUERY ------------------------------------------------ // BOX-SELECTION AND QUERY ------------------------------------------------
// confirm selection // confirm selection
if (plot.Selecting && (IO.MouseReleased[1] || !IO.MouseDown[1])) { if (plot.Selecting && (IO.MouseReleased[gp.InputMap.BoxSelectButton] || !IO.MouseDown[gp.InputMap.BoxSelectButton])) {
UpdateTransformCache(); UpdateTransformCache();
ImVec2 select_size = plot.SelectStart - IO.MousePos; ImVec2 select_size = plot.SelectStart - IO.MousePos;
if (HasFlag(plot.Flags, ImPlotFlags_BoxSelect) && ImFabs(select_size.x) > 2 && ImFabs(select_size.y) > 2) { if (HasFlag(plot.Flags, ImPlotFlags_BoxSelect) && ImFabs(select_size.x) > 2 && ImFabs(select_size.y) > 2) {
ImPlotPoint p1 = PixelsToPlot(plot.SelectStart); ImPlotPoint p1 = PixelsToPlot(plot.SelectStart);
ImPlotPoint p2 = PixelsToPlot(IO.MousePos); ImPlotPoint p2 = PixelsToPlot(IO.MousePos);
if (!gp.X.LockMin && !IO.KeyAlt) if (!gp.X.LockMin && IO.KeyMods != gp.InputMap.HorizontalMod)
plot.XAxis.Range.Min = ImMin(p1.x, p2.x); plot.XAxis.Range.Min = ImMin(p1.x, p2.x);
if (!gp.X.LockMax && !IO.KeyAlt) if (!gp.X.LockMax && IO.KeyMods != gp.InputMap.HorizontalMod)
plot.XAxis.Range.Max = ImMax(p1.x, p2.x); plot.XAxis.Range.Max = ImMax(p1.x, p2.x);
for (int i = 0; i < MAX_Y_AXES; i++) { for (int i = 0; i < MAX_Y_AXES; i++) {
p1 = PixelsToPlot(plot.SelectStart, i); p1 = PixelsToPlot(plot.SelectStart, i);
p2 = PixelsToPlot(IO.MousePos, i); p2 = PixelsToPlot(IO.MousePos, i);
if (!gp.Y[i].LockMin && !IO.KeyShift) if (!gp.Y[i].LockMin && IO.KeyMods != gp.InputMap.VerticalMod)
plot.YAxis[i].Range.Min = ImMin(p1.y, p2.y); plot.YAxis[i].Range.Min = ImMin(p1.y, p2.y);
if (!gp.Y[i].LockMax && !IO.KeyShift) if (!gp.Y[i].LockMax && IO.KeyMods != gp.InputMap.VerticalMod)
plot.YAxis[i].Range.Max = ImMax(p1.y, p2.y); plot.YAxis[i].Range.Max = ImMax(p1.y, p2.y);
} }
} }
@ -1193,27 +1213,27 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
ImGui::SetMouseCursor(ImGuiMouseCursor_NotAllowed); ImGui::SetMouseCursor(ImGuiMouseCursor_NotAllowed);
} }
// cancel selection // cancel selection
if (plot.Selecting && (IO.MouseClicked[0] || IO.MouseDown[0])) { if (plot.Selecting && (IO.MouseClicked[gp.InputMap.BoxSelectCancelButton] || IO.MouseDown[gp.InputMap.BoxSelectCancelButton])) {
plot.Selecting = false; plot.Selecting = false;
} }
// begin selection or query // begin selection or query
if (gp.Hov_Frame && gp.Hov_Plot && IO.MouseClicked[1]) { if (gp.Hov_Frame && gp.Hov_Plot && IO.MouseClicked[gp.InputMap.BoxSelectButton] && HasFlag(IO.KeyMods, gp.InputMap.BoxSelectMod)) {
plot.SelectStart = IO.MousePos; plot.SelectStart = IO.MousePos;
plot.Selecting = true; plot.Selecting = true;
} }
// update query // update query
if (plot.Querying) { if (plot.Querying) {
UpdateTransformCache(); UpdateTransformCache();
plot.QueryRect.Min.x = IO.KeyAlt ? gp.BB_Plot.Min.x : ImMin(plot.QueryStart.x, IO.MousePos.x); plot.QueryRect.Min.x = HasFlag(IO.KeyMods, gp.InputMap.HorizontalMod) ? gp.BB_Plot.Min.x : ImMin(plot.QueryStart.x, IO.MousePos.x);
plot.QueryRect.Max.x = IO.KeyAlt ? gp.BB_Plot.Max.x : ImMax(plot.QueryStart.x, IO.MousePos.x); plot.QueryRect.Max.x = HasFlag(IO.KeyMods, gp.InputMap.HorizontalMod) ? gp.BB_Plot.Max.x : ImMax(plot.QueryStart.x, IO.MousePos.x);
plot.QueryRect.Min.y = IO.KeyShift ? gp.BB_Plot.Min.y : ImMin(plot.QueryStart.y, IO.MousePos.y); plot.QueryRect.Min.y = HasFlag(IO.KeyMods, gp.InputMap.VerticalMod) ? gp.BB_Plot.Min.y : ImMin(plot.QueryStart.y, IO.MousePos.y);
plot.QueryRect.Max.y = IO.KeyShift ? gp.BB_Plot.Max.y : ImMax(plot.QueryStart.y, IO.MousePos.y); plot.QueryRect.Max.y = HasFlag(IO.KeyMods, gp.InputMap.VerticalMod) ? gp.BB_Plot.Max.y : ImMax(plot.QueryStart.y, IO.MousePos.y);
plot.QueryRect.Min -= gp.BB_Plot.Min; plot.QueryRect.Min -= gp.BB_Plot.Min;
plot.QueryRect.Max -= gp.BB_Plot.Min; plot.QueryRect.Max -= gp.BB_Plot.Min;
} }
// end query // end query
if (plot.Querying && (IO.MouseReleased[2] || IO.MouseReleased[1])) { if (plot.Querying && (IO.MouseReleased[gp.InputMap.QueryButton] || IO.MouseReleased[gp.InputMap.BoxSelectButton])) {
plot.Querying = false; plot.Querying = false;
if (plot.QueryRect.GetWidth() > 2 && plot.QueryRect.GetHeight() > 2) { if (plot.QueryRect.GetWidth() > 2 && plot.QueryRect.GetHeight() > 2) {
plot.Queried = true; plot.Queried = true;
@ -1222,22 +1242,23 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
plot.Queried = false; plot.Queried = false;
} }
} }
// begin query // begin query
if (HasFlag(plot.Flags, ImPlotFlags_Query) && (gp.Hov_Frame && gp.Hov_Plot && IO.MouseClicked[2])) { if (HasFlag(plot.Flags, ImPlotFlags_Query) && gp.Hov_Frame && gp.Hov_Plot && IO.MouseClicked[gp.InputMap.QueryButton] && HasFlag(IO.KeyMods, gp.InputMap.QueryMod)) {
plot.QueryRect = ImRect(0,0,0,0); plot.QueryRect = ImRect(0,0,0,0);
plot.Querying = true; plot.Querying = true;
plot.Queried = true; plot.Queried = true;
plot.QueryStart = IO.MousePos; plot.QueryStart = IO.MousePos;
} }
// toggle between select/query // toggle between select/query
if (HasFlag(plot.Flags, ImPlotFlags_Query) && plot.Selecting && IO.KeyCtrl) { if (HasFlag(plot.Flags, ImPlotFlags_Query) && plot.Selecting && HasFlag(IO.KeyMods,gp.InputMap.QueryToggleMod)) {
plot.Selecting = false; plot.Selecting = false;
plot.QueryRect = ImRect(0,0,0,0); plot.QueryRect = ImRect(0,0,0,0);
plot.Querying = true; plot.Querying = true;
plot.Queried = true; plot.Queried = true;
plot.QueryStart = plot.SelectStart; plot.QueryStart = plot.SelectStart;
} }
if (HasFlag(plot.Flags, ImPlotFlags_BoxSelect) && plot.Querying && !IO.KeyCtrl && !IO.MouseDown[2]) { if (HasFlag(plot.Flags, ImPlotFlags_BoxSelect) && plot.Querying && !HasFlag(IO.KeyMods, gp.InputMap.QueryToggleMod) && !IO.MouseDown[gp.InputMap.QueryButton]) {
plot.Selecting = true; plot.Selecting = true;
plot.Querying = false; plot.Querying = false;
plot.Queried = false; plot.Queried = false;
@ -1246,7 +1267,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// DOUBLE CLICK ----------------------------------------------------------- // DOUBLE CLICK -----------------------------------------------------------
if ( IO.MouseDoubleClicked[0] && gp.Hov_Frame && (hov_x_axis_region || any_hov_y_axis_region) && !hov_legend && !hov_query) { if ( IO.MouseDoubleClicked[gp.InputMap.FitButton] && gp.Hov_Frame && (hov_x_axis_region || any_hov_y_axis_region) && !hov_legend && !hov_query) {
gp.FitThisFrame = true; gp.FitThisFrame = true;
gp.FitX = hov_x_axis_region; gp.FitX = hov_x_axis_region;
for (int i = 0; i < MAX_Y_AXES; i++) { for (int i = 0; i < MAX_Y_AXES; i++) {
@ -1264,7 +1285,7 @@ bool BeginPlot(const char* title, const char* x_label, const char* y_label, cons
// FOCUS ------------------------------------------------------------------ // FOCUS ------------------------------------------------------------------
// focus window // focus window
if ((IO.MouseClicked[0] || IO.MouseClicked[1]) && gp.Hov_Frame) if ((IO.MouseClicked[0] || IO.MouseClicked[1] || IO.MouseClicked[2]) && gp.Hov_Frame)
ImGui::FocusWindow(ImGui::GetCurrentWindow()); ImGui::FocusWindow(ImGui::GetCurrentWindow());
UpdateTransformCache(); UpdateTransformCache();
@ -1762,7 +1783,7 @@ void EndPlot() {
// CONTEXT MENU ----------------------------------------------------------- // CONTEXT MENU -----------------------------------------------------------
if (HasFlag(plot.Flags, ImPlotFlags_ContextMenu) && gp.Hov_Frame && gp.Hov_Plot && IO.MouseDoubleClicked[1] && !hov_legend) if (HasFlag(plot.Flags, ImPlotFlags_ContextMenu) && gp.Hov_Frame && gp.Hov_Plot && IO.MouseDoubleClicked[gp.InputMap.ContextMenuButton] && !hov_legend)
ImGui::OpenPopup("##Context"); ImGui::OpenPopup("##Context");
if (ImGui::BeginPopup("##Context")) { if (ImGui::BeginPopup("##Context")) {
PlotContextMenu(plot); PlotContextMenu(plot);

View File

@ -47,7 +47,7 @@ enum ImPlotFlags_ {
ImPlotFlags_Crosshairs = 1 << 6, // the default mouse cursor will be replaced with a crosshair when hovered ImPlotFlags_Crosshairs = 1 << 6, // the default mouse cursor will be replaced with a crosshair when hovered
ImPlotFlags_AntiAliased = 1 << 7, // plot lines will be software anti-aliased (not recommended, prefer MSAA) ImPlotFlags_AntiAliased = 1 << 7, // plot lines will be software anti-aliased (not recommended, prefer MSAA)
ImPlotFlags_NoChild = 1 << 8, // a child window region will not be used to capture mouse scroll (can boost performance for single ImGui window applications) ImPlotFlags_NoChild = 1 << 8, // a child window region will not be used to capture mouse scroll (can boost performance for single ImGui window applications)
ImPlotFlags_YAxis2 = 1 << 9, // enable a 2nd y-axis ImPlotFlags_YAxis2 = 1 << 9, // enable a 2nd y-axis
ImPlotFlags_YAxis3 = 1 << 10, // enable a 3rd y-axis ImPlotFlags_YAxis3 = 1 << 10, // enable a 3rd y-axis
ImPlotFlags_Default = ImPlotFlags_MousePos | ImPlotFlags_Legend | ImPlotFlags_Highlight | ImPlotFlags_BoxSelect | ImPlotFlags_ContextMenu ImPlotFlags_Default = ImPlotFlags_MousePos | ImPlotFlags_Legend | ImPlotFlags_Highlight | ImPlotFlags_BoxSelect | ImPlotFlags_ContextMenu
}; };
@ -172,6 +172,23 @@ struct ImPlotStyle {
ImPlotStyle(); ImPlotStyle();
}; };
// Input mapping structure, default values listed in the comments.
struct ImPlotInputMap {
ImGuiMouseButton PanButton; // LMB enables panning when held
ImGuiKeyModFlags PanMod; // none optional modifier that must be held for panning
ImGuiMouseButton FitButton; // LMB fits visible data when double clicked
ImGuiMouseButton ContextMenuButton; // RMB opens plot context menu (if enabled) when double clicked
ImGuiMouseButton BoxSelectButton; // RMB begins box selection when pressed and confirms selection when released
ImGuiKeyModFlags BoxSelectMod; // none optional modifier that must be held for box selection
ImGuiMouseButton BoxSelectCancelButton; // LMB cancels active box selection when pressed
ImGuiMouseButton QueryButton; // MMB begins query selection when pressed and end query selection when released
ImGuiKeyModFlags QueryMod; // none optional modifier that must be held for query selection
ImGuiKeyModFlags QueryToggleMod; // Ctrl when held, active box selections turn into queries
ImGuiKeyModFlags HorizontalMod; // Alt expands active box selection/query horizontally to plot edge when held
ImGuiKeyModFlags VerticalMod; // Shift expands active box selection/query vertically to plot edge when held
ImPlotInputMap();
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Begin/End Plot // Begin/End Plot
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -283,7 +300,14 @@ bool IsPlotQueried();
ImPlotLimits GetPlotQuery(int y_axis = -1); ImPlotLimits GetPlotQuery(int y_axis = -1);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Plot Styling // Plot Input Mapping
//-----------------------------------------------------------------------------
// Allows changing how keyboard/mouse interaction works.
ImPlotInputMap& GetInputMap();
//-----------------------------------------------------------------------------
// Plot Styling and Behaviour
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Provides access to plot style structure for permanant modifications to colors, sizes, etc. // Provides access to plot style structure for permanant modifications to colors, sizes, etc.