mirror of
https://github.com/gwm17/implot.git
synced 2024-11-23 02:38:53 -05:00
Improved Drag and Drop Support (#172)
* prototyping enhanced dnd features * improve dnd demo using new utils * dnd stuff * finish up dnd improvements * remove unused code, fix timestamps
This commit is contained in:
parent
7234801868
commit
67e0876f89
247
implot.cpp
247
implot.cpp
|
@ -31,6 +31,7 @@ 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.
|
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.
|
You can read releases logs https://github.com/epezent/implot/releases for more details.
|
||||||
|
|
||||||
|
- 2021/01/XX (0.9) - BeginLegendDragDropSource was changed to BeginDragDropSourceItem with a number of other drag and drop improvements.
|
||||||
- 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
|
- 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.
|
to implot_internal.h due to its immaturity.
|
||||||
- 2020/10/16 (0.8) - ImPlotStyleVar_InfoPadding was changed to ImPlotStyleVar_MousePosPadding
|
- 2020/10/16 (0.8) - ImPlotStyleVar_InfoPadding was changed to ImPlotStyleVar_MousePosPadding
|
||||||
|
@ -2265,31 +2266,7 @@ void EndPlot() {
|
||||||
DrawList.AddRectFilled(rect.Min, rect.Max, an.ColorBg);
|
DrawList.AddRectFilled(rect.Min, rect.Max, an.ColorBg);
|
||||||
DrawList.AddText(pos + gp.Style.AnnotationPadding, an.ColorFg, txt);
|
DrawList.AddText(pos + gp.Style.AnnotationPadding, an.ColorFg, txt);
|
||||||
}
|
}
|
||||||
PopPlotClipRect();
|
|
||||||
|
|
||||||
// render y-axis drag/drop hover
|
|
||||||
if ((plot.YAxis[1].Present || plot.YAxis[2].Present) && ImGui::IsDragDropPayloadBeingAccepted()) {
|
|
||||||
for (int i = 0; i < IMPLOT_Y_AXES; ++i) {
|
|
||||||
if (plot.YAxis[i].ExtHovered) {
|
|
||||||
float x_loc = gp.YAxisReference[i];
|
|
||||||
ImVec2 p1(x_loc - 5, plot.PlotRect.Min.y - 5);
|
|
||||||
ImVec2 p2(x_loc + 5, plot.PlotRect.Max.y + 5);
|
|
||||||
DrawList.AddRect(p1, p2, ImGui::GetColorU32(ImGuiCol_DragDropTarget), 0.0f, ImDrawCornerFlags_All, 2.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// render x-axis drag/drop hover
|
|
||||||
if (plot.XAxis.Present && ImGui::IsDragDropPayloadBeingAccepted()) {
|
|
||||||
if (plot.XAxis.ExtHovered) {
|
|
||||||
float y_loc = plot.XAxis.HoverRect.Min.y;
|
|
||||||
ImVec2 p1(plot.XAxis.HoverRect.Min.x - 5, y_loc - 5);
|
|
||||||
ImVec2 p2(plot.XAxis.HoverRect.Max.x + 5, y_loc + 5);
|
|
||||||
DrawList.AddRect(p1, p2, ImGui::GetColorU32(ImGuiCol_DragDropTarget), 0.0f, ImDrawCornerFlags_All, 2.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PushPlotClipRect();
|
|
||||||
// render selection/query
|
// render selection/query
|
||||||
if (plot.Selecting) {
|
if (plot.Selecting) {
|
||||||
const ImRect select_bb(ImMin(IO.MousePos, plot.SelectStart), ImMax(IO.MousePos, plot.SelectStart));
|
const ImRect select_bb(ImMin(IO.MousePos, plot.SelectStart), ImMax(IO.MousePos, plot.SelectStart));
|
||||||
|
@ -2423,9 +2400,9 @@ void EndPlot() {
|
||||||
legend_size,
|
legend_size,
|
||||||
plot.LegendLocation,
|
plot.LegendLocation,
|
||||||
plot.LegendOutside ? gp.Style.PlotPadding : gp.Style.LegendPadding);
|
plot.LegendOutside ? gp.Style.PlotPadding : gp.Style.LegendPadding);
|
||||||
const ImRect legend_bb(legend_pos, legend_pos + legend_size);
|
plot.LegendRect = ImRect(legend_pos, legend_pos + legend_size);
|
||||||
// test hover
|
// test hover
|
||||||
plot.LegendHovered = plot.FrameHovered && legend_bb.Contains(IO.MousePos);
|
plot.LegendHovered = plot.FrameHovered && plot.LegendRect.Contains(IO.MousePos);
|
||||||
|
|
||||||
if (plot.LegendOutside)
|
if (plot.LegendOutside)
|
||||||
ImGui::PushClipRect(plot.FrameRect.Min, plot.FrameRect.Max, true);
|
ImGui::PushClipRect(plot.FrameRect.Min, plot.FrameRect.Max, true);
|
||||||
|
@ -2433,11 +2410,14 @@ void EndPlot() {
|
||||||
PushPlotClipRect();
|
PushPlotClipRect();
|
||||||
ImU32 col_bg = GetStyleColorU32(ImPlotCol_LegendBg);
|
ImU32 col_bg = GetStyleColorU32(ImPlotCol_LegendBg);
|
||||||
ImU32 col_bd = GetStyleColorU32(ImPlotCol_LegendBorder);
|
ImU32 col_bd = GetStyleColorU32(ImPlotCol_LegendBorder);
|
||||||
DrawList.AddRectFilled(legend_bb.Min, legend_bb.Max, col_bg);
|
DrawList.AddRectFilled(plot.LegendRect.Min, plot.LegendRect.Max, col_bg);
|
||||||
DrawList.AddRect(legend_bb.Min, legend_bb.Max, col_bd);
|
DrawList.AddRect(plot.LegendRect.Min, plot.LegendRect.Max, col_bd);
|
||||||
ShowLegendEntries(plot, legend_bb, plot.LegendHovered, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, plot.LegendOrientation, DrawList);
|
ShowLegendEntries(plot, plot.LegendRect, plot.LegendHovered, gp.Style.LegendInnerPadding, gp.Style.LegendSpacing, plot.LegendOrientation, DrawList);
|
||||||
ImGui::PopClipRect();
|
ImGui::PopClipRect();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
plot.LegendRect = ImRect();
|
||||||
|
}
|
||||||
if (plot.LegendFlipSideNextFrame) {
|
if (plot.LegendFlipSideNextFrame) {
|
||||||
plot.LegendOutside = !plot.LegendOutside;
|
plot.LegendOutside = !plot.LegendOutside;
|
||||||
plot.LegendFlipSideNextFrame = false;
|
plot.LegendFlipSideNextFrame = false;
|
||||||
|
@ -2924,6 +2904,150 @@ bool DragPoint(const char* id, double* x, double* y, bool show_label, const ImVe
|
||||||
return dragging;
|
return dragging;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define IMPLOT_ID_PLT 10030910
|
||||||
|
#define IMPLOT_ID_LEG 10030911
|
||||||
|
#define IMPLOT_ID_XAX 10030912
|
||||||
|
#define IMPLOT_ID_YAX 10030913
|
||||||
|
|
||||||
|
bool BeginDragDropTargetEx(int id, const ImRect& rect) {
|
||||||
|
ImGuiContext& G = *GImGui;
|
||||||
|
const ImGuiID ID = G.CurrentWindow->GetID(id);
|
||||||
|
if (ImGui::ItemAdd(rect, ID, &rect) &&
|
||||||
|
ImGui::BeginDragDropTarget())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginDragDropTarget() {
|
||||||
|
return BeginDragDropTargetEx(IMPLOT_ID_PLT, GImPlot->CurrentPlot->PlotRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginDragDropTargetX() {
|
||||||
|
return BeginDragDropTargetEx(IMPLOT_ID_XAX, GImPlot->CurrentPlot->XAxis.HoverRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginDragDropTargetY(ImPlotYAxis axis) {
|
||||||
|
return BeginDragDropTargetEx(IMPLOT_ID_YAX + axis, GImPlot->CurrentPlot->YAxis[axis].HoverRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginDragDropTargetLegend() {
|
||||||
|
return !ImHasFlag(GImPlot->CurrentPlot->Flags,ImPlotFlags_NoLegend) &&
|
||||||
|
BeginDragDropTargetEx(IMPLOT_ID_LEG, GImPlot->CurrentPlot->LegendRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndDragDropTarget() {
|
||||||
|
ImGui::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginDragDropSourceEx(ImGuiID source_id, bool is_hovered, ImGuiDragDropFlags flags, ImGuiKeyModFlags key_mods) {
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
ImGuiMouseButton mouse_button = ImGuiMouseButton_Left;
|
||||||
|
|
||||||
|
if (g.IO.MouseDown[mouse_button] == false) {
|
||||||
|
if (g.ActiveId == source_id)
|
||||||
|
ImGui::ClearActiveID();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_hovered && g.IO.MouseClicked[mouse_button] && g.IO.KeyMods == key_mods) {
|
||||||
|
ImGui::SetActiveID(source_id, window);
|
||||||
|
ImGui::FocusWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g.ActiveId != source_id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
g.ActiveIdAllowOverlap = is_hovered;
|
||||||
|
g.ActiveIdUsingNavDirMask = ~(ImU32)0;
|
||||||
|
g.ActiveIdUsingNavInputMask = ~(ImU32)0;
|
||||||
|
g.ActiveIdUsingKeyInputMask = ~(ImU64)0;
|
||||||
|
|
||||||
|
if (ImGui::IsMouseDragging(mouse_button)) {
|
||||||
|
|
||||||
|
if (!g.DragDropActive) {
|
||||||
|
ImGui::ClearDragDrop();
|
||||||
|
ImGuiPayload& payload = g.DragDropPayload;
|
||||||
|
payload.SourceId = source_id;
|
||||||
|
payload.SourceParentId = 0;
|
||||||
|
g.DragDropActive = true;
|
||||||
|
g.DragDropSourceFlags = 0;
|
||||||
|
g.DragDropMouseButton = mouse_button;
|
||||||
|
}
|
||||||
|
g.DragDropSourceFrameCount = g.FrameCount;
|
||||||
|
g.DragDropWithinSource = true;
|
||||||
|
|
||||||
|
if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) {
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip)) {
|
||||||
|
ImGuiWindow* tooltip_window = g.CurrentWindow;
|
||||||
|
tooltip_window->SkipItems = true;
|
||||||
|
tooltip_window->HiddenFramesCanSkipItems = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginDragDropSource(ImGuiKeyModFlags key_mods, ImGuiDragDropFlags flags) {
|
||||||
|
if (ImGui::GetIO().KeyMods == key_mods) {
|
||||||
|
GImPlot->CurrentPlot->XAxis.Dragging = false;
|
||||||
|
for (int i = 0; i < IMPLOT_Y_AXES; ++i)
|
||||||
|
GImPlot->CurrentPlot->YAxis[i].Dragging = false;
|
||||||
|
}
|
||||||
|
const ImGuiID ID = GImGui->CurrentWindow->GetID(IMPLOT_ID_PLT);
|
||||||
|
ImRect rect = GImPlot->CurrentPlot->PlotRect;
|
||||||
|
return ImGui::ItemAdd(rect, ID, &rect) && BeginDragDropSourceEx(ID, GImPlot->CurrentPlot->PlotHovered, flags, key_mods);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginDragDropSourceX(ImGuiKeyModFlags key_mods, ImGuiDragDropFlags flags) {
|
||||||
|
if (ImGui::GetIO().KeyMods == key_mods)
|
||||||
|
GImPlot->CurrentPlot->XAxis.Dragging = false;
|
||||||
|
const ImGuiID ID = GImGui->CurrentWindow->GetID(IMPLOT_ID_XAX);
|
||||||
|
ImRect rect = GImPlot->CurrentPlot->XAxis.HoverRect;
|
||||||
|
return ImGui::ItemAdd(rect, ID, &rect) && BeginDragDropSourceEx(ID, GImPlot->CurrentPlot->XAxis.ExtHovered, flags, key_mods);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginDragDropSourceY(ImPlotYAxis axis, ImGuiKeyModFlags key_mods, ImGuiDragDropFlags flags) {
|
||||||
|
if (ImGui::GetIO().KeyMods == key_mods)
|
||||||
|
GImPlot->CurrentPlot->YAxis[axis].Dragging = false;
|
||||||
|
const ImGuiID ID = GImGui->CurrentWindow->GetID(IMPLOT_ID_YAX + axis);
|
||||||
|
ImRect rect = GImPlot->CurrentPlot->YAxis[axis].HoverRect;
|
||||||
|
return ImGui::ItemAdd(rect, ID, &rect) && BeginDragDropSourceEx(ID, GImPlot->CurrentPlot->YAxis[axis].ExtHovered, flags, key_mods);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BeginDragDropSourceItem(const char* label_id, ImGuiDragDropFlags flags) {
|
||||||
|
ImPlotContext& gp = *GImPlot;
|
||||||
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "BeginDragDropSourceItem() needs to be called between BeginPlot() and EndPlot()!");
|
||||||
|
ImGuiID source_id = ImGui::GetID(label_id);
|
||||||
|
ImPlotItem* item = gp.CurrentPlot->Items.GetByKey(source_id);
|
||||||
|
bool is_hovered = item && item->LegendHovered;
|
||||||
|
return BeginDragDropSourceEx(source_id, is_hovered, flags, ImGuiKeyModFlags_None);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EndDragDropSource() {
|
||||||
|
ImGui::EndDragDropSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemIcon(const ImVec4& col) {
|
||||||
|
ItemIcon(ImGui::ColorConvertFloat4ToU32(col));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemIcon(ImU32 col) {
|
||||||
|
const float txt_size = ImGui::GetTextLineHeight();
|
||||||
|
ImVec2 size(txt_size-4,txt_size);
|
||||||
|
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||||
|
ImVec2 pos = window->DC.CursorPos;
|
||||||
|
ImGui::GetWindowDrawList()->AddRectFilled(pos + ImVec2(0,2), pos + size - ImVec2(0,2), col);
|
||||||
|
ImGui::Dummy(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation, bool outside) {
|
void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation, bool outside) {
|
||||||
ImPlotContext& gp = *GImPlot;
|
ImPlotContext& gp = *GImPlot;
|
||||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "SetLegendLocation() needs to be called between BeginPlot() and EndPlot()!");
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "SetLegendLocation() needs to be called between BeginPlot() and EndPlot()!");
|
||||||
|
@ -2947,74 +3071,9 @@ bool IsLegendEntryHovered(const char* label_id) {
|
||||||
return item && item->LegendHovered;
|
return item && item->LegendHovered;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BeginLegendDragDropSource(const char* label_id, ImGuiDragDropFlags flags) {
|
|
||||||
ImPlotContext& gp = *GImPlot;
|
|
||||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "BeginLegendDragDropSource() needs to be called between BeginPlot() and EndPlot()!");
|
|
||||||
ImGuiID source_id = ImGui::GetID(label_id);
|
|
||||||
ImPlotItem* item = gp.CurrentPlot->Items.GetByKey(source_id);
|
|
||||||
bool is_hovered = item && item->LegendHovered;
|
|
||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
|
||||||
|
|
||||||
ImGuiMouseButton mouse_button = ImGuiMouseButton_Left;
|
|
||||||
|
|
||||||
if (g.IO.MouseDown[mouse_button] == false) {
|
|
||||||
if (g.ActiveId == source_id)
|
|
||||||
ImGui::ClearActiveID();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_hovered && g.IO.MouseClicked[mouse_button]) {
|
|
||||||
ImGui::SetActiveID(source_id, window);
|
|
||||||
ImGui::FocusWindow(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g.ActiveId != source_id)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Allow the underlying widget to display/return hovered during the mouse
|
|
||||||
// release frame, else we would get a flicker.
|
|
||||||
g.ActiveIdAllowOverlap = is_hovered;
|
|
||||||
|
|
||||||
// Disable navigation and key inputs while dragging
|
|
||||||
g.ActiveIdUsingNavDirMask = ~(ImU32)0;
|
|
||||||
g.ActiveIdUsingNavInputMask = ~(ImU32)0;
|
|
||||||
g.ActiveIdUsingKeyInputMask = ~(ImU64)0;
|
|
||||||
|
|
||||||
if (ImGui::IsMouseDragging(mouse_button)) {
|
|
||||||
if (!g.DragDropActive) {
|
|
||||||
ImGui::ClearDragDrop();
|
|
||||||
ImGuiPayload& payload = g.DragDropPayload;
|
|
||||||
payload.SourceId = source_id;
|
|
||||||
payload.SourceParentId = 0;
|
|
||||||
g.DragDropActive = true;
|
|
||||||
g.DragDropSourceFlags = 0;
|
|
||||||
g.DragDropMouseButton = mouse_button;
|
|
||||||
}
|
|
||||||
g.DragDropSourceFrameCount = g.FrameCount;
|
|
||||||
g.DragDropWithinSource = true;
|
|
||||||
|
|
||||||
if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) {
|
|
||||||
// Target can request the Source to not display its tooltip (we use a
|
|
||||||
// dedicated flag to make this request explicit) We unfortunately can't
|
|
||||||
// just modify the source flags and skip the call to BeginTooltip, as
|
|
||||||
// caller may be emitting contents.
|
|
||||||
ImGui::BeginTooltip();
|
|
||||||
if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip)) {
|
|
||||||
ImGuiWindow* tooltip_window = g.CurrentWindow;
|
|
||||||
tooltip_window->SkipItems = true;
|
|
||||||
tooltip_window->HiddenFramesCanSkipItems = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EndLegendDragDropSource() {
|
|
||||||
ImGui::EndDragDropSource();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BeginLegendPopup(const char* label_id, ImGuiMouseButton mouse_button) {
|
bool BeginLegendPopup(const char* label_id, ImGuiMouseButton mouse_button) {
|
||||||
ImPlotContext& gp = *GImPlot;
|
ImPlotContext& gp = *GImPlot;
|
||||||
|
|
42
implot.h
42
implot.h
|
@ -527,7 +527,7 @@ IMPLOT_API bool DragPoint(const char* id, double* x, double* y, bool show_label
|
||||||
// Legend Utils and Tools
|
// Legend Utils and Tools
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// The following functions MUST be called between Begin/EndPlot!
|
// The following functions MUST be called BETWEEN Begin/EndPlot!
|
||||||
|
|
||||||
// Set the location of the current plot's legend.
|
// Set the location of the current plot's legend.
|
||||||
IMPLOT_API void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation = ImPlotOrientation_Vertical, bool outside = false);
|
IMPLOT_API void SetLegendLocation(ImPlotLocation location, ImPlotOrientation orientation = ImPlotOrientation_Vertical, bool outside = false);
|
||||||
|
@ -535,15 +535,43 @@ IMPLOT_API void SetLegendLocation(ImPlotLocation location, ImPlotOrientation ori
|
||||||
IMPLOT_API void SetMousePosLocation(ImPlotLocation location);
|
IMPLOT_API void SetMousePosLocation(ImPlotLocation location);
|
||||||
// Returns true if a plot item legend entry is hovered.
|
// Returns true if a plot item legend entry is hovered.
|
||||||
IMPLOT_API bool IsLegendEntryHovered(const char* label_id);
|
IMPLOT_API bool IsLegendEntryHovered(const char* label_id);
|
||||||
// Begin a drag and drop source from a legend entry. The only supported flag is SourceNoPreviewTooltip
|
|
||||||
IMPLOT_API bool BeginLegendDragDropSource(const char* label_id, ImGuiDragDropFlags flags = 0);
|
|
||||||
// End legend drag and drop source.
|
|
||||||
IMPLOT_API void EndLegendDragDropSource();
|
|
||||||
// Begin a popup for a legend entry.
|
// Begin a popup for a legend entry.
|
||||||
IMPLOT_API bool BeginLegendPopup(const char* label_id, ImGuiMouseButton mouse_button = 1);
|
IMPLOT_API bool BeginLegendPopup(const char* label_id, ImGuiMouseButton mouse_button = 1);
|
||||||
// End a popup for a legend entry.
|
// End a popup for a legend entry.
|
||||||
IMPLOT_API void EndLegendPopup();
|
IMPLOT_API void EndLegendPopup();
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Drag and Drop Utils
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// The following functions MUST be called BETWEEN Begin/EndPlot!
|
||||||
|
|
||||||
|
// Turns the current plot's plotting area into a drag and drop target. Don't forget to call EndDragDropTarget!
|
||||||
|
IMPLOT_API bool BeginDragDropTarget();
|
||||||
|
// Turns the current plot's X-axis into a drag and drop target. Don't forget to call EndDragDropTarget!
|
||||||
|
IMPLOT_API bool BeginDragDropTargetX();
|
||||||
|
// Turns the current plot's Y-Axis into a drag and drop target. Don't forget to call EndDragDropTarget!
|
||||||
|
IMPLOT_API bool BeginDragDropTargetY(ImPlotYAxis axis = ImPlotYAxis_1);
|
||||||
|
// Turns the current plot's legend into a drag and drop target. Don't forget to call EndDragDropTarget!
|
||||||
|
IMPLOT_API bool BeginDragDropTargetLegend();
|
||||||
|
// Ends a drag and drop target (currently just an alias for ImGui::EndDragDropTarget).
|
||||||
|
IMPLOT_API void EndDragDropTarget();
|
||||||
|
|
||||||
|
// NB: By default, plot and axes drag and drop sources require holding the Ctrl modifier to initiate the drag.
|
||||||
|
// You can change the modifier if desired. If ImGuiKeyModFlags_None is provided, the axes will be locked from panning.
|
||||||
|
|
||||||
|
// Turns the current plot's plotting area into a drag and drop source. Don't forget to call EndDragDropSource!
|
||||||
|
IMPLOT_API bool BeginDragDropSource(ImGuiKeyModFlags key_mods = ImGuiKeyModFlags_Ctrl, ImGuiDragDropFlags flags = 0);
|
||||||
|
// Turns the current plot's X-axis into a drag and drop source. Don't forget to call EndDragDropSource!
|
||||||
|
IMPLOT_API bool BeginDragDropSourceX(ImGuiKeyModFlags key_mods = ImGuiKeyModFlags_Ctrl, ImGuiDragDropFlags flags = 0);
|
||||||
|
// Turns the current plot's Y-axis into a drag and drop source. Don't forget to call EndDragDropSource!
|
||||||
|
IMPLOT_API bool BeginDragDropSourceY(ImPlotYAxis axis = ImPlotYAxis_1, ImGuiKeyModFlags key_mods = ImGuiKeyModFlags_Ctrl, ImGuiDragDropFlags flags = 0);
|
||||||
|
// Turns an item in the current plot's legend into drag and drop source. Don't forget to call EndDragDropSource!
|
||||||
|
IMPLOT_API bool BeginDragDropSourceItem(const char* label_id, ImGuiDragDropFlags flags = 0);
|
||||||
|
// Ends a drag and drop source (currently just an alias for ImGui::EndDragDropSource).
|
||||||
|
IMPLOT_API void EndDragDropSource();
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Plot and Item Styling
|
// Plot and Item Styling
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -645,6 +673,10 @@ IMPLOT_API const char* GetColormapName(ImPlotColormap colormap);
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Render a icon similar to those that appear in legends (nifty for data lists).
|
||||||
|
IMPLOT_API void ItemIcon(const ImVec4& col);
|
||||||
|
IMPLOT_API void ItemIcon(ImU32 col);
|
||||||
|
|
||||||
// Get the plot draw list for rendering to the current plot area.
|
// Get the plot draw list for rendering to the current plot area.
|
||||||
IMPLOT_API ImDrawList* GetPlotDrawList();
|
IMPLOT_API ImDrawList* GetPlotDrawList();
|
||||||
// Push clip rect for rendering to current plot area.
|
// Push clip rect for rendering to current plot area.
|
||||||
|
|
329
implot_demo.cpp
329
implot_demo.cpp
|
@ -81,8 +81,8 @@ struct ScrollingBuffer {
|
||||||
int MaxSize;
|
int MaxSize;
|
||||||
int Offset;
|
int Offset;
|
||||||
ImVector<ImVec2> Data;
|
ImVector<ImVec2> Data;
|
||||||
ScrollingBuffer() {
|
ScrollingBuffer(int max_size = 2000) {
|
||||||
MaxSize = 2000;
|
MaxSize = max_size;
|
||||||
Offset = 0;
|
Offset = 0;
|
||||||
Data.reserve(MaxSize);
|
Data.reserve(MaxSize);
|
||||||
}
|
}
|
||||||
|
@ -663,8 +663,8 @@ void ShowDemoWindow(bool* p_open) {
|
||||||
}
|
}
|
||||||
if (ImGui::CollapsingHeader("Time Formatted Axes")) {
|
if (ImGui::CollapsingHeader("Time Formatted Axes")) {
|
||||||
|
|
||||||
static double t_min = 1577836800; // 01/01/2020 @ 12:00:00am (UTC)
|
static double t_min = 1609459200; // 01/01/2021 @ 12:00:00am (UTC)
|
||||||
static double t_max = 1609459200; // 01/01/2021 @ 12:00:00am (UTC)
|
static double t_max = 1640995200; // 01/01/2022 @ 12:00:00am (UTC)
|
||||||
|
|
||||||
ImGui::BulletText("When ImPlotAxisFlags_Time is enabled on the X-Axis, values are interpreted as\n"
|
ImGui::BulletText("When ImPlotAxisFlags_Time is enabled on the X-Axis, values are interpreted as\n"
|
||||||
"UNIX timestamps in seconds and axis labels are formated as date/time.");
|
"UNIX timestamps in seconds and axis labels are formated as date/time.");
|
||||||
|
@ -969,175 +969,216 @@ void ShowDemoWindow(bool* p_open) {
|
||||||
}
|
}
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
if (ImGui::CollapsingHeader("Drag and Drop")) {
|
if (ImGui::CollapsingHeader("Drag and Drop")) {
|
||||||
const int K_CHANNELS = 9;
|
ImGui::BulletText("Drag/drop items from the left column.");
|
||||||
srand((int)(10000000 * DEMO_TIME));
|
ImGui::BulletText("Drag/drop items between plots.");
|
||||||
static bool paused = false;
|
ImGui::Indent();
|
||||||
static bool init = true;
|
ImGui::BulletText("Plot 1 Targets: Plot, Y-Axes, Legend");
|
||||||
static ScrollingBuffer data[K_CHANNELS];
|
ImGui::BulletText("Plot 1 Sources: Legend Items");
|
||||||
static bool show[K_CHANNELS];
|
ImGui::BulletText("Plot 2 Targets: Plot, X-Axis, Y-Axis");
|
||||||
static int yAxis[K_CHANNELS];
|
ImGui::BulletText("Plot 2 Sources: Plot, X-Axis, Y-Axis (hold Ctrl)");
|
||||||
if (init) {
|
ImGui::Unindent();
|
||||||
for (int i = 0; i < K_CHANNELS; ++i) {
|
|
||||||
show[i] = false;
|
// convenience struct to manage DND items; do this however you like
|
||||||
yAxis[i] = 0;
|
struct MyDndItem {
|
||||||
|
int Idx;
|
||||||
|
int Plt;
|
||||||
|
int Yax;
|
||||||
|
char Label[16];
|
||||||
|
ImVector<ImVec2> Data;
|
||||||
|
ImVec4 Color;
|
||||||
|
MyDndItem() {
|
||||||
|
static int i = 0;
|
||||||
|
Idx = i++;
|
||||||
|
Plt = 0;
|
||||||
|
Yax = ImPlotYAxis_1;
|
||||||
|
sprintf(Label, "%02d Hz", Idx+1);
|
||||||
|
Color = ImPlot::GetColormapColor(Idx);
|
||||||
|
Data.reserve(1001);
|
||||||
|
for (int k = 0; k < 1001; ++k) {
|
||||||
|
float t = k * 1.0f / 999;
|
||||||
|
Data.push_back(ImVec2(t, 0.5f + 0.5f * sinf(2*3.14f*t*(Idx+1))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
init = false;
|
void Reset() { Plt = 0; Yax = ImPlotYAxis_1; }
|
||||||
|
};
|
||||||
|
|
||||||
|
const int k_dnd = 20;
|
||||||
|
static MyDndItem dnd[k_dnd];
|
||||||
|
static MyDndItem* dndx = NULL; // for plot 2
|
||||||
|
static MyDndItem* dndy = NULL; // for plot 2
|
||||||
|
|
||||||
|
// child window to serve as initial source for our DND items
|
||||||
|
ImGui::BeginChild("DND_LEFT",ImVec2(100,400));
|
||||||
|
if (ImGui::Button("Reset Data", ImVec2(100, 0))) {
|
||||||
|
for (int k = 0; k < k_dnd; ++k)
|
||||||
|
dnd[k].Reset();
|
||||||
|
dndx = dndy = NULL;
|
||||||
}
|
}
|
||||||
ImGui::BulletText("Drag data items from the left column onto the plot or onto a specific y-axis.");
|
for (int k = 0; k < k_dnd; ++k) {
|
||||||
ImGui::BulletText("Redrag data items from the legend onto other y-axes.");
|
if (dnd[k].Plt > 0)
|
||||||
ImGui::BeginGroup();
|
continue;
|
||||||
if (ImGui::Button("Clear", ImVec2(100, 0))) {
|
ImPlot::ItemIcon(dnd[k].Color); ImGui::SameLine();
|
||||||
for (int i = 0; i < K_CHANNELS; ++i) {
|
ImGui::Selectable(dnd[k].Label, false, 0, ImVec2(100, 0));
|
||||||
show[i] = false;
|
|
||||||
data[i].Data.shrink(0);
|
|
||||||
data[i].Offset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ImGui::Button(paused ? "Resume" : "Pause", ImVec2(100,0)))
|
|
||||||
paused = !paused;
|
|
||||||
for (int i = 0; i < K_CHANNELS; ++i) {
|
|
||||||
char label[16];
|
|
||||||
sprintf(label, show[i] ? "data_%d (Y%d)" : "data_%d", i, yAxis[i]+1);
|
|
||||||
ImGui::Selectable(label, false, 0, ImVec2(100, 0));
|
|
||||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||||
ImGui::SetDragDropPayload("DND_PLOT", &i, sizeof(int));
|
ImGui::SetDragDropPayload("MY_DND", &k, sizeof(int));
|
||||||
ImGui::TextUnformatted(label);
|
ImPlot::ItemIcon(dnd[k].Color); ImGui::SameLine();
|
||||||
|
ImGui::TextUnformatted(dnd[k].Label);
|
||||||
ImGui::EndDragDropSource();
|
ImGui::EndDragDropSource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndGroup();
|
ImGui::EndChild();
|
||||||
ImGui::SameLine();
|
if (ImGui::BeginDragDropTarget()) {
|
||||||
srand((unsigned int)DEMO_TIME*10000000);
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) {
|
||||||
static float t = 0;
|
int i = *(int*)payload->Data; dnd[i].Reset();
|
||||||
if (!paused) {
|
|
||||||
t += ImGui::GetIO().DeltaTime;
|
|
||||||
for (int i = 0; i < K_CHANNELS; ++i) {
|
|
||||||
if (show[i])
|
|
||||||
data[i].AddPoint(t, (i+1)*0.1f + RandomRange(-0.01f,0.01f));
|
|
||||||
}
|
}
|
||||||
|
ImGui::EndDragDropTarget();
|
||||||
}
|
}
|
||||||
ImPlot::SetNextPlotLimitsX((double)t - 10, t, paused ? ImGuiCond_Once : ImGuiCond_Always);
|
|
||||||
if (ImPlot::BeginPlot("##DND", NULL, NULL, ImVec2(-1,0), ImPlotFlags_YAxis2 | ImPlotFlags_YAxis3, ImPlotAxisFlags_NoTickLabels)) {
|
ImGui::SameLine();
|
||||||
for (int i = 0; i < K_CHANNELS; ++i) {
|
ImGui::BeginChild("DND_RIGHT",ImVec2(-1,400));
|
||||||
if (show[i] && data[i].Data.size() > 0) {
|
// plot 1 (time series)
|
||||||
char label[K_CHANNELS];
|
ImPlotAxisFlags flags = ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines;
|
||||||
sprintf(label, "data_%d", i);
|
if (ImPlot::BeginPlot("##DND1", NULL, "[drop here]", ImVec2(-1,195), ImPlotFlags_YAxis2 | ImPlotFlags_YAxis3, flags | ImPlotAxisFlags_Lock, flags, flags, flags, "[drop here]", "[drop here]")) {
|
||||||
ImPlot::SetPlotYAxis(yAxis[i]);
|
for (int k = 0; k < k_dnd; ++k) {
|
||||||
ImPlot::PlotLine(label, &data[i].Data[0].x, &data[i].Data[0].y, data[i].Data.size(), data[i].Offset, 2 * sizeof(float));
|
if (dnd[k].Plt == 1 && dnd[k].Data.size() > 0) {
|
||||||
// allow legend labels to be dragged and dropped
|
ImPlot::SetPlotYAxis(dnd[k].Yax);
|
||||||
if (ImPlot::BeginLegendDragDropSource(label)) {
|
ImPlot::SetNextLineStyle(dnd[k].Color);
|
||||||
ImGui::SetDragDropPayload("DND_PLOT", &i, sizeof(int));
|
static char label[16];
|
||||||
ImGui::TextUnformatted(label);
|
sprintf(label,"%s (Y%d)", dnd[k].Label, dnd[k].Yax+1);
|
||||||
ImPlot::EndLegendDragDropSource();
|
ImPlot::PlotLine(label, &dnd[k].Data[0].x, &dnd[k].Data[0].y, dnd[k].Data.size(), 0, 2 * sizeof(float));
|
||||||
|
// allow legend item labels to be DND sources
|
||||||
|
if (ImPlot::BeginDragDropSourceItem(label)) {
|
||||||
|
ImGui::SetDragDropPayload("MY_DND", &k, sizeof(int));
|
||||||
|
ImPlot::ItemIcon(dnd[k].Color); ImGui::SameLine();
|
||||||
|
ImGui::TextUnformatted(dnd[k].Label);
|
||||||
|
ImPlot::EndDragDropSource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// make our plot a drag and drop target
|
// allow the main plot area to be a DND target
|
||||||
if (ImGui::BeginDragDropTarget()) {
|
if (ImPlot::BeginDragDropTarget()) {
|
||||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_PLOT")) {
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) {
|
||||||
int i = *(int*)payload->Data;
|
int i = *(int*)payload->Data; dnd[i].Plt = 1; dnd[i].Yax = 0;
|
||||||
show[i] = true;
|
}
|
||||||
yAxis[i] = 0;
|
ImPlot::EndDragDropTarget();
|
||||||
// set specific y-axis if hovered
|
}
|
||||||
for (int y = 0; y < 3; y++) {
|
// allow each y-axis to be a DND target
|
||||||
if (ImPlot::IsPlotYAxisHovered(y))
|
for (int y = 0; y < 3; ++y) {
|
||||||
yAxis[i] = y;
|
if (ImPlot::BeginDragDropTargetY(y)) {
|
||||||
}
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) {
|
||||||
}
|
int i = *(int*)payload->Data; dnd[i].Plt = 1; dnd[i].Yax = y;
|
||||||
ImGui::EndDragDropTarget();
|
}
|
||||||
}
|
ImPlot::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// allow the legend to be a DND target
|
||||||
|
if (ImPlot::BeginDragDropTargetLegend()) {
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) {
|
||||||
|
int i = *(int*)payload->Data; dnd[i].Plt = 1; dnd[i].Yax = 0;
|
||||||
|
}
|
||||||
|
ImPlot::EndDragDropTarget();
|
||||||
|
}
|
||||||
ImPlot::EndPlot();
|
ImPlot::EndPlot();
|
||||||
}
|
}
|
||||||
|
// plot 2 (Lissajous)
|
||||||
|
ImPlot::PushStyleColor(ImPlotCol_XAxis, dndx == NULL ? ImPlot::GetStyle().Colors[ImPlotCol_XAxis] : dndx->Color);
|
||||||
|
ImPlot::PushStyleColor(ImPlotCol_YAxis, dndy == NULL ? ImPlot::GetStyle().Colors[ImPlotCol_YAxis] : dndy->Color);
|
||||||
|
if (ImPlot::BeginPlot("##DND2", dndx == NULL ? "[drop here]" : dndx->Label, dndy == NULL ? "[drop here]" : dndy->Label, ImVec2(-1,195), 0, flags, flags )) {
|
||||||
|
if (dndx != NULL && dndy != NULL) {
|
||||||
|
ImVec4 mixed((dndx->Color.x + dndy->Color.x)/2,(dndx->Color.y + dndy->Color.y)/2,(dndx->Color.z + dndy->Color.z)/2,(dndx->Color.w + dndy->Color.w)/2);
|
||||||
|
ImPlot::SetNextLineStyle(mixed);
|
||||||
|
ImPlot::PlotLine("##dndxy", &dndx->Data[0].y, &dndy->Data[0].y, dndx->Data.size(), 0, 2 * sizeof(float));
|
||||||
|
}
|
||||||
|
// allow the x-axis to be a DND target
|
||||||
|
if (ImPlot::BeginDragDropTargetX()) {
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) {
|
||||||
|
int i = *(int*)payload->Data; dndx = &dnd[i];
|
||||||
|
}
|
||||||
|
ImPlot::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
// allow the x-axis to be a DND source
|
||||||
|
if (dndx != NULL && ImPlot::BeginDragDropSourceX()) {
|
||||||
|
ImGui::SetDragDropPayload("MY_DND", &dndx->Idx, sizeof(int));
|
||||||
|
ImPlot::ItemIcon(dndx->Color); ImGui::SameLine();
|
||||||
|
ImGui::TextUnformatted(dndx->Label);
|
||||||
|
ImPlot::EndDragDropSource();
|
||||||
|
}
|
||||||
|
// allow the y-axis to be a DND target
|
||||||
|
if (ImPlot::BeginDragDropTargetY()) {
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) {
|
||||||
|
int i = *(int*)payload->Data; dndy = &dnd[i];
|
||||||
|
}
|
||||||
|
ImPlot::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
// allow the y-axis to be a DND source
|
||||||
|
if (dndy != NULL && ImPlot::BeginDragDropSourceY()) {
|
||||||
|
ImGui::SetDragDropPayload("MY_DND", &dndy->Idx, sizeof(int));
|
||||||
|
ImPlot::ItemIcon(dndy->Color); ImGui::SameLine();
|
||||||
|
ImGui::TextUnformatted(dndy->Label);
|
||||||
|
ImPlot::EndDragDropSource();
|
||||||
|
}
|
||||||
|
// allow the plot area to be a DND target
|
||||||
|
if (ImPlot::BeginDragDropTarget()) {
|
||||||
|
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) {
|
||||||
|
int i = *(int*)payload->Data; dndx = dndy = &dnd[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// allow the plot area to be a DND source
|
||||||
|
if (ImPlot::BeginDragDropSource()) {
|
||||||
|
ImGui::TextUnformatted("Yes, you can\ndrag this!");
|
||||||
|
ImPlot::EndDragDropSource();
|
||||||
|
}
|
||||||
|
ImPlot::EndPlot();
|
||||||
|
}
|
||||||
|
ImPlot::PopStyleColor(2);
|
||||||
|
ImGui::EndChild();
|
||||||
}
|
}
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
if (ImGui::CollapsingHeader("Digital and Analog Signals")) {
|
if (ImGui::CollapsingHeader("Digital and Analog Signals")) {
|
||||||
static bool paused = false;
|
|
||||||
#define K_PLOT_DIGITAL_CH_COUNT 4
|
|
||||||
#define K_PLOT_ANALOG_CH_COUNT 4
|
|
||||||
static ScrollingBuffer dataDigital[K_PLOT_DIGITAL_CH_COUNT];
|
|
||||||
static ScrollingBuffer dataAnalog[K_PLOT_ANALOG_CH_COUNT];
|
|
||||||
static bool showDigital[K_PLOT_DIGITAL_CH_COUNT];
|
|
||||||
static bool showAnalog[K_PLOT_ANALOG_CH_COUNT];
|
|
||||||
|
|
||||||
ImGui::BulletText("You can plot digital and analog signals on the same plot.");
|
ImGui::BulletText("You can plot digital and analog signals on the same plot.");
|
||||||
ImGui::BulletText("Digital signals do not respond to Y drag and zoom, so that");
|
ImGui::BulletText("Digital signals do not respond to Y drag and zoom, so that");
|
||||||
ImGui::Indent();
|
ImGui::Indent();
|
||||||
ImGui::Text("you can drag analog signals over the rising/falling digital edge.");
|
ImGui::Text("you can drag analog signals over the rising/falling digital edge.");
|
||||||
ImGui::Unindent();
|
ImGui::Unindent();
|
||||||
ImGui::BeginGroup();
|
|
||||||
if (ImGui::Button("Clear", ImVec2(100, 0))) {
|
static bool paused = false;
|
||||||
for (int i = 0; i < K_PLOT_DIGITAL_CH_COUNT; ++i)
|
static ScrollingBuffer dataDigital[2];
|
||||||
showDigital[i] = false;
|
static ScrollingBuffer dataAnalog[2];
|
||||||
for (int i = 0; i < K_PLOT_ANALOG_CH_COUNT; ++i)
|
static bool showDigital[2] = {true, false};
|
||||||
showAnalog[i] = false;
|
static bool showAnalog[2] = {true, false};
|
||||||
}
|
|
||||||
if (ImGui::Button(paused ? "Resume" : "Pause", ImVec2(100,0)))
|
char label[32];
|
||||||
paused = !paused;
|
ImGui::Checkbox("digital_0", &showDigital[0]); ImGui::SameLine();
|
||||||
for (int i = 0; i < K_PLOT_DIGITAL_CH_COUNT; ++i) {
|
ImGui::Checkbox("digital_1", &showDigital[1]); ImGui::SameLine();
|
||||||
char label[32];
|
ImGui::Checkbox("analog_0", &showAnalog[0]); ImGui::SameLine();
|
||||||
sprintf(label, "digital_%d", i);
|
ImGui::Checkbox("analog_1", &showAnalog[1]);
|
||||||
ImGui::Checkbox(label, &showDigital[i]);
|
|
||||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
|
||||||
ImGui::SetDragDropPayload("DND_DIGITAL_PLOT", &i, sizeof(int));
|
|
||||||
ImGui::TextUnformatted(label);
|
|
||||||
ImGui::EndDragDropSource();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < K_PLOT_ANALOG_CH_COUNT; ++i) {
|
|
||||||
char label[32];
|
|
||||||
sprintf(label, "analog_%d", i);
|
|
||||||
ImGui::Checkbox(label, &showAnalog[i]);
|
|
||||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
|
||||||
ImGui::SetDragDropPayload("DND_ANALOG_PLOT", &i, sizeof(int));
|
|
||||||
ImGui::TextUnformatted(label);
|
|
||||||
ImGui::EndDragDropSource();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndGroup();
|
|
||||||
ImGui::SameLine();
|
|
||||||
static float t = 0;
|
static float t = 0;
|
||||||
if (!paused) {
|
if (!paused) {
|
||||||
t += ImGui::GetIO().DeltaTime;
|
t += ImGui::GetIO().DeltaTime;
|
||||||
//digital signal values
|
//digital signal values
|
||||||
int i = 0;
|
if (showDigital[0])
|
||||||
if (showDigital[i])
|
dataDigital[0].AddPoint(t, sinf(2*t) > 0.45);
|
||||||
dataDigital[i].AddPoint(t, sinf(2*t) > 0.45);
|
if (showDigital[1])
|
||||||
i++;
|
dataDigital[1].AddPoint(t, sinf(2*t) < 0.45);
|
||||||
if (showDigital[i])
|
|
||||||
dataDigital[i].AddPoint(t, sinf(2*t) < 0.45);
|
|
||||||
i++;
|
|
||||||
if (showDigital[i])
|
|
||||||
dataDigital[i].AddPoint(t, fmodf(t,5.0f));
|
|
||||||
i++;
|
|
||||||
if (showDigital[i])
|
|
||||||
dataDigital[i].AddPoint(t, sinf(2*t) < 0.17);
|
|
||||||
//Analog signal values
|
//Analog signal values
|
||||||
i = 0;
|
if (showAnalog[0])
|
||||||
if (showAnalog[i])
|
dataAnalog[0].AddPoint(t, sinf(2*t));
|
||||||
dataAnalog[i].AddPoint(t, sinf(2*t));
|
if (showAnalog[1])
|
||||||
i++;
|
dataAnalog[1].AddPoint(t, cosf(2*t));
|
||||||
if (showAnalog[i])
|
|
||||||
dataAnalog[i].AddPoint(t, cosf(2*t));
|
|
||||||
i++;
|
|
||||||
if (showAnalog[i])
|
|
||||||
dataAnalog[i].AddPoint(t, sinf(2*t) * cosf(2*t));
|
|
||||||
i++;
|
|
||||||
if (showAnalog[i])
|
|
||||||
dataAnalog[i].AddPoint(t, sinf(2*t) - cosf(2*t));
|
|
||||||
}
|
}
|
||||||
ImPlot::SetNextPlotLimitsY(-1, 1);
|
ImPlot::SetNextPlotLimitsY(-1, 1);
|
||||||
ImPlot::SetNextPlotLimitsX(t - 10.0, t, paused ? ImGuiCond_Once : ImGuiCond_Always);
|
ImPlot::SetNextPlotLimitsX(t - 10.0, t, paused ? ImGuiCond_Once : ImGuiCond_Always);
|
||||||
if (ImPlot::BeginPlot("##Digital")) {
|
if (ImPlot::BeginPlot("##Digital")) {
|
||||||
for (int i = 0; i < K_PLOT_DIGITAL_CH_COUNT; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
if (showDigital[i] && dataDigital[i].Data.size() > 0) {
|
if (showDigital[i] && dataDigital[i].Data.size() > 0) {
|
||||||
char label[32];
|
|
||||||
sprintf(label, "digital_%d", i);
|
sprintf(label, "digital_%d", i);
|
||||||
ImPlot::PlotDigital(label, &dataDigital[i].Data[0].x, &dataDigital[i].Data[0].y, dataDigital[i].Data.size(), dataDigital[i].Offset, 2 * sizeof(float));
|
ImPlot::PlotDigital(label, &dataDigital[i].Data[0].x, &dataDigital[i].Data[0].y, dataDigital[i].Data.size(), dataDigital[i].Offset, 2 * sizeof(float));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < K_PLOT_ANALOG_CH_COUNT; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
if (showAnalog[i]) {
|
if (showAnalog[i]) {
|
||||||
char label[32];
|
|
||||||
sprintf(label, "analog_%d", i);
|
sprintf(label, "analog_%d", i);
|
||||||
if (dataAnalog[i].Data.size() > 0)
|
if (dataAnalog[i].Data.size() > 0)
|
||||||
ImPlot::PlotLine(label, &dataAnalog[i].Data[0].x, &dataAnalog[i].Data[0].y, dataAnalog[i].Data.size(), dataAnalog[i].Offset, 2 * sizeof(float));
|
ImPlot::PlotLine(label, &dataAnalog[i].Data[0].x, &dataAnalog[i].Data[0].y, dataAnalog[i].Data.size(), dataAnalog[i].Offset, 2 * sizeof(float));
|
||||||
|
@ -1145,22 +1186,6 @@ void ShowDemoWindow(bool* p_open) {
|
||||||
}
|
}
|
||||||
ImPlot::EndPlot();
|
ImPlot::EndPlot();
|
||||||
}
|
}
|
||||||
if (ImGui::BeginDragDropTarget()) {
|
|
||||||
const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_DIGITAL_PLOT");
|
|
||||||
if (payload) {
|
|
||||||
int i = *(int*)payload->Data;
|
|
||||||
showDigital[i] = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
payload = ImGui::AcceptDragDropPayload("DND_ANALOG_PLOT");
|
|
||||||
if (payload) {
|
|
||||||
int i = *(int*)payload->Data;
|
|
||||||
showAnalog[i] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndDragDropTarget();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ImGui::CollapsingHeader("Tables")) {
|
if (ImGui::CollapsingHeader("Tables")) {
|
||||||
#ifdef IMGUI_HAS_TABLE
|
#ifdef IMGUI_HAS_TABLE
|
||||||
|
|
|
@ -572,6 +572,7 @@ struct ImPlotPlot
|
||||||
ImRect CanvasRect;
|
ImRect CanvasRect;
|
||||||
ImRect PlotRect;
|
ImRect PlotRect;
|
||||||
ImRect AxesRect;
|
ImRect AxesRect;
|
||||||
|
ImRect LegendRect;
|
||||||
|
|
||||||
ImPlotPlot() {
|
ImPlotPlot() {
|
||||||
Flags = PreviousFlags = ImPlotFlags_None;
|
Flags = PreviousFlags = ImPlotFlags_None;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user