mirror of
https://github.com/Drezil/imgui.git
synced 2025-09-19 17:43:15 +02:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
bbed1c4bbb | |||
2d3aa2e52c | |||
8bcb0cda73 | |||
d07649b7b4 |
24
imgui.cpp
24
imgui.cpp
@ -3296,7 +3296,7 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width)
|
||||
void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width, float text_alignment)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
@ -3306,7 +3306,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end
|
||||
|
||||
if (text != text_end)
|
||||
{
|
||||
window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width);
|
||||
window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width, text_alignment);
|
||||
if (g.LogEnabled)
|
||||
LogRenderedText(&pos, text, text_end);
|
||||
}
|
||||
@ -3337,11 +3337,11 @@ void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, co
|
||||
if (need_clipping)
|
||||
{
|
||||
ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y);
|
||||
draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect);
|
||||
draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, 0.0f, &fine_clip_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL);
|
||||
draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, 0.0f, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3832,6 +3832,7 @@ void ImGui::GcCompactTransientWindowBuffers(ImGuiWindow* window)
|
||||
window->DC.ChildWindows.clear();
|
||||
window->DC.ItemWidthStack.clear();
|
||||
window->DC.TextWrapPosStack.clear();
|
||||
window->DC.TextAlignmentStack.clear();
|
||||
}
|
||||
|
||||
void ImGui::GcAwakeTransientWindowBuffers(ImGuiWindow* window)
|
||||
@ -6784,6 +6785,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->DC.TextWrapPos = -1.0f; // disabled
|
||||
window->DC.ItemWidthStack.resize(0);
|
||||
window->DC.TextWrapPosStack.resize(0);
|
||||
window->DC.TextAlignmentStack.resize(0);
|
||||
|
||||
if (window->AutoFitFramesX > 0)
|
||||
window->AutoFitFramesX--;
|
||||
@ -7234,6 +7236,20 @@ void ImGui::PopTextWrapPos()
|
||||
window->DC.TextWrapPosStack.pop_back();
|
||||
}
|
||||
|
||||
void ImGui::PushTextAlignment(float alignment)
|
||||
{
|
||||
ImGuiWindow *window = GetCurrentWindow();
|
||||
window->DC.TextAlignmentStack.push_back(window->DC.TextAlignment);
|
||||
window->DC.TextAlignment = alignment;
|
||||
}
|
||||
|
||||
void ImGui::PopTextAlignment()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
window->DC.TextAlignment = window->DC.TextAlignmentStack.back();
|
||||
window->DC.TextAlignmentStack.pop_back();
|
||||
}
|
||||
|
||||
static ImGuiWindow* GetCombinedRootWindow(ImGuiWindow* window, bool popup_hierarchy)
|
||||
{
|
||||
ImGuiWindow* last_window = NULL;
|
||||
|
8
imgui.h
8
imgui.h
@ -424,6 +424,8 @@ namespace ImGui
|
||||
IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position. NOT necessarily the width of last item unlike most 'Item' functions.
|
||||
IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // push word-wrapping position for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space
|
||||
IMGUI_API void PopTextWrapPos();
|
||||
IMGUI_API void PushTextAlignment(float alignment = 0.0f); // push text alignment position for TextWrapped*() commands. 0.0f: no alignment; 1.0f: align right; 0.5f: align center
|
||||
IMGUI_API void PopTextAlignment();
|
||||
|
||||
// Style read access
|
||||
// - Use the ShowStyleEditor() function to interactively see/edit the colors.
|
||||
@ -2676,7 +2678,7 @@ struct ImDrawList
|
||||
IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f);
|
||||
IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments);
|
||||
IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL);
|
||||
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
|
||||
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, float text_align = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
|
||||
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness);
|
||||
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col);
|
||||
IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points)
|
||||
@ -3011,9 +3013,9 @@ 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 ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8
|
||||
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
|
||||
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width, float *line_width = NULL) const;
|
||||
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c) const;
|
||||
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) const;
|
||||
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, float text_align = 0.0f, bool cpu_fine_clip = false) const;
|
||||
|
||||
// [Internal] Don't use!
|
||||
IMGUI_API void BuildLookupTable();
|
||||
|
@ -1026,13 +1026,35 @@ static void ShowDemoWindowWidgets()
|
||||
if (ImGui::TreeNode("Word Wrapping"))
|
||||
{
|
||||
// Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility.
|
||||
ImGui::TextUnformatted("[Left Align]");
|
||||
ImGui::TextWrapped(
|
||||
"This text should automatically wrap on the edge of the window. The current implementation "
|
||||
"for text wrapping follows simple rules suitable for English and possibly other languages.");
|
||||
ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255));
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::PushTextAlignment(0.5f);
|
||||
ImGui::TextUnformatted("[Center Align]");
|
||||
ImGui::TextWrapped(
|
||||
"This text should automatically wrap on the edge of the window. The current implementation "
|
||||
"for text wrapping follows simple rules suitable for English and possibly other languages.");
|
||||
ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255));
|
||||
ImGui::PopTextAlignment();
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::PushTextAlignment(1.0f);
|
||||
ImGui::TextUnformatted("[Right Align]");
|
||||
ImGui::TextWrapped(
|
||||
"This text should automatically wrap on the edge of the window. The current implementation "
|
||||
"for text wrapping follows simple rules suitable for English and possibly other languages.");
|
||||
ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255));
|
||||
ImGui::PopTextAlignment();
|
||||
ImGui::Spacing();
|
||||
|
||||
static float wrap_width = 200.0f;
|
||||
ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f");
|
||||
static float text_align = 0.0f;
|
||||
ImGui::SliderFloat("Text alignment", &text_align, 0.0f, 1.0f, "%.2f");
|
||||
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
for (int n = 0; n < 2; n++)
|
||||
@ -1042,16 +1064,44 @@ static void ShowDemoWindowWidgets()
|
||||
ImVec2 marker_min = ImVec2(pos.x + wrap_width, pos.y);
|
||||
ImVec2 marker_max = ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight());
|
||||
ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width);
|
||||
ImGui::PushTextAlignment(text_align);
|
||||
if (n == 0)
|
||||
ImGui::Text("The lazy dog is a good dog. This paragraph should fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width);
|
||||
else
|
||||
ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh");
|
||||
ImGui::Text(
|
||||
"The lazy dog is a good dog. This paragraph should fit within %.0f pixels. "
|
||||
"Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width);
|
||||
else {
|
||||
ImGui::TextWrapped("aaaaaaaa bbbbbbbb, c\n\ttest\r\n cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh");
|
||||
}
|
||||
ImGui::PopTextAlignment();
|
||||
|
||||
// Draw actual text bounding box, following by marker of our expected limit (should not overlap!)
|
||||
draw_list->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255));
|
||||
draw_list->AddRectFilled(marker_min, marker_max, IM_COL32(255, 0, 255, 255));
|
||||
ImGui::PopTextWrapPos();
|
||||
}
|
||||
ImGui::Spacing();
|
||||
|
||||
ImGui::TextUnformatted("[Typesetting Example]");
|
||||
ImGui::SameLine(); HelpMarker("Use SetCursorPos and TextWrapPos to horizontally align text blocks.");
|
||||
ImGui::PushTextAlignment(text_align);
|
||||
|
||||
float max_wrap_width = ImGui::GetContentRegionAvail().x;
|
||||
if (wrap_width < max_wrap_width) {
|
||||
ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPosX() + fabs(max_wrap_width - wrap_width) * text_align, ImGui::GetCursorPosY()));
|
||||
}
|
||||
|
||||
ImGui::PushTextWrapPos(ImGui::GetCursorPosX() + wrap_width);
|
||||
ImGui::Text(
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt "
|
||||
"ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation "
|
||||
"ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in "
|
||||
"reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur "
|
||||
"sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id "
|
||||
"est laborum.");
|
||||
ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255));
|
||||
ImGui::PopTextWrapPos();
|
||||
|
||||
ImGui::PopTextAlignment();
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@ -3417,7 +3467,7 @@ static void ShowDemoWindowLayout()
|
||||
case 2:
|
||||
ImVec4 clip_rect(p0.x, p0.y, p1.x, p1.y); // AddText() takes a ImVec4* here so let's convert.
|
||||
draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255));
|
||||
draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(), text_pos, IM_COL32_WHITE, text_str, NULL, 0.0f, &clip_rect);
|
||||
draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(), text_pos, IM_COL32_WHITE, text_str, NULL, 0.0f, 0.0f, &clip_rect);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1569,7 +1569,7 @@ void ImDrawList::AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const Im
|
||||
PathStroke(col, 0, thickness);
|
||||
}
|
||||
|
||||
void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
|
||||
void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, float text_align, const ImVec4* cpu_fine_clip_rect)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
@ -1595,7 +1595,7 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
|
||||
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
|
||||
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
|
||||
}
|
||||
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL);
|
||||
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, text_align, cpu_fine_clip_rect != NULL);
|
||||
}
|
||||
|
||||
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
|
||||
@ -3418,7 +3418,7 @@ static inline const char* CalcWordWrapNextLineStartA(const char* text, const cha
|
||||
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
|
||||
// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end.
|
||||
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
|
||||
const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const
|
||||
const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width, float *line_length) const
|
||||
{
|
||||
// For references, possible wrap point marked with ^
|
||||
// "aaa bbb, ccc,ddd. eee fff. ggg!"
|
||||
@ -3434,6 +3434,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||
float line_width = 0.0f;
|
||||
float word_width = 0.0f;
|
||||
float blank_width = 0.0f;
|
||||
float last_blank_width = 0.0f;
|
||||
wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters
|
||||
|
||||
const char* word_end = text;
|
||||
@ -3455,10 +3456,9 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
line_width = word_width = blank_width = 0.0f;
|
||||
inside_word = true;
|
||||
s = next_s;
|
||||
continue;
|
||||
line_width += word_width;
|
||||
word_width = last_blank_width = 0.0f;
|
||||
break;
|
||||
}
|
||||
if (c == '\r')
|
||||
{
|
||||
@ -3472,7 +3472,6 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||
{
|
||||
if (inside_word)
|
||||
{
|
||||
line_width += blank_width;
|
||||
blank_width = 0.0f;
|
||||
word_end = s;
|
||||
}
|
||||
@ -3481,7 +3480,6 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||
}
|
||||
else
|
||||
{
|
||||
word_width += char_width;
|
||||
if (inside_word)
|
||||
{
|
||||
word_end = next_s;
|
||||
@ -3490,8 +3488,10 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||
{
|
||||
prev_word_end = word_end;
|
||||
line_width += word_width + blank_width;
|
||||
last_blank_width = blank_width;
|
||||
word_width = blank_width = 0.0f;
|
||||
}
|
||||
word_width += char_width;
|
||||
|
||||
// Allow wrapping after punctuation.
|
||||
inside_word = (c != '.' && c != ',' && c != ';' && c != '!' && c != '?' && c != '\"');
|
||||
@ -3500,9 +3500,12 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||
// We ignore blank width at the end of the line (they can be skipped)
|
||||
if (line_width + word_width > wrap_width)
|
||||
{
|
||||
// Words that cannot possibly fit within an entire line will be cut anywhere.
|
||||
if (word_width < wrap_width)
|
||||
s = prev_word_end ? prev_word_end : word_end;
|
||||
// Words that cannot possibly fit within an entire line will be cut before
|
||||
// the character that pushed them over the limit.
|
||||
else
|
||||
line_width += word_width - char_width;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3513,6 +3516,14 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||
// +1 may not be a character start point in UTF-8 but it's ok because caller loops use (text >= word_wrap_eol).
|
||||
if (s == text && text < text_end)
|
||||
return s + 1;
|
||||
if (s == text_end)
|
||||
line_width += word_width;
|
||||
else
|
||||
line_width -= last_blank_width;
|
||||
|
||||
if (line_length)
|
||||
*line_length = line_width * scale;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -3526,6 +3537,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
||||
|
||||
ImVec2 text_size = ImVec2(0, 0);
|
||||
float line_width = 0.0f;
|
||||
float wrapped_line_width = 0.0f;
|
||||
|
||||
const bool word_wrap_enabled = (wrap_width > 0.0f);
|
||||
const char* word_wrap_eol = NULL;
|
||||
@ -3537,12 +3549,15 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
||||
{
|
||||
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
||||
if (!word_wrap_eol)
|
||||
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width);
|
||||
{
|
||||
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width, &wrapped_line_width);
|
||||
if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
|
||||
word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
|
||||
}
|
||||
|
||||
if (s >= word_wrap_eol)
|
||||
{
|
||||
if (text_size.x < line_width)
|
||||
text_size.x = line_width;
|
||||
text_size.x = ImMax(text_size.x, wrapped_line_width);
|
||||
text_size.y += line_height;
|
||||
line_width = 0.0f;
|
||||
word_wrap_eol = NULL;
|
||||
@ -3610,7 +3625,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
}
|
||||
|
||||
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
||||
void ImFont::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, bool cpu_fine_clip) const
|
||||
void ImFont::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, float text_align, bool cpu_fine_clip) const
|
||||
{
|
||||
if (!text_end)
|
||||
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||
@ -3676,13 +3691,21 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
const ImU32 col_untinted = col | ~IM_COL32_A_MASK;
|
||||
const char* word_wrap_eol = NULL;
|
||||
|
||||
float line_width = 0.0f;
|
||||
|
||||
while (s < text_end)
|
||||
{
|
||||
if (word_wrap_enabled)
|
||||
{
|
||||
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
||||
if (!word_wrap_eol)
|
||||
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - start_x));
|
||||
{
|
||||
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width, &line_width);
|
||||
if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
|
||||
word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
|
||||
else
|
||||
x = pos.x + IM_ROUND((wrap_width - line_width) * text_align);
|
||||
}
|
||||
|
||||
if (s >= word_wrap_eol)
|
||||
{
|
||||
@ -3703,7 +3726,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
|
||||
if (c < 32)
|
||||
{
|
||||
if (c == '\n')
|
||||
if (c == '\n') // if word-wrap is disabled, need to break lines manually
|
||||
{
|
||||
x = start_x;
|
||||
y += line_height;
|
||||
|
@ -2296,8 +2296,11 @@ struct IMGUI_API ImGuiWindowTempData
|
||||
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
|
||||
float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window).
|
||||
float TextWrapPos; // Current text wrap pos.
|
||||
float TextAlignment; // Current text alignment.
|
||||
ImVector<float> ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth)
|
||||
ImVector<float> TextWrapPosStack; // Store text wrap pos to restore (attention: .back() is not == TextWrapPos)
|
||||
ImVector<float> TextAlignmentStack; // Store text alignment to restore (attention: .back() is not == TextAlignment)
|
||||
ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
|
||||
};
|
||||
|
||||
// Storage for one window
|
||||
@ -3147,7 +3150,7 @@ namespace ImGui
|
||||
// AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT.
|
||||
// NB: All position are in absolute pixels coordinates (we are never using window coordinates internally)
|
||||
IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);
|
||||
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
|
||||
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width, float text_alignment);
|
||||
IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL);
|
||||
IMGUI_API void RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL);
|
||||
IMGUI_API void RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end, const ImVec2* text_size_if_known);
|
||||
|
@ -160,6 +160,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
text_end = text + strlen(text); // FIXME-OPT
|
||||
|
||||
const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
const float text_alignment = window->DC.TextAlignment;
|
||||
const float wrap_pos_x = window->DC.TextWrapPos;
|
||||
const bool wrap_enabled = (wrap_pos_x >= 0.0f);
|
||||
if (text_end - text <= 2000 || wrap_enabled)
|
||||
@ -167,14 +168,17 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
// Common case
|
||||
const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f;
|
||||
const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width);
|
||||
const float text_offset = wrap_enabled ? IM_ROUND((wrap_width - text_size.x) * text_alignment) : 0.0f;
|
||||
const ImVec2 final_pos = ImVec2(text_pos.x + text_offset, text_pos.y);
|
||||
|
||||
ImRect bb(text_pos, text_pos + text_size);
|
||||
ImRect bb(final_pos, final_pos + text_size);
|
||||
ItemSize(text_size, 0.0f);
|
||||
if (!ItemAdd(bb, 0))
|
||||
return;
|
||||
|
||||
// Render (we don't hide text after ## in this end-user function)
|
||||
RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width);
|
||||
// we use text_size.x here as wrap_width to correctly handle text alignment
|
||||
RenderTextWrapped(bb.Min, text_begin, text_end, text_size.x, text_alignment);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4933,7 +4937,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
|
||||
{
|
||||
ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
|
||||
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
|
||||
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos - draw_scroll, col, buf_display, buf_display_end, 0.0f, 0.0f, is_multiline ? NULL : &clip_rect);
|
||||
}
|
||||
|
||||
// Draw blinking cursor
|
||||
@ -4968,7 +4972,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (is_multiline || (buf_display_end - buf_display) < buf_display_max_length)
|
||||
{
|
||||
ImU32 col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
|
||||
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, col, buf_display, buf_display_end, 0.0f, is_multiline ? NULL : &clip_rect);
|
||||
draw_window->DrawList->AddText(g.Font, g.FontSize, draw_pos, col, buf_display, buf_display_end, 0.0f, 0.0f, is_multiline ? NULL : &clip_rect);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user