diff --git a/imgui.h b/imgui.h index f0163f9f1..12f01f43f 100644 --- a/imgui.h +++ b/imgui.h @@ -3832,7 +3832,7 @@ struct ImFont // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. IMGUI_API ImFontBaked* GetFontBaked(float font_size, float density = -1.0f); // Get or create baked data for given size - IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL); // utf8 + IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** out_remaining = NULL); IMGUI_API const char* CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width); IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c, const ImVec4* cpu_fine_clip = NULL); IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 76d8474bf..e0d56612a 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -5458,7 +5458,7 @@ const char* ImFont::CalcWordWrapPosition(float size, const char* text, const cha return s; } -ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) +ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** out_remaining) { if (!text_end) text_end = text_begin + ImStrlen(text_begin); // FIXME-OPT: Need to avoid this. @@ -5536,8 +5536,8 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons if (line_width > 0 || text_size.y == 0.0f) text_size.y += line_height; - if (remaining) - *remaining = s; + if (out_remaining != NULL) + *out_remaining = s; return text_size; } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 5178d5448..3012404e0 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -135,7 +135,7 @@ static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1); // For InputTextEx() static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard = false); -static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); +static int InputTextCalcTextLenAndLineCount(ImGuiContext* ctx, const char* text_begin, const char** out_text_end); static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, const char* text_end, const char** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); //------------------------------------------------------------------------- @@ -3941,20 +3941,22 @@ bool ImGui::InputTextWithHint(const char* label, const char* hint, char* buf, si } // This is only used in the path where the multiline widget is inactive. -static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end) +static int InputTextCalcTextLenAndLineCount(ImGuiContext*, const char* text_begin, const char** out_text_end) { int line_count = 0; const char* s = text_begin; - while (true) { - const char* s_eol = strchr(s, '\n'); - line_count++; - if (s_eol == NULL) + while (true) { - s = s + ImStrlen(s); - break; + const char* s_eol = strchr(s, '\n'); + line_count++; + if (s_eol == NULL) + { + s = s + ImStrlen(s); + break; + } + s = s_eol + 1; } - s = s_eol + 1; } *out_text_end = s; return line_count; @@ -5259,7 +5261,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } // 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: This is one of the messiest piece of the whole codebase. if (render_cursor || render_selection) { IM_ASSERT(state != NULL); @@ -5285,14 +5287,17 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ const char* selmin_ptr = render_selection ? text_begin + ImMin(state->Stb->select_start, state->Stb->select_end) : NULL; // Count lines and find line number for cursor and selection ends + // FIXME: Switch to zero-based index to reduce confusion. int line_count = 1; if (is_multiline) { - for (const char* s = text_begin; (s = (const char*)ImMemchr(s, '\n', (size_t)(text_end - s))) != NULL; s++) { - if (cursor_line_no == -1 && s >= cursor_ptr) { cursor_line_no = line_count; } - if (selmin_line_no == -1 && s >= selmin_ptr) { selmin_line_no = line_count; } - line_count++; + for (const char* s = text_begin; (s = (const char*)ImMemchr(s, '\n', (size_t)(text_end - s))) != NULL; s++) + { + if (cursor_line_no == -1 && s >= cursor_ptr) { cursor_line_no = line_count; } + if (selmin_line_no == -1 && s >= selmin_ptr) { selmin_line_no = line_count; } + line_count++; + } } } if (cursor_line_no == -1) @@ -5372,7 +5377,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ else { ImVec2 rect_size = InputTextCalcTextSize(&g, p, text_selected_end, &p, NULL, true); - if (rect_size.x <= 0.0f) rect_size.x = IM_TRUNC(g.FontBaked->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines + if (rect_size.x <= 0.0f) + rect_size.x = IM_TRUNC(g.FontBaked->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn)); rect.ClipWith(clip_rect); if (rect.Overlaps(clip_rect)) @@ -5419,7 +5425,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ { // Render text only (no selection, no cursor) if (is_multiline) - text_size = ImVec2(inner_size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_display_end) * g.FontSize); // We don't need width + text_size = ImVec2(inner_size.x, InputTextCalcTextLenAndLineCount(&g, buf_display, &buf_display_end) * g.FontSize); // We don't need width else if (!is_displaying_hint && g.ActiveId == id) buf_display_end = buf_display + state->TextLen; else if (!is_displaying_hint)