4

The call to ImGui::InputText() takes a char array which I need to initialise from a std::string and then transfer the contents back to the std::string. In it's simplest form:

char buf[255]{};
std::string s{"foo"};
void fn() {    
    strncpy( buf, s.c_str(), sizeof(buf)-1 );
    ImGui::InputText( "Text", buf, sizeof(buf) );
    s=buf;
}

However, it appears wasteful to have two buffers (buf and the buffer allocated within std::string) both doing much the same thing. Can I avoid the buf buffer and the copying to and from it by using just the std::string and a simple wrapper "X". I don't care about efficiency, I just want the simplest code at the call site. This code does work but is it safe and is there a better way?

class X {
public:
    X(std::string& s) : s_{s} { s.resize(len_); }
    ~X() { s_.resize(strlen(s_.c_str())); }
    operator char*(){ return s_.data(); }
    static constexpr auto len() { return len_-1; }
private:
    std::string& s_;
    static constexpr auto len_=255;
};

std::string s{"foo"};

void fn() {
    ImGui::InputText( "Text", X(s), X::len() );
}
273K
  • 29,503
  • 10
  • 41
  • 64

1 Answers1

11

If you want to use InputText() with std::string or any custom dynamic string type, see misc/cpp/imgui_stdlib.h and comments in imgui_demo.cpp.

misc/cpp/imgui_stdlib.h

namespace ImGui
{
    // ImGui::InputText() with std::string
    // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
    IMGUI_API bool  InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
    IMGUI_API bool  InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
    IMGUI_API bool  InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
}

Your first code

std::string s{"foo"};
void fn() {    
    ImGui::InputText( "Text", &s );
}

Reading manuals works wonders.

273K
  • 29,503
  • 10
  • 41
  • 64
  • 2
    imgui_demo.cpp several times has the comment: "To wire InputText() with std::string or any other custom string type, see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file". Again, reading manuals works wonders. – 273K Sep 03 '21 at 17:17
  • 7
    Do you have a link to this wonderful manual? (not only example code) – Lasersköld Sep 30 '22 at 09:44