ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
59.11k stars 10.09k forks source link

I want to pass a method function as the ImGuiInputResizeCallback #7390

Open RicardoDazzling opened 5 months ago

RicardoDazzling commented 5 months ago

Version/Branch of Dear ImGui:

Version 1.90.4, Branch: master

Back-ends:

imgui_impl_glfw.cpp + imgui_impl_opengl3.cpp

Compiler, OS:

Windows 10

Full config/build information:

Dear ImGui 1.90.5 WIP (19043)

sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20 define: __cplusplus=199711 define: _WIN32 define: _WIN64 define: _MSC_VER=1939 define: _MSVC_LANG=201402

io.BackendPlatformName: imgui_impl_glfw io.BackendRendererName: imgui_impl_opengl3 io.ConfigFlags: 0x00000003 NavEnableKeyboard NavEnableGamepad io.ConfigInputTextCursorBlink io.ConfigWindowsResizeFromEdges io.ConfigMemoryCompactTimer = 60.0 io.BackendFlags: 0x00000006 HasMouseCursors HasSetMousePos

io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64 io.DisplaySize: 1280.00,720.00 io.DisplayFramebufferScale: 1.00,1.00

style.WindowPadding: 8.00,8.00 style.WindowBorderSize: 1.00 style.FramePadding: 4.00,3.00 style.FrameRounding: 0.00 style.FrameBorderSize: 0.00 style.ItemSpacing: 8.00,4.00 style.ItemInnerSpacing: 4.00,4.00

Details:

My Issue/Question:

Hello!

My problem is that I want to use a input that don't have a max size, such is used in the demo file. But I see that in the demo file is used a static method, but I want to create a class with a object (str) that was updated when the resize callback was called, it object is defined inside the class, but when I try to create the Input, it don't accept the class method, only static methods. Its a example that my code:

class ResizableInputTextMultiline {
private:
    ImVector<char>* str;
public:
    ResizableInputTextMultiline(ImVector<char>* str);
    bool Draw(const char* label, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0);
    int ResizeCallback(ImGuiInputTextCallbackData* data);
};

bool ResizableInputTextMultiline::Draw(const char* label, const ImVec2& size, ImGuiInputTextFlags flags)
{
    IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
    return ImGui::InputTextMultiline(label, this->str->begin(), (size_t)this->str->size(), size, flags | ImGuiInputTextFlags_CallbackResize, this->ResizeCallback, (void*)this->str); //Error (active)  E0300   a pointer to a bound function may only be used to call the function
}

Can I solve this and give the class method as a resize callback argument?

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

// Here's some code anyone can copy and paste to reproduce your issue
ImGui::Begin("Example Bug");
MoreCodeToExplainMyIssue();
ImGui::End();
cfillion commented 5 months ago

data->UserData is the string in your snippet, so if you don't need to access other members of your object the above is fine. Just make ResizeCallback static or non-member. Otherwise:

ImGui::InputTextMultiline(label, str->begin(), str->size(), size, flags | ImGuiInputTextFlags_CallbackResize, [](ImGuiInputTextCallbackData *data) {
  return static_cast<ResizableInputTextMultiline *>(data->UserData)->ResizeCallback(data);
}, this);

Also have a look at misc/cpp/imgui_stdlib.h to not re-invent the wheel.

RicardoDazzling commented 5 months ago

The error from IDE solved, but I'm not understand at all. With your code, it will call the ResizeCallback from my object or I'll need to made it static before?

GamingMinds-DanielC commented 5 months ago

It is a normal member (non-static) in that short code snippet. The call passes the object's this-pointer as user data to the function and gives it a lambda (available since C++ 11) as a wrapper. That lambda then takes the user data, casts it back into the object pointer and calls the method on the object.