Moving InputTextHinted code to InputTextEx

This commit is contained in:
Lucas Lazare 2019-03-05 11:45:13 -05:00
parent b0d1723a2f
commit 8e04908631
4 changed files with 43 additions and 53 deletions

View File

@ -450,7 +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 InputTextHinted(const char* label, const char* hint, char* buf, size_t buf_size, bool* is_user_data, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputTextHinted(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);
@ -758,8 +758,7 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input) ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input)
ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this)
// [Internal] // [Internal]
ImGuiInputTextFlags_Multiline = 1 << 20, // For internal use by InputTextMultiline() ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline()
ImGuiInputTextFlags_ShowTextAsDisabled = 1 << 21 // For internal use by InputTextHinted (text within the input text field is showed with the ImGuiCol_TextDisabled color)
}; };
// Flags for ImGui::TreeNodeEx(), ImGui::CollapsingHeader*() // Flags for ImGui::TreeNodeEx(), ImGui::CollapsingHeader*()

View File

@ -485,8 +485,7 @@ static void ShowDemoWindowWidgets()
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] = ""; static char str1[128] = "";
static bool is_user_data = false; ImGui::InputTextHinted("hinted input text", "type text here", str1, IM_ARRAYSIZE(str1));
ImGui::InputTextHinted("hinted input text", "type text here", str1, IM_ARRAYSIZE(str1), &is_user_data);
static int i0 = 123; static int i0 = 123;
ImGui::InputInt("input int", &i0); ImGui::InputInt("input int", &i0);

View File

@ -1527,7 +1527,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

View File

@ -2691,7 +2691,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.
@ -2893,47 +2893,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::InputTextHinted(const char* label, const char* hint, char* buf, size_t buf_size, bool* is_user_data, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) bool ImGui::InputTextHinted(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
{ {
ImGuiWindow* window = GetCurrentWindow(); return InputTextEx(label, hint, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data);
const ImGuiID id = window->GetID(label);
if (id != GetActiveID()) {
if (buf_size > 0 && !*buf) {
unsigned int len = (unsigned int)strlen(hint) + 1;
IM_ASSERT(buf_size >= len);
memcpy(buf, hint, len);
*is_user_data = false;
}
} else {
if (!*is_user_data) {
ImGuiInputTextState& state = GImGui->InputTextState;
state.TextW[0] = '\0';
state.CurLenW = 0;
state.TextA[0] = '\0';
state.CurLenA = 0;
state.InitialTextA[0] = '\0';
state.Stb.cursor = 0;
*is_user_data = true;
}
}
if (!*is_user_data) {
ImGuiInputTextFlags CallbackFlags = ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackAlways | ImGuiInputTextFlags_CallbackCharFilter;
InputTextEx(label, buf, (int) buf_size, ImVec2(0, 0), (flags | ImGuiInputTextFlags_ShowTextAsDisabled) & ~CallbackFlags, NULL, NULL);
return false;
} else {
return InputTextEx(label, 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)
@ -3228,7 +3198,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)
@ -3754,6 +3724,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.
@ -3892,11 +3863,24 @@ 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; if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
buf_display_end = buf_display + state->CurLenA; {
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) { IM_ASSERT(text_color != ImGuiCol_COUNT);
ImGuiCol text_color = flags & ImGuiInputTextFlags_ShowTextAsDisabled ? ImGuiCol_TextDisabled : ImGuiCol_Text;
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_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);
} }
@ -3907,10 +3891,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
bool cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (state->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f; bool cursor_is_visible = (!g.IO.ConfigInputTextCursorBlink) || (state->CursorAnim <= 0.0f) || ImFmod(state->CursorAnim, 1.20f) <= 0.80f;
ImVec2 cursor_screen_pos = draw_pos + cursor_offset - draw_scroll; ImVec2 cursor_screen_pos = draw_pos + cursor_offset - draw_scroll;
ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f); ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f);
if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) { if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect))
ImGuiCol text_color = flags & ImGuiInputTextFlags_ShowTextAsDisabled ? ImGuiCol_TextDisabled : ImGuiCol_Text; draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_Text));
draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(text_color));
}
// Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.)
if (!is_readonly) if (!is_readonly)
@ -3920,15 +3902,25 @@ 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 && buf_display)
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
else if (g.ActiveId == id) else if (g.ActiveId == id)
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 (is_multiline || (buf_display_end - buf_display) < buf_display_max_length) {
ImGuiCol text_color = flags & ImGuiInputTextFlags_ShowTextAsDisabled ? ImGuiCol_TextDisabled : ImGuiCol_Text; 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)
{
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); 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);
} }
} }