Refactor: Moved Text functions from imgui.cpp to imgui_widgets.cpp (#2036)
This commit is contained in:
Родитель
52c115fb2c
Коммит
3eaa063984
238
imgui.cpp
238
imgui.cpp
|
@ -7871,177 +7871,6 @@ ImGuiStorage* ImGui::GetStateStorage()
|
||||||
return window->DC.StateStorage;
|
return window->DC.StateStorage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::TextV(const char* fmt, va_list args)
|
|
||||||
{
|
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
|
||||||
if (window->SkipItems)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
|
||||||
TextUnformatted(g.TempBuffer, text_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::Text(const char* fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
TextV(fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::TextColoredV(const ImVec4& col, const char* fmt, va_list args)
|
|
||||||
{
|
|
||||||
PushStyleColor(ImGuiCol_Text, col);
|
|
||||||
TextV(fmt, args);
|
|
||||||
PopStyleColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::TextColored(const ImVec4& col, const char* fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
TextColoredV(col, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::TextDisabledV(const char* fmt, va_list args)
|
|
||||||
{
|
|
||||||
PushStyleColor(ImGuiCol_Text, GImGui->Style.Colors[ImGuiCol_TextDisabled]);
|
|
||||||
TextV(fmt, args);
|
|
||||||
PopStyleColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::TextDisabled(const char* fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
TextDisabledV(fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::TextWrappedV(const char* fmt, va_list args)
|
|
||||||
{
|
|
||||||
bool need_wrap = (GImGui->CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position is one ia already set
|
|
||||||
if (need_wrap) PushTextWrapPos(0.0f);
|
|
||||||
TextV(fmt, args);
|
|
||||||
if (need_wrap) PopTextWrapPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::TextWrapped(const char* fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
TextWrappedV(fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::TextUnformatted(const char* text, const char* text_end)
|
|
||||||
{
|
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
|
||||||
if (window->SkipItems)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
IM_ASSERT(text != NULL);
|
|
||||||
const char* text_begin = text;
|
|
||||||
if (text_end == NULL)
|
|
||||||
text_end = text + strlen(text); // FIXME-OPT
|
|
||||||
|
|
||||||
const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrentLineTextBaseOffset);
|
|
||||||
const float wrap_pos_x = window->DC.TextWrapPos;
|
|
||||||
const bool wrap_enabled = wrap_pos_x >= 0.0f;
|
|
||||||
if (text_end - text > 2000 && !wrap_enabled)
|
|
||||||
{
|
|
||||||
// Long text!
|
|
||||||
// Perform manual coarse clipping to optimize for long multi-line text
|
|
||||||
// From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled.
|
|
||||||
// We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line.
|
|
||||||
const char* line = text;
|
|
||||||
const float line_height = GetTextLineHeight();
|
|
||||||
const ImRect clip_rect = window->ClipRect;
|
|
||||||
ImVec2 text_size(0,0);
|
|
||||||
|
|
||||||
if (text_pos.y <= clip_rect.Max.y)
|
|
||||||
{
|
|
||||||
ImVec2 pos = text_pos;
|
|
||||||
|
|
||||||
// Lines to skip (can't skip when logging text)
|
|
||||||
if (!g.LogEnabled)
|
|
||||||
{
|
|
||||||
int lines_skippable = (int)((clip_rect.Min.y - text_pos.y) / line_height);
|
|
||||||
if (lines_skippable > 0)
|
|
||||||
{
|
|
||||||
int lines_skipped = 0;
|
|
||||||
while (line < text_end && lines_skipped < lines_skippable)
|
|
||||||
{
|
|
||||||
const char* line_end = strchr(line, '\n');
|
|
||||||
if (!line_end)
|
|
||||||
line_end = text_end;
|
|
||||||
line = line_end + 1;
|
|
||||||
lines_skipped++;
|
|
||||||
}
|
|
||||||
pos.y += lines_skipped * line_height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lines to render
|
|
||||||
if (line < text_end)
|
|
||||||
{
|
|
||||||
ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height));
|
|
||||||
while (line < text_end)
|
|
||||||
{
|
|
||||||
const char* line_end = strchr(line, '\n');
|
|
||||||
if (IsClippedEx(line_rect, 0, false))
|
|
||||||
break;
|
|
||||||
|
|
||||||
const ImVec2 line_size = CalcTextSize(line, line_end, false);
|
|
||||||
text_size.x = ImMax(text_size.x, line_size.x);
|
|
||||||
RenderText(pos, line, line_end, false);
|
|
||||||
if (!line_end)
|
|
||||||
line_end = text_end;
|
|
||||||
line = line_end + 1;
|
|
||||||
line_rect.Min.y += line_height;
|
|
||||||
line_rect.Max.y += line_height;
|
|
||||||
pos.y += line_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count remaining lines
|
|
||||||
int lines_skipped = 0;
|
|
||||||
while (line < text_end)
|
|
||||||
{
|
|
||||||
const char* line_end = strchr(line, '\n');
|
|
||||||
if (!line_end)
|
|
||||||
line_end = text_end;
|
|
||||||
line = line_end + 1;
|
|
||||||
lines_skipped++;
|
|
||||||
}
|
|
||||||
pos.y += lines_skipped * line_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
text_size.y += (pos - text_pos).y;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImRect bb(text_pos, text_pos + text_size);
|
|
||||||
ItemSize(bb);
|
|
||||||
ItemAdd(bb, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Account of baseline offset
|
|
||||||
ImRect bb(text_pos, text_pos + text_size);
|
|
||||||
ItemSize(text_size);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::AlignTextToFramePadding()
|
void ImGui::AlignTextToFramePadding()
|
||||||
{
|
{
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
@ -8053,40 +7882,6 @@ void ImGui::AlignTextToFramePadding()
|
||||||
window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y);
|
window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a label+text combo aligned to other label+value widgets
|
|
||||||
void ImGui::LabelTextV(const char* label, const char* fmt, va_list args)
|
|
||||||
{
|
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
|
||||||
if (window->SkipItems)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
const ImGuiStyle& style = g.Style;
|
|
||||||
const float w = CalcItemWidth();
|
|
||||||
|
|
||||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
|
||||||
const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2));
|
|
||||||
const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size);
|
|
||||||
ItemSize(total_bb, style.FramePadding.y);
|
|
||||||
if (!ItemAdd(total_bb, 0))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Render
|
|
||||||
const char* value_text_begin = &g.TempBuffer[0];
|
|
||||||
const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
|
||||||
RenderTextClipped(value_bb.Min, value_bb.Max, value_text_begin, value_text_end, NULL, ImVec2(0.0f,0.5f));
|
|
||||||
if (label_size.x > 0.0f)
|
|
||||||
RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::LabelText(const char* label, const char* fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
LabelTextV(label, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags)
|
bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
@ -8979,39 +8774,6 @@ void ImGui::Bullet()
|
||||||
SameLine(0, style.FramePadding.x*2);
|
SameLine(0, style.FramePadding.x*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text with a little bullet aligned to the typical tree node.
|
|
||||||
void ImGui::BulletTextV(const char* fmt, va_list args)
|
|
||||||
{
|
|
||||||
ImGuiWindow* window = GetCurrentWindow();
|
|
||||||
if (window->SkipItems)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
const ImGuiStyle& style = g.Style;
|
|
||||||
|
|
||||||
const char* text_begin = g.TempBuffer;
|
|
||||||
const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
|
||||||
const ImVec2 label_size = CalcTextSize(text_begin, text_end, false);
|
|
||||||
const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it
|
|
||||||
const float line_height = ImMax(ImMin(window->DC.CurrentLineSize.y, g.FontSize + g.Style.FramePadding.y*2), g.FontSize);
|
|
||||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x*2) : 0.0f), ImMax(line_height, label_size.y))); // Empty text doesn't add padding
|
|
||||||
ItemSize(bb);
|
|
||||||
if (!ItemAdd(bb, 0))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Render
|
|
||||||
RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f));
|
|
||||||
RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2, text_base_offset_y), text_begin, text_end, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::BulletText(const char* fmt, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, fmt);
|
|
||||||
BulletTextV(fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format)
|
static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format)
|
||||||
{
|
{
|
||||||
if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32) // Signedness doesn't matter when pushing the argument
|
if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32) // Signedness doesn't matter when pushing the argument
|
||||||
|
|
|
@ -55,6 +55,243 @@
|
||||||
// - BulletTextV()
|
// - BulletTextV()
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ImGui::TextUnformatted(const char* text, const char* text_end)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
if (window->SkipItems)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
IM_ASSERT(text != NULL);
|
||||||
|
const char* text_begin = text;
|
||||||
|
if (text_end == NULL)
|
||||||
|
text_end = text + strlen(text); // FIXME-OPT
|
||||||
|
|
||||||
|
const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrentLineTextBaseOffset);
|
||||||
|
const float wrap_pos_x = window->DC.TextWrapPos;
|
||||||
|
const bool wrap_enabled = wrap_pos_x >= 0.0f;
|
||||||
|
if (text_end - text > 2000 && !wrap_enabled)
|
||||||
|
{
|
||||||
|
// Long text!
|
||||||
|
// Perform manual coarse clipping to optimize for long multi-line text
|
||||||
|
// From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled.
|
||||||
|
// We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line.
|
||||||
|
const char* line = text;
|
||||||
|
const float line_height = GetTextLineHeight();
|
||||||
|
const ImRect clip_rect = window->ClipRect;
|
||||||
|
ImVec2 text_size(0,0);
|
||||||
|
|
||||||
|
if (text_pos.y <= clip_rect.Max.y)
|
||||||
|
{
|
||||||
|
ImVec2 pos = text_pos;
|
||||||
|
|
||||||
|
// Lines to skip (can't skip when logging text)
|
||||||
|
if (!g.LogEnabled)
|
||||||
|
{
|
||||||
|
int lines_skippable = (int)((clip_rect.Min.y - text_pos.y) / line_height);
|
||||||
|
if (lines_skippable > 0)
|
||||||
|
{
|
||||||
|
int lines_skipped = 0;
|
||||||
|
while (line < text_end && lines_skipped < lines_skippable)
|
||||||
|
{
|
||||||
|
const char* line_end = strchr(line, '\n');
|
||||||
|
if (!line_end)
|
||||||
|
line_end = text_end;
|
||||||
|
line = line_end + 1;
|
||||||
|
lines_skipped++;
|
||||||
|
}
|
||||||
|
pos.y += lines_skipped * line_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lines to render
|
||||||
|
if (line < text_end)
|
||||||
|
{
|
||||||
|
ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height));
|
||||||
|
while (line < text_end)
|
||||||
|
{
|
||||||
|
const char* line_end = strchr(line, '\n');
|
||||||
|
if (IsClippedEx(line_rect, 0, false))
|
||||||
|
break;
|
||||||
|
|
||||||
|
const ImVec2 line_size = CalcTextSize(line, line_end, false);
|
||||||
|
text_size.x = ImMax(text_size.x, line_size.x);
|
||||||
|
RenderText(pos, line, line_end, false);
|
||||||
|
if (!line_end)
|
||||||
|
line_end = text_end;
|
||||||
|
line = line_end + 1;
|
||||||
|
line_rect.Min.y += line_height;
|
||||||
|
line_rect.Max.y += line_height;
|
||||||
|
pos.y += line_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count remaining lines
|
||||||
|
int lines_skipped = 0;
|
||||||
|
while (line < text_end)
|
||||||
|
{
|
||||||
|
const char* line_end = strchr(line, '\n');
|
||||||
|
if (!line_end)
|
||||||
|
line_end = text_end;
|
||||||
|
line = line_end + 1;
|
||||||
|
lines_skipped++;
|
||||||
|
}
|
||||||
|
pos.y += lines_skipped * line_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
text_size.y += (pos - text_pos).y;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImRect bb(text_pos, text_pos + text_size);
|
||||||
|
ItemSize(bb);
|
||||||
|
ItemAdd(bb, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Account of baseline offset
|
||||||
|
ImRect bb(text_pos, text_pos + text_size);
|
||||||
|
ItemSize(text_size);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::Text(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
TextV(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::TextV(const char* fmt, va_list args)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
if (window->SkipItems)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||||
|
TextUnformatted(g.TempBuffer, text_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::TextColored(const ImVec4& col, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
TextColoredV(col, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::TextColoredV(const ImVec4& col, const char* fmt, va_list args)
|
||||||
|
{
|
||||||
|
PushStyleColor(ImGuiCol_Text, col);
|
||||||
|
TextV(fmt, args);
|
||||||
|
PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::TextDisabled(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
TextDisabledV(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::TextDisabledV(const char* fmt, va_list args)
|
||||||
|
{
|
||||||
|
PushStyleColor(ImGuiCol_Text, GImGui->Style.Colors[ImGuiCol_TextDisabled]);
|
||||||
|
TextV(fmt, args);
|
||||||
|
PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::TextWrapped(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
TextWrappedV(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::TextWrappedV(const char* fmt, va_list args)
|
||||||
|
{
|
||||||
|
bool need_wrap = (GImGui->CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position is one ia already set
|
||||||
|
if (need_wrap) PushTextWrapPos(0.0f);
|
||||||
|
TextV(fmt, args);
|
||||||
|
if (need_wrap) PopTextWrapPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::LabelText(const char* label, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
LabelTextV(label, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a label+text combo aligned to other label+value widgets
|
||||||
|
void ImGui::LabelTextV(const char* label, const char* fmt, va_list args)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
if (window->SkipItems)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
const ImGuiStyle& style = g.Style;
|
||||||
|
const float w = CalcItemWidth();
|
||||||
|
|
||||||
|
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||||
|
const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2));
|
||||||
|
const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size);
|
||||||
|
ItemSize(total_bb, style.FramePadding.y);
|
||||||
|
if (!ItemAdd(total_bb, 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Render
|
||||||
|
const char* value_text_begin = &g.TempBuffer[0];
|
||||||
|
const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||||
|
RenderTextClipped(value_bb.Min, value_bb.Max, value_text_begin, value_text_end, NULL, ImVec2(0.0f,0.5f));
|
||||||
|
if (label_size.x > 0.0f)
|
||||||
|
RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::BulletText(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
BulletTextV(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text with a little bullet aligned to the typical tree node.
|
||||||
|
void ImGui::BulletTextV(const char* fmt, va_list args)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
|
if (window->SkipItems)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
const ImGuiStyle& style = g.Style;
|
||||||
|
|
||||||
|
const char* text_begin = g.TempBuffer;
|
||||||
|
const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
|
||||||
|
const ImVec2 label_size = CalcTextSize(text_begin, text_end, false);
|
||||||
|
const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it
|
||||||
|
const float line_height = ImMax(ImMin(window->DC.CurrentLineSize.y, g.FontSize + g.Style.FramePadding.y*2), g.FontSize);
|
||||||
|
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x*2) : 0.0f), ImMax(line_height, label_size.y))); // Empty text doesn't add padding
|
||||||
|
ItemSize(bb);
|
||||||
|
if (!ItemAdd(bb, 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Render
|
||||||
|
RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f));
|
||||||
|
RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2, text_base_offset_y), text_begin, text_end, false);
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// WIDGETS: Main
|
// WIDGETS: Main
|
||||||
|
|
Загрузка…
Ссылка в новой задаче