Browse Source

Added InputTextWithHint() (#2400)

Squashed commit of the following:

commit 1970d84051d3878f8c1354d9c33c795d9c66143f
Author: Lucas Lazare <[email protected]>
Date:   Tue Mar 5 12:20:39 2019 -0500

    Removing sneaky tabulations #2 (why, editor T-T)

    I should update my settings, I guess

commit 219bdfcb7fbd17edf3048cb0edfde2532e4d6ac3
Author: Lucas Lazare <[email protected]>
Date:   Tue Mar 5 12:17:27 2019 -0500

    Removing useless check introduced in b0d172

commit 8afd7a2b459df0eb14eca88d832d2bebd1e684e6
Author: Lucas Lazare <[email protected]>
Date:   Tue Mar 5 11:49:24 2019 -0500

    Removing sneaky tabulations

commit 8e0490863126d63cafc782a6aac8707e44f95653
Author: Lucas Lazare <[email protected]>
Date:   Tue Mar 5 11:45:13 2019 -0500

    Moving InputTextHinted code to InputTextEx

commit b0d1723a2fb02d17ba15b9c1e679dedbbe3c17fd
Author: Lucas Lazare <[email protected]>
Date:   Tue Mar 5 00:23:02 2019 -0500

    C++11 to C++98

commit 9afeae399826015357962607b4aeb0109fde698e
Author: Lucas Lazare <[email protected]>
Date:   Mon Mar 4 23:43:28 2019 -0500

    Added InputTextHinted
Lucas Lazare 6 years ago
parent
commit
ab80ee6453
6 changed files with 62 additions and 11 deletions
  1. 1 0
      imgui.h
  2. 4 1
      imgui_demo.cpp
  3. 1 1
      imgui_internal.h
  4. 43 9
      imgui_widgets.cpp
  5. 12 0
      misc/cpp/imgui_stdlib.cpp
  6. 1 0
      misc/cpp/imgui_stdlib.h

+ 1 - 0
imgui.h

@@ -450,6 +450,7 @@ namespace ImGui
     // - Most of the ImGuiInputTextFlags flags are only useful for InputText() and not for InputFloatX, InputIntX, InputDouble etc.
     // - Most of the ImGuiInputTextFlags flags are only useful for InputText() and not for InputFloatX, InputIntX, InputDouble etc.
     IMGUI_API bool          InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
     IMGUI_API bool          InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
     IMGUI_API bool          InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
     IMGUI_API bool          InputTextMultiline(const char* label, char* buf, size_t buf_size, 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, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
     IMGUI_API bool          InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags flags = 0);
     IMGUI_API bool          InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags flags = 0);
     IMGUI_API bool          InputFloat2(const char* label, float v[2], const char* format = "%.3f", ImGuiInputTextFlags flags = 0);
     IMGUI_API bool          InputFloat2(const char* label, float v[2], const char* format = "%.3f", ImGuiInputTextFlags flags = 0);
     IMGUI_API bool          InputFloat3(const char* label, float v[3], const char* format = "%.3f", ImGuiInputTextFlags flags = 0);
     IMGUI_API bool          InputFloat3(const char* label, float v[3], const char* format = "%.3f", ImGuiInputTextFlags flags = 0);

+ 4 - 1
imgui_demo.cpp

@@ -481,10 +481,13 @@ static void ShowDemoWindowWidgets()
 
 
         {
         {
             static char str0[128] = "Hello, world!";
             static char str0[128] = "Hello, world!";
-            static int i0 = 123;
             ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0));
             ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0));
             ImGui::SameLine(); ShowHelpMarker("USER:\nHold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n\nPROGRAMMER:\nYou can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated in imgui_demo.cpp).");
             ImGui::SameLine(); ShowHelpMarker("USER:\nHold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n\nPROGRAMMER:\nYou can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated in imgui_demo.cpp).");
 
 
+            static char str1[128] = "";
+            ImGui::InputTextWithHint("input text (w/ hint)", "enter text here", str1, IM_ARRAYSIZE(str1));
+
+            static int i0 = 123;
             ImGui::InputInt("input int", &i0);
             ImGui::InputInt("input int", &i0);
             ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n  e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n");
             ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n  e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n");
 
 

+ 1 - 1
imgui_internal.h

@@ -1545,7 +1545,7 @@ namespace ImGui
     template<typename T, typename SIGNED_T>                     IMGUI_API T     RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
     template<typename T, typename SIGNED_T>                     IMGUI_API T     RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
 
 
     // InputText
     // InputText
-    IMGUI_API bool          InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
+    IMGUI_API bool          InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
     IMGUI_API bool          InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format);
     IMGUI_API bool          InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format);
 
 
     // Color
     // Color

+ 43 - 9
imgui_widgets.cpp

@@ -2692,7 +2692,7 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const c
     DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, data_ptr, format);
     DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, data_ptr, format);
     ImStrTrimBlanks(data_buf);
     ImStrTrimBlanks(data_buf);
     ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal);
     ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal);
-    bool value_changed = InputTextEx(label, data_buf, IM_ARRAYSIZE(data_buf), bb.GetSize(), flags);
+    bool value_changed = InputTextEx(label, NULL, data_buf, IM_ARRAYSIZE(data_buf), bb.GetSize(), flags);
     if (g.ScalarAsInputTextId == 0)
     if (g.ScalarAsInputTextId == 0)
     {
     {
         // First frame we started displaying the InputText widget, we expect it to take the active id.
         // First frame we started displaying the InputText widget, we expect it to take the active id.
@@ -2883,9 +2883,10 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f
 }
 }
 
 
 //-------------------------------------------------------------------------
 //-------------------------------------------------------------------------
-// [SECTION] Widgets: InputText, InputTextMultiline
+// [SECTION] Widgets: InputText, InputTextMultiline, InputTextWithHint
 //-------------------------------------------------------------------------
 //-------------------------------------------------------------------------
 // - InputText()
 // - InputText()
+// - InputTextWithHint()
 // - InputTextMultiline()
 // - InputTextMultiline()
 // - InputTextEx() [Internal]
 // - InputTextEx() [Internal]
 //-------------------------------------------------------------------------
 //-------------------------------------------------------------------------
@@ -2893,12 +2894,17 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f
 bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
 bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
 {
 {
     IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline()
     IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline()
-    return InputTextEx(label, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data);
+    return InputTextEx(label, NULL, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data);
 }
 }
 
 
 bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
 bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
 {
 {
-    return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data);
+    return InputTextEx(label, NULL, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data);
+}
+
+bool ImGui::InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
+{
+    return InputTextEx(label, hint, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data);
 }
 }
 
 
 static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end)
 static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end)
@@ -3193,7 +3199,7 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
 // - If you want to use ImGui::InputText() with std::string, see misc/cpp/imgui_stdlib.h
 // - If you want to use ImGui::InputText() with std::string, see misc/cpp/imgui_stdlib.h
 // (FIXME: Rather confusing and messy function, among the worse part of our codebase, expecting to rewrite a V2 at some point.. Partly because we are
 // (FIXME: Rather confusing and messy function, among the worse part of our codebase, expecting to rewrite a V2 at some point.. Partly because we are
 //  doing UTF8 > U16 > UTF8 conversions on the go to easily interface with stb_textedit. Ideally should stay in UTF-8 all the time. See https://github.com/nothings/stb/issues/188)
 //  doing UTF8 > U16 > UTF8 conversions on the go to easily interface with stb_textedit. Ideally should stay in UTF-8 all the time. See https://github.com/nothings/stb/issues/188)
-bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* callback_user_data)
+bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* callback_user_data)
 {
 {
     ImGuiWindow* window = GetCurrentWindow();
     ImGuiWindow* window = GetCurrentWindow();
     if (window->SkipItems)
     if (window->SkipItems)
@@ -3725,6 +3731,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
     const int buf_display_max_length = 2 * 1024 * 1024;
     const int buf_display_max_length = 2 * 1024 * 1024;
     const char* buf_display = NULL;
     const char* buf_display = NULL;
     const char* buf_display_end = NULL;
     const char* buf_display_end = NULL;
+    ImGuiCol text_color = ImGuiCol_COUNT;
 
 
     // Render text. We currently only render selection when the widget is active or while scrolling.
     // Render text. We currently only render selection when the widget is active or while scrolling.
     // FIXME: We could remove the '&& render_cursor' to keep rendering selection when inactive.
     // FIXME: We could remove the '&& render_cursor' to keep rendering selection when inactive.
@@ -3861,11 +3868,26 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
             }
             }
         }
         }
 
 
+        if (state->CurLenA != 0 || hint == NULL)
+        {
+            buf_display = (!is_readonly && state->TextAIsValid) ? state->TextA.Data : buf;
+            buf_display_end = buf_display + state->CurLenA;
+            text_color = ImGuiCol_Text;
+        }
+        else
+        {
+            buf_display = hint;
+            buf_display_end = hint + strlen(hint);
+            text_color = ImGuiCol_TextDisabled;
+        }
+
+
         // We test for 'buf_display_max_length' as a way to avoid some pathological cases (e.g. single-line 1 MB string) which would make ImDrawList crash.
         // We test for 'buf_display_max_length' as a way to avoid some pathological cases (e.g. single-line 1 MB string) which would make ImDrawList crash.
-        buf_display = (!is_readonly && state->TextAIsValid) ? state->TextA.Data : buf;
-        buf_display_end = buf_display + state->CurLenA;
         if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
         if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
-            draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
+        {
+            IM_ASSERT(text_color != ImGuiCol_COUNT);
+            draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, GetColorU32(text_color), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
+        }
 
 
         // Draw blinking cursor
         // Draw blinking cursor
         if (render_cursor)
         if (render_cursor)
@@ -3885,6 +3907,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
     else
     else
     {
     {
         // Render text only (no selection, no cursor)
         // Render text only (no selection, no cursor)
+        text_color = ImGuiCol_Text;
         buf_display = (g.ActiveId == id && !is_readonly && state->TextAIsValid) ? state->TextA.Data : buf;
         buf_display = (g.ActiveId == id && !is_readonly && state->TextAIsValid) ? state->TextA.Data : buf;
         if (is_multiline)
         if (is_multiline)
             text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width
             text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width
@@ -3892,8 +3915,19 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
             buf_display_end = buf_display + state->CurLenA;
             buf_display_end = buf_display + state->CurLenA;
         else
         else
             buf_display_end = buf_display + strlen(buf_display);
             buf_display_end = buf_display + strlen(buf_display);
+
+        if (buf_display_end == buf_display && hint != NULL)
+        {
+            buf_display = hint;
+            buf_display_end = buf_display + strlen(buf_display);
+            text_color = ImGuiCol_TextDisabled;
+        }
+
         if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
         if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
-            draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, GetColorU32(ImGuiCol_Text), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
+        {
+            IM_ASSERT(text_color != ImGuiCol_COUNT);
+            draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, GetColorU32(text_color), buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
+        }
     }
     }
 
 
     if (is_multiline)
     if (is_multiline)

+ 12 - 0
misc/cpp/imgui_stdlib.cpp

@@ -63,3 +63,15 @@ bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2
     cb_user_data.ChainCallbackUserData = user_data;
     cb_user_data.ChainCallbackUserData = user_data;
     return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data);
     return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data);
 }
 }
+
+bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
+{
+    IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
+    flags |= ImGuiInputTextFlags_CallbackResize;
+
+    InputTextCallback_UserData cb_user_data;
+    cb_user_data.Str = str;
+    cb_user_data.ChainCallback = callback;
+    cb_user_data.ChainCallbackUserData = user_data;
+    return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
+}

+ 1 - 0
misc/cpp/imgui_stdlib.h

@@ -19,4 +19,5 @@ namespace ImGui
     // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
     // 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  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  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);
 }
 }