Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make context menus open with single right-click instead of double right-click #170

Merged
merged 1 commit into from
Jan 19, 2021
Merged
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
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ ImPlot is an immediate mode, GPU accelerated plotting library for [Dear ImGui](h
- up to three independent y-axes
- controls for zooming, panning, box selection, and auto-fitting data
- controls for creating persistent query ranges (see demo)
- remappable input controls
- several plot styling options: 10 marker types, adjustable marker sizes, line weights, outline colors, fill colors, etc.
- 10 built-in and user definable colormaps
- optional plot titles, axis labels, and grid labels
Expand Down
42 changes: 29 additions & 13 deletions implot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ 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.
- 2021/01/18 (0.9) - The default behavior for opening context menus was change from double right-click to single right-click. ImPlotInputMap and related functions were moved
to implot_internal.h due to its immaturity.
- 2020/10/16 (0.8) - ImPlotStyleVar_InfoPadding was changed to ImPlotStyleVar_MousePosPadding
- 2020/09/10 (0.8) - The single array versions of PlotLine, PlotScatter, PlotStems, and PlotShaded were given additional arguments for x-scale and x0.
- 2020/09/07 (0.8) - Plotting functions which accept a custom getter function pointer have been post-fixed with a G (e.g. PlotLineG)
Expand Down Expand Up @@ -1708,16 +1710,20 @@ bool BeginPlot(const char* title, const char* x_label, const char* y1_label, con
if (!plot.YAxis[i].IsLockedMax() && y_can_change)
plot.YAxis[i].SetMax(ImMax(p1.y, p2.y));
}
if (x_can_change || y_can_change || (ImHasFlag(IO.KeyMods,gp.InputMap.HorizontalMod) && ImHasFlag(IO.KeyMods,gp.InputMap.VerticalMod)))
plot.ContextLocked = gp.InputMap.BoxSelectButton == gp.InputMap.ContextMenuButton;
}
plot.Selecting = false;
}
// bad selection
if (plot.Selecting && (ImHasFlag(plot.Flags, ImPlotFlags_NoBoxSelect) || plot.IsLocked()) && ImLengthSqr(plot.SelectStart - IO.MousePos) > 4) {
ImGui::SetMouseCursor(ImGuiMouseCursor_NotAllowed);
plot.ContextLocked = gp.InputMap.BoxSelectButton == gp.InputMap.ContextMenuButton;
}
// cancel selection
if (plot.Selecting && (IO.MouseClicked[gp.InputMap.BoxSelectCancelButton] || IO.MouseDown[gp.InputMap.BoxSelectCancelButton])) {
plot.Selecting = false;
plot.ContextLocked = gp.InputMap.BoxSelectButton == gp.InputMap.ContextMenuButton;
}
// begin selection or query
if (plot.FrameHovered && plot.PlotHovered && IO.MouseClicked[gp.InputMap.BoxSelectButton] && ImHasFlag(IO.KeyMods, gp.InputMap.BoxSelectMod)) {
Expand All @@ -1738,8 +1744,10 @@ bool BeginPlot(const char* title, const char* x_label, const char* y1_label, con
// end query
if (plot.Querying && (IO.MouseReleased[gp.InputMap.QueryButton] || IO.MouseReleased[gp.InputMap.BoxSelectButton])) {
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.ContextLocked = gp.InputMap.BoxSelectButton == gp.InputMap.ContextMenuButton;
}
else
plot.Queried = false;
}
Expand Down Expand Up @@ -2466,24 +2474,27 @@ void EndPlot() {

// CONTEXT MENUS -----------------------------------------------------------

if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && plot.FrameHovered && plot.PlotHovered && IO.MouseDoubleClicked[gp.InputMap.ContextMenuButton] && !plot.LegendHovered)
// main ctx menu
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && plot.FrameHovered && plot.PlotHovered && IO.MouseReleased[gp.InputMap.ContextMenuButton] && !plot.LegendHovered && !plot.ContextLocked)
ImGui::OpenPopup("##PlotContext");
if (ImGui::BeginPopup("##PlotContext")) {
ShowPlotContextMenu(plot);
ImGui::EndPopup();
}

if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && plot.FrameHovered && plot.XAxis.ExtHovered && IO.MouseDoubleClicked[gp.InputMap.ContextMenuButton] && !plot.LegendHovered)
// x-axis ctx menu
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && plot.FrameHovered && plot.XAxis.ExtHovered && IO.MouseReleased[gp.InputMap.ContextMenuButton] && !plot.LegendHovered && !plot.ContextLocked)
ImGui::OpenPopup("##XContext");
if (ImGui::BeginPopup("##XContext")) {
ImGui::Text("X-Axis"); ImGui::Separator();
ShowAxisContextMenu(plot.XAxis, ImHasFlag(plot.Flags, ImPlotFlags_Equal) ? &plot.YAxis[0] : NULL, true);
ImGui::EndPopup();
}

// y-axes ctx menus
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
ImGui::PushID(i);
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && plot.FrameHovered && plot.YAxis[i].ExtHovered && IO.MouseDoubleClicked[gp.InputMap.ContextMenuButton] && !plot.LegendHovered)
if (!ImHasFlag(plot.Flags, ImPlotFlags_NoMenus) && plot.FrameHovered && plot.YAxis[i].ExtHovered && IO.MouseReleased[gp.InputMap.ContextMenuButton] && !plot.LegendHovered && !plot.ContextLocked)
ImGui::OpenPopup("##YContext");
if (ImGui::BeginPopup("##YContext")) {
if (i == 0) {
Expand All @@ -2507,6 +2518,11 @@ void EndPlot() {

// CLEANUP ----------------------------------------------------------------

// resset context locked flag
if (plot.ContextLocked && IO.MouseReleased[gp.InputMap.BoxSelectButton])
plot.ContextLocked = false;


// reset the plot items for the next frame
for (int i = 0; i < gp.CurrentPlot->Items.GetSize(); ++i) {
gp.CurrentPlot->Items.GetByIndex(i)->SeenThisFrame = false;
Expand Down Expand Up @@ -3719,27 +3735,27 @@ void ShowStyleEditor(ImPlotStyle* ref) {
}

void ShowUserGuide() {
ImGui::BulletText("Left click and drag within the plot area to pan X and Y axes.");
ImGui::BulletText("Left-click drag within the plot area to pan X and Y axes.");
ImGui::Indent();
ImGui::BulletText("Left click and drag on an axis to pan an individual axis.");
ImGui::BulletText("Left-click drag on axis labels to pan an individual axis.");
ImGui::Unindent();
ImGui::BulletText("Scroll in the plot area to zoom both X any Y axes.");
ImGui::Indent();
ImGui::BulletText("Scroll on an axis to zoom an individual axis.");
ImGui::BulletText("Scroll on axis labels to zoom an individual axis.");
ImGui::Unindent();
ImGui::BulletText("Right click and drag to box select data.");
ImGui::BulletText("Right-click drag to box select data.");
ImGui::Indent();
ImGui::BulletText("Hold Alt to expand box selection horizontally.");
ImGui::BulletText("Hold Shift to expand box selection vertically.");
ImGui::BulletText("Left click while box selecting to cancel the selection.");
ImGui::BulletText("Left-click while box selecting to cancel the selection.");
ImGui::Unindent();
ImGui::BulletText("Double left click to fit all visible data.");
ImGui::BulletText("Double left-click to fit all visible data.");
ImGui::Indent();
ImGui::BulletText("Double left click on an axis to fit the individual axis.");
ImGui::BulletText("Double left-click axis labels to fit the individual axis.");
ImGui::Unindent();
ImGui::BulletText("Double right click to open the full plot context menu.");
ImGui::BulletText("Right-click open the full plot context menu.");
ImGui::Indent();
ImGui::BulletText("Double right click on an axis to open the axis context menu.");
ImGui::BulletText("Right-click axis labels to open an individual axis context menu.");
ImGui::Unindent();
ImGui::BulletText("Click legend label icons to show/hide plot items.");
}
Expand Down
50 changes: 15 additions & 35 deletions implot.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,24 @@ enum ImPlotFlags_ {
ImPlotFlags_None = 0, // default
ImPlotFlags_NoTitle = 1 << 0, // the plot title will not be displayed (titles are also hidden if preceeded by double hashes, e.g. "##MyPlot")
ImPlotFlags_NoLegend = 1 << 1, // the legend will not be displayed
ImPlotFlags_NoMenus = 1 << 2, // the user will not be able to open context menus with double-right click
ImPlotFlags_NoBoxSelect = 1 << 3, // the user will not be able to box-select with right-mouse
ImPlotFlags_NoMenus = 1 << 2, // the user will not be able to open context menus with right-click
ImPlotFlags_NoBoxSelect = 1 << 3, // the user will not be able to box-select with right-click drag
ImPlotFlags_NoMousePos = 1 << 4, // the mouse position, in plot coordinates, will not be displayed inside of the plot
ImPlotFlags_NoHighlight = 1 << 5, // plot items will not be highlighted when their legend entry is hovered
ImPlotFlags_NoChild = 1 << 6, // a child window region will not be used to capture mouse scroll (can boost performance for single ImGui window applications)
ImPlotFlags_Equal = 1 << 7, // primary x and y axes will be constrained to have the same units/pixel (does not apply to auxiliary y axes)
ImPlotFlags_Equal = 1 << 7, // primary x and y axes will be constrained to have the same units/pixel (does not apply to auxiliary y-axes)
ImPlotFlags_YAxis2 = 1 << 8, // enable a 2nd y-axis on the right side
ImPlotFlags_YAxis3 = 1 << 9, // enable a 3rd y-axis on the right side
ImPlotFlags_Query = 1 << 10, // the user will be able to draw query rects with middle-mouse
ImPlotFlags_Query = 1 << 10, // the user will be able to draw query rects with middle-mouse or CTRL + right-click drag
ImPlotFlags_Crosshairs = 1 << 11, // the default mouse cursor will be replaced with a crosshair when hovered
ImPlotFlags_AntiAliased = 1 << 12, // plot lines will be software anti-aliased (not recommended for density plots, prefer MSAA)
ImPlotFlags_AntiAliased = 1 << 12, // plot lines will be software anti-aliased (not recommended for high density plots, prefer MSAA)
ImPlotFlags_CanvasOnly = ImPlotFlags_NoTitle | ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect | ImPlotFlags_NoMousePos
};

// Options for plot axes (X and Y).
enum ImPlotAxisFlags_ {
ImPlotAxisFlags_None = 0, // default
ImPlotAxisFlags_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels also hidden if string is NULL)
ImPlotAxisFlags_NoLabel = 1 << 0, // the axis label will not be displayed (axis labels also hidden if the supplied string name is NULL)
ImPlotAxisFlags_NoGridLines = 1 << 1, // the axis grid lines will not be displayed
ImPlotAxisFlags_NoTickMarks = 1 << 2, // the axis tick marks will not be displayed
ImPlotAxisFlags_NoTickLabels = 1 << 3, // the axis tick labels will not be displayed
Expand Down Expand Up @@ -291,23 +291,6 @@ struct ImPlotStyle {
IMPLOT_API 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
IMPLOT_API ImPlotInputMap();
};

//-----------------------------------------------------------------------------
// ImPlot End-User API
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -461,7 +444,7 @@ IMPLOT_API void PlotDummy(const char* label_id);
// Plot Utils
//-----------------------------------------------------------------------------

// The following functions MUST be called before BeginPlot!
// The following functions MUST be called BEFORE BeginPlot!

// Set the axes range limits of the next plot. Call right before BeginPlot(). If ImGuiCond_Always is used, the axes limits will be locked.
IMPLOT_API void SetNextPlotLimits(double xmin, double xmax, double ymin, double ymax, ImGuiCond cond = ImGuiCond_Once);
Expand All @@ -482,7 +465,7 @@ IMPLOT_API void SetNextPlotTicksX(double x_min, double x_max, int n_ticks, const
IMPLOT_API void SetNextPlotTicksY(const double* values, int n_ticks, const char* const labels[] = NULL, bool show_default = false, ImPlotYAxis y_axis = 0);
IMPLOT_API void SetNextPlotTicksY(double y_min, double y_max, int n_ticks, const char* const labels[] = NULL, bool show_default = false, ImPlotYAxis y_axis = 0);

// The following functions MUST be called between Begin/EndPlot!
// The following functions MUST be called BETWEEN Begin/EndPlot!

// Select which Y axis will be used for subsequent plot elements. The default is ImPlotYAxis_1, or the first (left) Y axis. Enable 2nd and 3rd axes with ImPlotFlags_YAxisX.
IMPLOT_API void SetPlotYAxis(ImPlotYAxis y_axis);
Expand Down Expand Up @@ -519,7 +502,7 @@ IMPLOT_API ImPlotLimits GetPlotQuery(ImPlotYAxis y_axis = IMPLOT_AUTO);
// Plot Tools
//-----------------------------------------------------------------------------

// The following functions MUST be called between Begin/EndPlot!
// The following functions MUST be called BETWEEN Begin/EndPlot!

// Shows an annotation callout at a chosen point.
IMPLOT_API void Annotate(double x, double y, const ImVec2& pix_offset, const char* fmt, ...) IM_FMTARGS(4);
Expand Down Expand Up @@ -622,12 +605,12 @@ IMPLOT_API const char* GetMarkerName(ImPlotMarker idx);
// Colormaps
//-----------------------------------------------------------------------------

// Item styling is based on Colormaps when the relevant ImPlotCol is set to
// Item styling is based on Colormaps when the relevant ImPlotCol_ is set to
// IMPLOT_AUTO_COL (default). Several built in colormaps are available and can be
// toggled in the demo. You can push/pop or set your own colormaps as well.

// The Colormap data will be ignored and a custom color will be used if you have either:
// 1) Modified an item style color in your ImPlotStyle to anything but IMPLOT_AUTO_COL.
// The Colormap data will be ignored and a custom color will be used if you have done one of the following:
// 1) Modified an item style color in your ImPlotStyle to anything other than IMPLOT_AUTO_COL.
// 2) Pushed an item style color using PushStyleColor().
// 3) Set the next item style with a SetNextXStyle function.

Expand All @@ -638,9 +621,9 @@ IMPLOT_API void PushColormap(const ImVec4* colormap, int size);
// Undo temporary colormap modification.
IMPLOT_API void PopColormap(int count = 1);

// Permanently sets a custom colormap. The colors will be copied to internal memory. Prefer PushColormap instead of calling this each frame.
// Permanently sets a custom colormap. The colors will be copied to internal memory. Typically used on startup. Prefer PushColormap instead of calling this each frame.
IMPLOT_API void SetColormap(const ImVec4* colormap, int size);
// Permanently switch to one of the built-in colormaps. If samples is greater than 1, the map will be linearly resampled. Don't call this each frame.
// Permanently switch to one of the built-in colormaps. If samples is greater than 1, the map will be linearly resampled. Typically used on startup. Don't call this each frame.
IMPLOT_API void SetColormap(ImPlotColormap colormap, int samples = 0);

// Returns the size of the current colormap.
Expand All @@ -652,7 +635,7 @@ IMPLOT_API ImVec4 LerpColormap(float t);
// Returns the next unused colormap color and advances the colormap. Can be used to skip colors if desired.
IMPLOT_API ImVec4 NextColormapColor();

// Renders a vertical color scale using the current color map. Call this outside of Begin/EndPlot.
// Renders a vertical color scale using the current color map. Call this before or after Begin/EndPlot.
IMPLOT_API void ShowColormapScale(double scale_min, double scale_max, float height);

// Returns a null terminated string name for a built-in colormap.
Expand All @@ -662,9 +645,6 @@ IMPLOT_API const char* GetColormapName(ImPlotColormap colormap);
// Miscellaneous
//-----------------------------------------------------------------------------

// Allows changing how keyboard/mouse interaction works.
IMPLOT_API ImPlotInputMap& GetInputMap();

// Get the plot draw list for rendering to the current plot area.
IMPLOT_API ImDrawList* GetPlotDrawList();
// Push clip rect for rendering to current plot area.
Expand Down
Loading