implot icon indicating copy to clipboard operation
implot copied to clipboard

IsAnnotationHovered() or equivalent

Open fecaltransplant opened this issue 2 years ago • 1 comments

Hi,

This is the second time I'm bothering you, but you were quite helpful last time and now I'm back. If the below has been answered elsewhere, please excuse the redundancy; I've done what I thought was a reasonably-thorough check of what's been asked as well as meandering through the ImPlot and demo source code.

I'm using the annotation feature which is working great. Is there an equivalent of ImGui::IsItemHovered() for the annotation? I would like to be able to select it for deletion or to drag it so that the text can be moved as seen below:

before

and adjust the text to a new position (by dragging):

after

If there is no equivalent IsItemHovered() feature for annotation, would there be another avenue you'd recommend to adjust these positions of annotated items?

Thanks!

fecaltransplant avatar Dec 22 '23 01:12 fecaltransplant

try this:

#include "implot_internal.h"
bool DragAnnotation(int n_id, double x, double y, ImVec2 *offset, const ImVec4& col, const char* fmt, ...) 
{
    // first draw Annotation 
    const ImVec4 color = ImPlot::IsColorAuto(col) ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : col;
    va_list args;
    va_start(args, fmt);
    char txt[1024];
    ImFormatStringV(txt , 1024, fmt, args);
    ImPlot::Annotation(x, y, color, *offset, false, txt);
    va_end(args);
    
    // copy from DragPoint in implot.cpp
    ImGui::PushID("#IMPLOT_DRAG_Annotation");
    IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "DragPoint() needs to be called between BeginPlot() and EndPlot()!");
    ImPlot::SetupLock();
    
    ImVec2 pos0 = ImPlot::PlotToPixels(x,y), pos=pos0;
    const ImGuiID id = ImGui::GetCurrentWindow()->GetID(n_id);
    
    // copy from render annotation part in implot.cpp
    const ImVec2 size = ImGui::CalcTextSize(txt) +  ImPlot::GetStyle().AnnotationPadding * 2;
    
    if (offset->x == 0)     {pos.x -= size.x / 2;}
    else if (offset->x > 0) {pos.x += offset->x;}
    else                    {pos.x -= size.x - offset->x;}
    if (offset->y == 0)     {pos.y -= size.y / 2;}
    else if (offset->y > 0) {pos.y += offset->y;}
    else                    {pos.y -= size.y - offset->y;}
    //if (Clamp)
        //pos = ImPlot::ClampLabelPos(pos, size, plot.PlotRect.Min, plot.PlotRect.Max);
    ImRect rect(pos, pos+size);
    
    ImGui::KeepAliveID(id);
    bool hovered = false, held = false;
    bool clicked = ImGui::ButtonBehavior(rect,id,&hovered,&held);

    bool modified = false;
    if (held && ImGui::IsMouseDragging(0)) {
        ImVec2 mouse = ImGui::GetMousePos();
        *offset = mouse - pos0;     //fixme: mouse pos always point to conner
        modified = true;
    }
    
    if ((hovered || held)) 
        ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);

    ImGui::PopID();
    return modified;
}
static ImVec2 offset = {-10,-10};
ImVec4 color = ImVec4(0, 127, 0, 63);
DragAnnotation(0, 0,0, &offset, color , "test\nline2\nline3");

rorschach-py avatar Apr 02 '25 07:04 rorschach-py