implot
implot copied to clipboard
Add items to context menu
Is it possible to define additional options from the right-click menu? I looked through the code and I can't find a solution other than modifying the ImPlot code. I think it would be a useful feature to allow us to expose extra functionality to the users.
As it turns out, I also needed this functionality. So I implemented it (possibly less than ideal solution)
Usage Example
if (ImPlot::BeginPlot("My Plot", ImVec2(-1, 0), ImPlotFlags_NoCentralMenu))
{
// ... plot stuff here ...
if (ImPlot::BeginCustomContext())
{
if (ImGui::MenuItem("My Custom Item")) doThing();
ImPlot::EndCustomContext(true); // true = append standard menu
}
ImPlot::EndPlot();
}
Please note that it is critical to:
- use
ImPlotFlags_NoCentralMenuin yourBeginPlot()call - call
BeginCustomContext()AFTERBeginPlot()and BEFOREEndPlot()
And if you want to use it:
implot.h changes
- Add flag to enum ImPlotFlags_
ImPlotFlags_NoCentralMenu = 1 << 9, // disable the central menu, but allow other menus (such as legends and axis)
- Add function declarations
//-----------------------------------------------------------------------------
// [SECTION] Context Menu
//-----------------------------------------------------------------------------
// Begin a custom central plot context menu
IMPLOT_API bool BeginCustomContext();
// End a custom central plot context menu
IMPLOT_API void EndCustomContext(bool include_default = false); // if include_default is true, the normal context menu will be appended
implot.cpp changes
- Modify EndPlot()
// if (can_ctx && plot.Hovered) <-- old line
if (can_ctx && !ImHasFlag(plot.Flags, ImPlotFlags_NoCentralMenu) && plot.Hovered) // <-- new line
- Add function definitions
//-----------------------------------------------------------------------------
// [SECTION] Context Menu
//-----------------------------------------------------------------------------
bool BeginCustomContext()
{
ImPlotContext& gp = *GImPlot;
if (gp.CurrentPlot == nullptr) return false;
ImPlotPlot &plot = *gp.CurrentPlot;
const bool can_ctx = plot.Hovered &&
!plot.Items.Legend.Hovered &&
ImGui::IsMouseReleased(ImGuiMouseButton_Right);
// main ctx menu
if (can_ctx)
ImGui::OpenPopup("##CustomPlotContext");
return ImGui::BeginPopup("##CustomPlotContext");
}
void EndCustomContext(bool include_default)
{
if (include_default)
ShowPlotContextMenu(*(GImPlot->CurrentPlot));
ImGui::EndPopup();
}
This has a bug when box selecting. Looking into it.
Fix:
Change the definition of BeginCustomContext() to:
bool BeginCustomContext()
{
ImPlotContext& gp = *GImPlot;
if (gp.CurrentPlot == nullptr) return false;
ImPlotPlot &plot = *gp.CurrentPlot;
const bool can_ctx = plot.Hovered &&
!plot.Items.Legend.Hovered &&
!plot.ContextLocked && // <-- added
ImGui::IsMouseReleased(ImGuiMouseButton_Right);
// main ctx menu
if (can_ctx)
ImGui::OpenPopup("##CustomPlotContext");
return ImGui::BeginPopup("##CustomPlotContext");
}
Hey there, @PapaNaxos, it works for me too. Thanks.
Are you about to draft a PR?
@Karm I hadn't planned on it. Was hoping maybe the maintainers would make a proper version (mine feels like a hack job).
Also I don't actually know how to make a pull request :sweat_smile:
@PapaNaxos If you don't mind, I'll polish your solution into a PR and attribute the credit to @PapaNaxos. To quote our lord and savior Mike Acton, "if it solves the problem, it is the solution".
@Karm that's totally fine with me, appreciated even!