Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Flix01/cb292384c82c4196f0d1dfc327bfba9c to your computer and use it in GitHub Desktop.
Save Flix01/cb292384c82c4196f0d1dfc327bfba9c to your computer and use it in GitHub Desktop.
Experimental attempt to create an ImGui::InputTextMultiline(...) for std::strings
// EXPERIMENTAL (ALMOST UNTESTED) InputTextMultiline(...) for std::strings.
// USE IT AT YOUR OWN RISK!
// Example usage:
/*
static std::string text = "Dear ImGui lacks InputTextMultiline(...) for std::string.";
static bool isTextBoxActive = false; // A better implementation should remove this
ImGui::InputTextMultiline("###ADummyLabelForMe",text,isTextBoxActive);
*/
// .h file
#include <imgui.h>
#include <string>
namespace ImGui {
IMGUI_API bool InputTextMultiline(const char* label,std::string& text,bool& staticItemActiveInOut, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
}
// .cpp file (needs imgui_internal.h)
namespace ImGui {
inline static void StdStringNonStdResize(std::string& s,int size) {
IM_ASSERT(size>=0);
const int oldLength = s.length();
if (size<oldLength) s = s.substr(0,size);
else if (size>oldLength) for (int i=0,icnt=size-oldLength;i<icnt;i++) s+='\0';
}
// Ideally we should remove "staticItemActiveInOut" and find a way to query the active state BEFORE calling the default InputTextMultiline(...) version
// Also I'm not sure this works well with Undo/Redo
// And I've only tested it in a single instance
bool InputTextMultiline(const char* label,std::string& text,bool& staticItemActiveInOut, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) {
bool rv = false;
const bool is_editable = (flags & ImGuiInputTextFlags_ReadOnly) == 0;
if (staticItemActiveInOutForID && is_editable) {
const ImGuiIO& io = ImGui::GetIO();
ImGuiTextEditState &edit_state = ImGui::GetCurrentContext()->InputTextState; // Hope this always points to the active InputText...
const char* clipText = (io.KeyMap[ImGuiKey_V] && io.KeyCtrl) ? ImGui::GetClipboardText() : "";
const size_t clipSize = strlen(clipText);
size_t sizeToAdd = clipSize+((io.InputCharacters[0] && (!(io.KeyCtrl && !io.KeyAlt)))?(5*IM_ARRAYSIZE(io.InputCharacters)):0);
if (IsKeyPressedMap(ImGuiKey_Enter) || IsKeyPressedMap(ImGuiKey_Tab)) sizeToAdd+=5;
size_t cnt = 0;
if (sizeToAdd>0) {
// Note that this happens only on a few frames
sizeToAdd+=1; // Trailing '\0'
const size_t oldTextLen = (size_t)text.length();
const size_t newTextLen = oldTextLen+sizeToAdd;
StdStringNonStdResize(text,newTextLen); // See its code: it sets text[i]='\0' too
edit_state.Text.resize(text.length()+1);
edit_state.InitialText.resize(text.length()+1);
rv = ImGui::InputTextMultiline(label,&text[0],newTextLen,flags,callback,user_data);
// Remove all trailing '\0's and resize all strings back to save memory (a bit slow)
for (int i=(int)text.length()-1;i>=0;i--) {
if (text[i]!='\0') break;
++cnt;
}
StdStringNonStdResize(text,text.length()-cnt);
staticItemActiveInOutForID = ImGui::IsItemActive();
if (staticItemActiveInOutForID) // Otherwise maybe edit_state points to something else
{
//Allows the textbox to expand while active.
edit_state.Text.resize(text.length()+1);
edit_state.InitialText.resize(text.length()+1);
}
}
else {
rv = ImGui::InputTextMultiline(label,&text[0],text.length(),flags,callback,user_data);
staticItemActiveInOutForID = ImGui::IsItemActive();
}
// Dbg only: (to remove)
if (ImGui::IsItemHovered()) ImGui::SetTooltip("text.length():%d (%s) cnt:%d sizeToAdd:%d\n",text.length(),staticItemActiveInOutForID?"active":"inactive",cnt,(int)sizeToAdd);
}
else {
rv = ImGui::InputTextMultiline(label,&text[0],text.length(),flags,callback,user_data);
staticItemActiveInOutForID = ImGui::IsItemActive();
}
return rv;
}
} // namespace ImGui
@Flix01
Copy link
Author

Flix01 commented Dec 12, 2017

Intended for ImGui version 1.52.

Please see: ocornut/imgui#1008 and ocornut/imgui#1443

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment