mirror of
https://github.com/ocornut/imgui.git
synced 2025-09-26 21:28:31 +00:00
ImStrv: Step 2 - change ImStrv typedef to struct, perform all other logic conversion.
Squashed commits (initially a commit from rokups + many rework by ocornut. keeping them separate commits made rebasing unnecessarily tricking so merged from 2024/02) ImStrv: many fixes (see details), added imconfig class extension example, added natvis description. ImStrv: rework toward ensuring End is always set to constant can be compile time calculated ImStrv: using length(), fix ambiguous empty() function, fix altered behaviors, removed unused operators. ImStrv: various tweaks and fixes. removed ImGuiTextRange from ImGuiTextFilter, fix test engine hooks, removed constructor only used twice.
This commit is contained in:
@@ -156,30 +156,24 @@ static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin,
|
||||
// - BulletTextV()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
void ImGui::TextEx(ImStrv text, ImGuiTextFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
return;
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// Accept null ranges
|
||||
if (text == text_end)
|
||||
text = text_end = "";
|
||||
|
||||
// Calculate length
|
||||
const char* text_begin = text;
|
||||
if (text_end == NULL)
|
||||
text_end = text + ImStrlen(text); // FIXME-OPT
|
||||
const char* text_begin = text.Begin;
|
||||
const char* text_end = text.End;
|
||||
|
||||
const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
const float wrap_pos_x = window->DC.TextWrapPos;
|
||||
const bool wrap_enabled = (wrap_pos_x >= 0.0f);
|
||||
if (text_end - text <= 2000 || wrap_enabled)
|
||||
if (text_end - text_begin <= 2000 || wrap_enabled)
|
||||
{
|
||||
// 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 ImVec2 text_size = CalcTextSize(text, false, wrap_width);
|
||||
|
||||
ImRect bb(text_pos, text_pos + text_size);
|
||||
ItemSize(text_size, 0.0f);
|
||||
@@ -187,7 +181,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
return;
|
||||
|
||||
// Render (we don't hide text after ## in this end-user function)
|
||||
RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width);
|
||||
RenderTextWrapped(bb.Min, text, wrap_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -196,7 +190,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
// - 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.
|
||||
// - We use memchr(), pay attention that well optimized versions of those str/mem functions are much faster than a casually written loop.
|
||||
const char* line = text;
|
||||
const char* line = text_begin;
|
||||
const float line_height = GetTextLineHeight();
|
||||
ImVec2 text_size(0, 0);
|
||||
|
||||
@@ -235,7 +229,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
if (!line_end)
|
||||
line_end = text_end;
|
||||
text_size.x = ImMax(text_size.x, CalcTextSize(line, line_end).x);
|
||||
RenderText(pos, line, line_end, false);
|
||||
RenderText(pos, ImStrv(line, line_end), false);
|
||||
line = line_end + 1;
|
||||
line_rect.Min.y += line_height;
|
||||
line_rect.Max.y += line_height;
|
||||
@@ -264,9 +258,9 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui::TextUnformatted(const char* text, const char* text_end)
|
||||
void ImGui::TextUnformatted(ImStrv text)
|
||||
{
|
||||
TextEx(text, text_end, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||
TextEx(text, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||
}
|
||||
|
||||
void ImGui::Text(const char* fmt, ...)
|
||||
@@ -283,9 +277,9 @@ void ImGui::TextV(const char* fmt, va_list args)
|
||||
if (window->SkipItems)
|
||||
return;
|
||||
|
||||
const char* text, *text_end;
|
||||
ImFormatStringToTempBufferV(&text, &text_end, fmt, args);
|
||||
TextEx(text, text_end, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||
ImStrv text;
|
||||
ImFormatStringToTempBufferV(&text, fmt, args);
|
||||
TextEx(text, ImGuiTextFlags_NoWidthForLargeClippedText);
|
||||
}
|
||||
|
||||
void ImGui::TextColored(const ImVec4& col, const char* fmt, ...)
|
||||
@@ -355,9 +349,9 @@ void ImGui::TextAlignedV(float align_x, float size_x, const char* fmt, va_list a
|
||||
if (window->SkipItems)
|
||||
return;
|
||||
|
||||
const char* text, *text_end;
|
||||
ImFormatStringToTempBufferV(&text, &text_end, fmt, args);
|
||||
const ImVec2 text_size = CalcTextSize(text, text_end);
|
||||
ImStrv text;
|
||||
ImFormatStringToTempBufferV(&text, fmt, args);
|
||||
const ImVec2 text_size = CalcTextSize(text);
|
||||
size_x = CalcItemSize(ImVec2(size_x, 0.0f), 0.0f, text_size.y).x;
|
||||
|
||||
ImVec2 pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
@@ -367,7 +361,7 @@ void ImGui::TextAlignedV(float align_x, float size_x, const char* fmt, va_list a
|
||||
window->DC.IdealMaxPos.x = ImMax(window->DC.IdealMaxPos.x, pos.x + text_size.x);
|
||||
if (align_x > 0.0f && text_size.x < size_x)
|
||||
pos.x += ImTrunc((size_x - text_size.x) * align_x);
|
||||
RenderTextEllipsis(window->DrawList, pos, pos_max, pos_max.x, text, text_end, &text_size);
|
||||
RenderTextEllipsis(window->DrawList, pos, pos_max, pos_max.x, text, &text_size);
|
||||
|
||||
const ImVec2 backup_max_pos = window->DC.CursorMaxPos;
|
||||
ItemSize(size);
|
||||
@@ -375,7 +369,7 @@ void ImGui::TextAlignedV(float align_x, float size_x, const char* fmt, va_list a
|
||||
window->DC.CursorMaxPos.x = backup_max_pos.x; // Cancel out extending content size because right-aligned text would otherwise mess it up.
|
||||
|
||||
if (size_x < text_size.x && IsItemHovered(ImGuiHoveredFlags_NoNavOverride | ImGuiHoveredFlags_AllowWhenDisabled | ImGuiHoveredFlags_ForTooltip))
|
||||
SetTooltip("%.*s", (int)(text_end - text), text);
|
||||
SetTooltip("%.*s", (int)(text.End - text.Begin), text.Begin);
|
||||
}
|
||||
|
||||
void ImGui::LabelText(ImStrv label, const char* fmt, ...)
|
||||
@@ -397,11 +391,10 @@ void ImGui::LabelTextV(ImStrv label, const char* fmt, va_list args)
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const float w = CalcItemWidth();
|
||||
|
||||
const char* value_text_begin, *value_text_end;
|
||||
ImFormatStringToTempBufferV(&value_text_begin, &value_text_end, fmt, args);
|
||||
const ImVec2 value_size = CalcTextSize(value_text_begin, value_text_end, false);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
ImStrv value_text;
|
||||
ImFormatStringToTempBufferV(&value_text, fmt, args);
|
||||
const ImVec2 value_size = CalcTextSize(value_text, false);
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const ImRect value_bb(pos, pos + ImVec2(w, value_size.y + style.FramePadding.y * 2));
|
||||
const ImRect total_bb(pos, pos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), ImMax(value_size.y, label_size.y) + style.FramePadding.y * 2));
|
||||
@@ -410,7 +403,7 @@ void ImGui::LabelTextV(ImStrv label, const char* fmt, va_list args)
|
||||
return;
|
||||
|
||||
// Render
|
||||
RenderTextClipped(value_bb.Min + style.FramePadding, value_bb.Max, value_text_begin, value_text_end, &value_size, ImVec2(0.0f, 0.0f));
|
||||
RenderTextClipped(value_bb.Min + style.FramePadding, value_bb.Max, value_text, &value_size, ImVec2(0.0f, 0.0f));
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label);
|
||||
}
|
||||
@@ -433,9 +426,9 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
const char* text_begin, *text_end;
|
||||
ImFormatStringToTempBufferV(&text_begin, &text_end, fmt, args);
|
||||
const ImVec2 label_size = CalcTextSize(text_begin, text_end, false);
|
||||
ImStrv text;
|
||||
ImFormatStringToTempBufferV(&text, fmt, args);
|
||||
const ImVec2 label_size = CalcTextSize(text, false);
|
||||
const ImVec2 total_size = ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x * 2) : 0.0f), label_size.y); // Empty text doesn't add padding
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
pos.y += window->DC.CurrLineTextBaseOffset;
|
||||
@@ -447,7 +440,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
|
||||
// Render
|
||||
ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
||||
RenderBullet(window->DrawList, bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, g.FontSize * 0.5f), text_col);
|
||||
RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x * 2, 0.0f), text_begin, text_end, false);
|
||||
RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x * 2, 0.0f), text, false);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -772,7 +765,7 @@ bool ImGui::ButtonEx(ImStrv label, const ImVec2& size_arg, ImGuiButtonFlags flag
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrLineTextBaseOffset) // Try to vertically align buttons that are smaller/have no padding so that text baseline matches (bit hacky, since it shouldn't be a flag)
|
||||
@@ -794,7 +787,7 @@ bool ImGui::ButtonEx(ImStrv label, const ImVec2& size_arg, ImGuiButtonFlags flag
|
||||
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("[", "]");
|
||||
RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb);
|
||||
RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, &label_size, style.ButtonTextAlign, &bb);
|
||||
|
||||
// Automatically close popups
|
||||
//if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
||||
@@ -1217,7 +1210,7 @@ bool ImGui::Checkbox(ImStrv label, bool* v)
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
|
||||
const float square_sz = GetFrameHeight();
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
@@ -1339,7 +1332,7 @@ bool ImGui::RadioButton(ImStrv label, bool active)
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
|
||||
const float square_sz = GetFrameHeight();
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
@@ -1436,7 +1429,7 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, ImStrv overlay)
|
||||
// Default displaying the fraction as percentage string, but user can override it
|
||||
// Don't display text for indeterminate bars by default
|
||||
char overlay_buf[32];
|
||||
if (!is_indeterminate || overlay != NULL)
|
||||
if (!is_indeterminate || overlay)
|
||||
{
|
||||
if (!overlay)
|
||||
{
|
||||
@@ -1444,11 +1437,11 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, ImStrv overlay)
|
||||
overlay = overlay_buf;
|
||||
}
|
||||
|
||||
ImVec2 overlay_size = CalcTextSize(overlay, NULL);
|
||||
ImVec2 overlay_size = CalcTextSize(overlay);
|
||||
if (overlay_size.x > 0.0f)
|
||||
{
|
||||
float text_x = is_indeterminate ? (bb.Min.x + bb.Max.x - overlay_size.x) * 0.5f : ImLerp(bb.Min.x, bb.Max.x, fill_n1) + style.ItemSpacing.x;
|
||||
RenderTextClipped(ImVec2(ImClamp(text_x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
|
||||
RenderTextClipped(ImVec2(ImClamp(text_x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1491,7 +1484,7 @@ bool ImGui::TextLink(ImStrv label)
|
||||
const char* label_end = FindRenderedTextEnd(label);
|
||||
|
||||
ImVec2 pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
ImVec2 size = CalcTextSize(label, label_end, true);
|
||||
ImVec2 size = CalcTextSize(label.Begin, label_end, true);
|
||||
ImRect bb(pos, pos + size);
|
||||
ItemSize(size, 0.0f);
|
||||
if (!ItemAdd(bb, id))
|
||||
@@ -1525,7 +1518,7 @@ bool ImGui::TextLink(ImStrv label)
|
||||
window->DrawList->AddLine(ImVec2(bb.Min.x, line_y), ImVec2(bb.Max.x, line_y), GetColorU32(line_colf)); // FIXME-TEXT: Underline mode // FIXME-DPI
|
||||
|
||||
PushStyleColor(ImGuiCol_Text, GetColorU32(text_colf));
|
||||
RenderText(bb.Min, label, label_end);
|
||||
RenderText(bb.Min, label.Begin, label_end);
|
||||
PopStyleColor();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
|
||||
@@ -1535,12 +1528,17 @@ bool ImGui::TextLink(ImStrv label)
|
||||
bool ImGui::TextLinkOpenURL(ImStrv label, ImStrv url)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (url == NULL)
|
||||
url = label;
|
||||
bool pressed = TextLink(label);
|
||||
label.End = FindRenderedTextEnd(label.Begin);
|
||||
if (!url)
|
||||
url = label;
|
||||
if (pressed && g.PlatformIO.Platform_OpenInShellFn != NULL)
|
||||
g.PlatformIO.Platform_OpenInShellFn(&g, url);
|
||||
SetItemTooltip(LocalizeGetMsg(ImGuiLocKey_OpenLink_s), url); // It is more reassuring for user to _always_ display URL when we same as label
|
||||
{
|
||||
ImStrv url_zt;
|
||||
ImFormatStringToTempBuffer(&url_zt, "%.*s", (int)url.length(), url.Begin);
|
||||
g.PlatformIO.Platform_OpenInShellFn(&g, url_zt.Begin);
|
||||
}
|
||||
SetItemTooltip(LocalizeGetMsg(ImGuiLocKey_OpenLink_s), (int)url.length(), url.Begin); // It is more reassuring for user to _always_ display URL when we same as label
|
||||
if (BeginPopupContextItem())
|
||||
{
|
||||
if (MenuItem(LocalizeGetMsg(ImGuiLocKey_CopyLink)))
|
||||
@@ -1695,13 +1693,13 @@ void ImGui::Separator()
|
||||
SeparatorEx(flags, 1.0f);
|
||||
}
|
||||
|
||||
void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_w)
|
||||
void ImGui::SeparatorTextEx(ImGuiID id, ImStrv label, float extra_w)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiStyle& style = g.Style;
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, label_end, false);
|
||||
const ImVec2 label_size = CalcTextSize(label, false);
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const ImVec2 padding = style.SeparatorTextPadding;
|
||||
|
||||
@@ -1734,7 +1732,7 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end
|
||||
window->DrawList->AddLine(ImVec2(sep2_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness);
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("---", NULL);
|
||||
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(bb.Max.x, bb.Max.y + style.ItemSpacing.y), bb.Max.x, label, label_end, &label_size);
|
||||
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(bb.Max.x, bb.Max.y + style.ItemSpacing.y), bb.Max.x, label, &label_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1757,7 +1755,7 @@ void ImGui::SeparatorText(ImStrv label)
|
||||
// - because of this we probably can't turn 'const char* label' into 'const char* fmt, ...'
|
||||
// Otherwise, we can decide that users wanting to drag this would layout a dedicated drag-item,
|
||||
// and then we can turn this into a format function.
|
||||
SeparatorTextEx(0, label, FindRenderedTextEnd(label), 0.0f);
|
||||
SeparatorTextEx(0, ImStrv(label.Begin, FindRenderedTextEnd(label)), 0.0f);
|
||||
}
|
||||
|
||||
// Using 'hover_visibility_delay' allows us to hide the highlight and mouse cursor for a short time, which can be convenient to reduce visual noise.
|
||||
@@ -1912,8 +1910,8 @@ bool ImGui::BeginCombo(ImStrv label, ImStrv preview_value, ImGuiComboFlags flags
|
||||
IM_ASSERT((flags & (ImGuiComboFlags_NoPreview | (ImGuiComboFlags)ImGuiComboFlags_CustomPreview)) == 0);
|
||||
|
||||
const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const float preview_width = ((flags & ImGuiComboFlags_WidthFitPreview) && (preview_value != NULL)) ? CalcTextSize(preview_value, NULL, true).x : 0.0f;
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
const float preview_width = ((flags & ImGuiComboFlags_WidthFitPreview) && (preview_value != NULL)) ? CalcTextSize(preview_value, true).x : 0.0f;
|
||||
const float w = (flags & ImGuiComboFlags_NoPreview) ? arrow_size : ((flags & ImGuiComboFlags_WidthFitPreview) ? (arrow_size + preview_width + style.FramePadding.x * 2.0f) : CalcItemWidth());
|
||||
const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||
const ImRect total_bb(bb.Min, bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
@@ -1952,16 +1950,15 @@ bool ImGui::BeginCombo(ImStrv label, ImStrv preview_value, ImGuiComboFlags flags
|
||||
if (flags & ImGuiComboFlags_CustomPreview)
|
||||
{
|
||||
g.ComboPreviewData.PreviewRect = ImRect(bb.Min.x, bb.Min.y, value_x2, bb.Max.y);
|
||||
IM_ASSERT(preview_value == NULL || preview_value[0] == 0);
|
||||
preview_value = NULL;
|
||||
IM_ASSERT(!preview_value);
|
||||
}
|
||||
|
||||
// Render preview and label
|
||||
if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview))
|
||||
if (!preview_value.empty() && !(flags & ImGuiComboFlags_NoPreview))
|
||||
{
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("{", "}");
|
||||
RenderTextClipped(bb.Min + style.FramePadding, ImVec2(value_x2, bb.Max.y), preview_value, NULL, NULL);
|
||||
RenderTextClipped(bb.Min + style.FramePadding, ImVec2(value_x2, bb.Max.y), preview_value, NULL);
|
||||
}
|
||||
if (label_size.x > 0)
|
||||
RenderText(ImVec2(bb.Max.x + style.ItemInnerSpacing.x, bb.Min.y + style.FramePadding.y), label);
|
||||
@@ -2666,7 +2663,7 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v
|
||||
|
||||
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a Drag widget, p_min and p_max are optional.
|
||||
// Read code of e.g. DragFloat(), DragInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||
bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, ImStrv format, ImGuiSliderFlags flags)
|
||||
bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, ImStrv format_p, ImGuiSliderFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@@ -2677,7 +2674,7 @@ bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, floa
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const float w = CalcItemWidth();
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
|
||||
@@ -2686,8 +2683,14 @@ bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, floa
|
||||
if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0))
|
||||
return false;
|
||||
|
||||
// FIXME-IMSTR
|
||||
char format_0[64]; // format may not end with \0
|
||||
const char* format = format_0;
|
||||
IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_0));
|
||||
ImStrncpy(format_0, format_p, IM_ARRAYSIZE(format_0));
|
||||
|
||||
// Default format string when passing NULL
|
||||
if (format == NULL)
|
||||
if (!format_p)
|
||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
|
||||
const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.ItemFlags);
|
||||
@@ -2756,7 +2759,7 @@ bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, floa
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("{", "}");
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, ImStrv(value_buf, value_buf_end), NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
@@ -2789,11 +2792,11 @@ bool ImGui::DragScalarN(ImStrv label, ImGuiDataType data_type, void* p_data, int
|
||||
}
|
||||
PopID();
|
||||
|
||||
const char* label_end = FindRenderedTextEnd(label);
|
||||
if (label != label_end)
|
||||
label.End = FindRenderedTextEnd(label);
|
||||
if (label.Begin != label.End)
|
||||
{
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
TextEx(label, label_end);
|
||||
TextEx(label);
|
||||
}
|
||||
|
||||
EndGroup();
|
||||
@@ -2846,7 +2849,8 @@ bool ImGui::DragFloatRange2(ImStrv label, float* v_current_min, float* v_current
|
||||
PopItemWidth();
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
|
||||
TextEx(label, FindRenderedTextEnd(label));
|
||||
label.End = FindRenderedTextEnd(label);
|
||||
TextEx(label);
|
||||
EndGroup();
|
||||
PopID();
|
||||
|
||||
@@ -2900,7 +2904,8 @@ bool ImGui::DragIntRange2(ImStrv label, int* v_current_min, int* v_current_max,
|
||||
PopItemWidth();
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
|
||||
TextEx(label, FindRenderedTextEnd(label));
|
||||
label.End = FindRenderedTextEnd(label);
|
||||
TextEx(label);
|
||||
EndGroup();
|
||||
PopID();
|
||||
|
||||
@@ -3270,7 +3275,7 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type
|
||||
|
||||
// Note: p_data, p_min and p_max are _pointers_ to a memory address holding the data. For a slider, they are all required.
|
||||
// Read code of e.g. SliderFloat(), SliderInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||
bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, ImStrv format, ImGuiSliderFlags flags)
|
||||
bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, ImStrv format_p, ImGuiSliderFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@@ -3281,7 +3286,7 @@ bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, co
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const float w = CalcItemWidth();
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f));
|
||||
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
|
||||
@@ -3290,8 +3295,13 @@ bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, co
|
||||
if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0))
|
||||
return false;
|
||||
|
||||
// FIXME-IMSTR
|
||||
char format_0[64]; // format may not end with \0
|
||||
const char* format = format_0;
|
||||
IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_0));
|
||||
|
||||
// Default format string when passing NULL
|
||||
if (format == NULL)
|
||||
if (!format_p)
|
||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
|
||||
const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.ItemFlags);
|
||||
@@ -3347,7 +3357,7 @@ bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, co
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("{", "}");
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, ImStrv(value_buf, value_buf_end), NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
@@ -3381,11 +3391,11 @@ bool ImGui::SliderScalarN(ImStrv label, ImGuiDataType data_type, void* v, int co
|
||||
}
|
||||
PopID();
|
||||
|
||||
const char* label_end = FindRenderedTextEnd(label);
|
||||
if (label != label_end)
|
||||
label.End = FindRenderedTextEnd(label);
|
||||
if (label.Begin != label.End)
|
||||
{
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
TextEx(label, label_end);
|
||||
TextEx(label);
|
||||
}
|
||||
|
||||
EndGroup();
|
||||
@@ -3414,7 +3424,7 @@ bool ImGui::SliderFloat4(ImStrv label, float v[4], float v_min, float v_max, ImS
|
||||
|
||||
bool ImGui::SliderAngle(ImStrv label, float* v_rad, float v_degrees_min, float v_degrees_max, ImStrv format, ImGuiSliderFlags flags)
|
||||
{
|
||||
if (format == NULL)
|
||||
if (!format)
|
||||
format = "%.0f deg";
|
||||
float v_deg = (*v_rad) * 360.0f / (2 * IM_PI);
|
||||
bool value_changed = SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, format, flags);
|
||||
@@ -3443,7 +3453,7 @@ bool ImGui::SliderInt4(ImStrv label, int v[4], int v_min, int v_max, ImStrv form
|
||||
return SliderScalarN(label, ImGuiDataType_S32, v, 4, &v_min, &v_max, format, flags);
|
||||
}
|
||||
|
||||
bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, ImStrv format, ImGuiSliderFlags flags)
|
||||
bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, ImStrv format_p, ImGuiSliderFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@@ -3453,7 +3463,7 @@ bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_t
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
||||
const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
|
||||
@@ -3461,8 +3471,13 @@ bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_t
|
||||
if (!ItemAdd(frame_bb, id))
|
||||
return false;
|
||||
|
||||
// FIXME-IMSTR
|
||||
char format_0[64]; // format may not end with \0
|
||||
const char* format = format_0;
|
||||
IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_0));
|
||||
|
||||
// Default format string when passing NULL
|
||||
if (format == NULL)
|
||||
if (!format_p)
|
||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
|
||||
const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.ItemFlags);
|
||||
@@ -3496,7 +3511,7 @@ bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_t
|
||||
// For the vertical slider we allow centered text to overlap the frame padding
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format);
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f));
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, ImStrv(value_buf, value_buf_end), NULL, ImVec2(0.5f, 0.0f));
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
|
||||
@@ -3738,7 +3753,7 @@ void ImGui::SetNextItemRefVal(ImGuiDataType data_type, void* p_data)
|
||||
|
||||
// Note: p_data, p_step, p_step_fast are _pointers_ to a memory address holding the data. For an Input widget, p_step and p_step_fast are optional.
|
||||
// Read code of e.g. InputFloat(), InputInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly.
|
||||
bool ImGui::InputScalar(ImStrv label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, ImStrv format, ImGuiInputTextFlags flags)
|
||||
bool ImGui::InputScalar(ImStrv label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, ImStrv format_p, ImGuiInputTextFlags flags)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@@ -3748,7 +3763,13 @@ bool ImGui::InputScalar(ImStrv label, ImGuiDataType data_type, void* p_data, con
|
||||
ImGuiStyle& style = g.Style;
|
||||
IM_ASSERT((flags & ImGuiInputTextFlags_EnterReturnsTrue) == 0); // Not supported by InputScalar(). Please open an issue if you this would be useful to you. Otherwise use IsItemDeactivatedAfterEdit()!
|
||||
|
||||
if (format == NULL)
|
||||
// FIXME-IMSTR
|
||||
char format_0[64]; // format may not end with \0
|
||||
const char* format = format_0;
|
||||
IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_0));
|
||||
ImStrncpy(format_0, format_p, IM_ARRAYSIZE(format_0));
|
||||
|
||||
if (!format_p)
|
||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
|
||||
void* p_data_default = (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasRefVal) ? &g.NextItemData.RefVal : &g.DataTypeZeroValue;
|
||||
@@ -3803,11 +3824,11 @@ bool ImGui::InputScalar(ImStrv label, ImGuiDataType data_type, void* p_data, con
|
||||
if (flags & ImGuiInputTextFlags_ReadOnly)
|
||||
EndDisabled();
|
||||
|
||||
const char* label_end = FindRenderedTextEnd(label);
|
||||
if (label != label_end)
|
||||
label.End = FindRenderedTextEnd(label);
|
||||
if (label.Begin != label.End)
|
||||
{
|
||||
SameLine(0, style.ItemInnerSpacing.x);
|
||||
TextEx(label, label_end);
|
||||
TextEx(label);
|
||||
}
|
||||
style.FramePadding = backup_frame_padding;
|
||||
|
||||
@@ -3846,11 +3867,11 @@ bool ImGui::InputScalarN(ImStrv label, ImGuiDataType data_type, void* p_data, in
|
||||
}
|
||||
PopID();
|
||||
|
||||
const char* label_end = FindRenderedTextEnd(label);
|
||||
if (label != label_end)
|
||||
label.End = FindRenderedTextEnd(label);
|
||||
if (label.Begin != label.End)
|
||||
{
|
||||
SameLine(0.0f, g.Style.ItemInnerSpacing.x);
|
||||
TextEx(label, label_end);
|
||||
TextEx(label);
|
||||
}
|
||||
|
||||
EndGroup();
|
||||
@@ -4290,10 +4311,10 @@ void ImGuiInputTextCallbackData::DeleteChars(int pos, int bytes_count)
|
||||
BufTextLen -= bytes_count;
|
||||
}
|
||||
|
||||
void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, const char* new_text_end)
|
||||
void ImGuiInputTextCallbackData::InsertChars(int pos, ImStrv new_text)
|
||||
{
|
||||
// Accept null ranges
|
||||
if (new_text == new_text_end)
|
||||
if (new_text.Begin == new_text.End)
|
||||
return;
|
||||
|
||||
ImGuiContext& g = *Ctx;
|
||||
@@ -4302,7 +4323,7 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
||||
|
||||
// Grow internal buffer if needed
|
||||
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
||||
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text);
|
||||
const int new_text_len = (int)new_text.length();
|
||||
if (new_text_len + BufTextLen + 1 > obj->TextA.Size && (Flags & ImGuiInputTextFlags_ReadOnly) == 0)
|
||||
{
|
||||
if (!is_resizable)
|
||||
@@ -4318,7 +4339,8 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
||||
|
||||
if (BufTextLen != pos)
|
||||
memmove(Buf + pos + new_text_len, Buf + pos, (size_t)(BufTextLen - pos));
|
||||
memcpy(Buf + pos, new_text, (size_t)new_text_len * sizeof(char));
|
||||
if (new_text_len > 0)
|
||||
memcpy(Buf + pos, new_text.Begin, (size_t)new_text_len * sizeof(char));
|
||||
Buf[BufTextLen + new_text_len] = '\0';
|
||||
|
||||
if (CursorPos >= pos)
|
||||
@@ -4636,7 +4658,7 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
||||
if (is_multiline) // Open group before calling GetID() because groups tracks id created within their scope (including the scrollbar)
|
||||
BeginGroup();
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? g.FontSize * 8.0f : label_size.y) + style.FramePadding.y * 2.0f); // Arbitrary default of 8 lines high for multi-line
|
||||
const ImVec2 total_size = ImVec2(frame_size.x + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), frame_size.y);
|
||||
|
||||
@@ -4868,7 +4890,7 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
||||
|
||||
// Select the buffer to render.
|
||||
const bool buf_display_from_state = (render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state;
|
||||
bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
||||
bool is_displaying_hint = (!hint.empty() && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
||||
|
||||
// Password pushes a temporary font with only a fallback glyph
|
||||
if (is_password && !is_displaying_hint)
|
||||
@@ -5133,16 +5155,16 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
||||
}
|
||||
else if (is_paste)
|
||||
{
|
||||
if (const char* clipboard = GetClipboardText())
|
||||
if (ImStrv clipboard = GetClipboardText())
|
||||
{
|
||||
// Filter pasted buffer
|
||||
const int clipboard_len = (int)ImStrlen(clipboard);
|
||||
const int clipboard_len = (int)clipboard.length();
|
||||
ImVector<char> clipboard_filtered;
|
||||
clipboard_filtered.reserve(clipboard_len + 1);
|
||||
for (const char* s = clipboard; *s != 0; )
|
||||
for (const char* s = clipboard.Begin; *s != 0; )
|
||||
{
|
||||
unsigned int c;
|
||||
int in_len = ImTextCharFromUtf8(&c, s, NULL);
|
||||
int in_len = ImTextCharFromUtf8(&c, s, clipboard.End);
|
||||
s += in_len;
|
||||
if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, true))
|
||||
continue;
|
||||
@@ -5365,7 +5387,7 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
||||
|
||||
// Display hint when contents is empty
|
||||
// At this point we need to handle the possibility that a callback could have modified the underlying buffer (#8368)
|
||||
const bool new_is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
||||
const bool new_is_displaying_hint = (!hint.empty() && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
||||
if (new_is_displaying_hint != is_displaying_hint)
|
||||
{
|
||||
if (is_password && !is_displaying_hint)
|
||||
@@ -5376,8 +5398,8 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
||||
}
|
||||
if (is_displaying_hint)
|
||||
{
|
||||
buf_display = hint;
|
||||
buf_display_end = hint + ImStrlen(hint);
|
||||
buf_display = hint.Begin;
|
||||
buf_display_end = hint.End;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5523,8 +5545,7 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
||||
g.Font->RenderText(draw_window->DrawList, g.FontSize,
|
||||
draw_pos - draw_scroll + ImVec2(0.0f, line_visible_n0 * g.FontSize),
|
||||
text_col, clip_rect.AsVec4(),
|
||||
line_index->get_line_begin(buf_display, line_visible_n0),
|
||||
line_index->get_line_end(buf_display, line_visible_n1 - 1),
|
||||
ImStrv(line_index->get_line_begin(buf_display, line_visible_n0), line_index->get_line_end(buf_display, line_visible_n1 - 1)),
|
||||
wrap_width, ImDrawTextFlags_WrapKeepBlanks);
|
||||
|
||||
// Render blinking cursor
|
||||
@@ -5579,7 +5600,7 @@ bool ImGui::InputTextEx(ImStrv label, ImStrv hint, char* buf, int buf_size, cons
|
||||
if (g.LogEnabled && (!is_password || is_displaying_hint))
|
||||
{
|
||||
LogSetNextTextDecoration("{", "}");
|
||||
LogRenderedText(&draw_pos, buf_display, buf_display_end);
|
||||
LogRenderedText(&draw_pos, ImStrv(buf_display, buf_display_end));
|
||||
}
|
||||
|
||||
if (label_size.x > 0)
|
||||
@@ -5694,7 +5715,6 @@ bool ImGui::ColorEdit4(ImStrv label, float col[4], ImGuiColorEditFlags flags)
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const float square_sz = GetFrameHeight();
|
||||
const char* label_display_end = FindRenderedTextEnd(label);
|
||||
float w_full = CalcItemWidth();
|
||||
g.NextItemData.ClearFlags();
|
||||
|
||||
@@ -5703,6 +5723,7 @@ bool ImGui::ColorEdit4(ImStrv label, float col[4], ImGuiColorEditFlags flags)
|
||||
const bool set_current_color_edit_id = (g.ColorEditCurrentID == 0);
|
||||
if (set_current_color_edit_id)
|
||||
g.ColorEditCurrentID = window->IDStack.back();
|
||||
label.End = FindRenderedTextEnd(label);
|
||||
|
||||
// If we're not showing any slider there's no point in doing any HSV conversions
|
||||
const ImGuiColorEditFlags flags_untouched = flags;
|
||||
@@ -5849,9 +5870,9 @@ bool ImGui::ColorEdit4(ImStrv label, float col[4], ImGuiColorEditFlags flags)
|
||||
if (g.CurrentWindow->BeginCount == 1)
|
||||
{
|
||||
picker_active_window = g.CurrentWindow;
|
||||
if (label != label_display_end)
|
||||
if (label.Begin != label.End)
|
||||
{
|
||||
TextEx(label, label_display_end);
|
||||
TextEx(label);
|
||||
Spacing();
|
||||
}
|
||||
ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar;
|
||||
@@ -5863,13 +5884,13 @@ bool ImGui::ColorEdit4(ImStrv label, float col[4], ImGuiColorEditFlags flags)
|
||||
}
|
||||
}
|
||||
|
||||
if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel))
|
||||
if (label.Begin != label.End && !(flags & ImGuiColorEditFlags_NoLabel))
|
||||
{
|
||||
// Position not necessarily next to last submitted button (e.g. if style.ColorButtonPosition == ImGuiDir_Left),
|
||||
// but we need to use SameLine() to setup baseline correctly. Might want to refactor SameLine() to simplify this.
|
||||
SameLine(0.0f, style.ItemInnerSpacing.x);
|
||||
window->DC.CursorPos.x = pos.x + ((flags & ImGuiColorEditFlags_NoInputs) ? w_button : w_full + style.ItemInnerSpacing.x);
|
||||
TextEx(label, label_display_end);
|
||||
TextEx(label);
|
||||
}
|
||||
|
||||
// Convert back
|
||||
@@ -6116,11 +6137,11 @@ bool ImGui::ColorPicker4(ImStrv label, float col[4], ImGuiColorEditFlags flags,
|
||||
if (!(flags & ImGuiColorEditFlags_NoLabel))
|
||||
{
|
||||
const char* label_display_end = FindRenderedTextEnd(label);
|
||||
if (label != label_display_end)
|
||||
if (label.Begin != label_display_end)
|
||||
{
|
||||
if ((flags & ImGuiColorEditFlags_NoSidePreview))
|
||||
SameLine(0, style.ItemInnerSpacing.x);
|
||||
TextEx(label, label_display_end);
|
||||
TextEx(ImStrv(label.Begin, label_display_end));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6438,10 +6459,10 @@ void ImGui::ColorTooltip(ImStrv text, const float* col, ImGuiColorEditFlags flag
|
||||
|
||||
if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePrevious, ImGuiWindowFlags_None))
|
||||
return;
|
||||
const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text;
|
||||
if (text_end > text)
|
||||
text.End = FindRenderedTextEnd(text);
|
||||
if (text.Begin != text.End)
|
||||
{
|
||||
TextEx(text, text_end);
|
||||
TextEx(text);
|
||||
Separator();
|
||||
}
|
||||
|
||||
@@ -6603,7 +6624,7 @@ bool ImGui::TreeNode(ImStrv label)
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
ImGuiID id = window->GetID(label);
|
||||
return TreeNodeBehavior(id, ImGuiTreeNodeFlags_None, label, NULL);
|
||||
return TreeNodeBehavior(id, ImGuiTreeNodeFlags_None, label);
|
||||
}
|
||||
|
||||
bool ImGui::TreeNodeV(ImStrv str_id, const char* fmt, va_list args)
|
||||
@@ -6622,7 +6643,7 @@ bool ImGui::TreeNodeEx(ImStrv label, ImGuiTreeNodeFlags flags)
|
||||
if (window->SkipItems)
|
||||
return false;
|
||||
ImGuiID id = window->GetID(label);
|
||||
return TreeNodeBehavior(id, flags, label, NULL);
|
||||
return TreeNodeBehavior(id, flags, label);
|
||||
}
|
||||
|
||||
bool ImGui::TreeNodeEx(ImStrv str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...)
|
||||
@@ -6650,9 +6671,9 @@ bool ImGui::TreeNodeExV(ImStrv str_id, ImGuiTreeNodeFlags flags, const char* fmt
|
||||
return false;
|
||||
|
||||
ImGuiID id = window->GetID(str_id);
|
||||
const char* label, *label_end;
|
||||
ImFormatStringToTempBufferV(&label, &label_end, fmt, args);
|
||||
return TreeNodeBehavior(id, flags, label, label_end);
|
||||
ImStrv label;
|
||||
ImFormatStringToTempBufferV(&label, fmt, args);
|
||||
return TreeNodeBehavior(id, flags, label);
|
||||
}
|
||||
|
||||
bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args)
|
||||
@@ -6662,9 +6683,9 @@ bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char
|
||||
return false;
|
||||
|
||||
ImGuiID id = window->GetID(ptr_id);
|
||||
const char* label, *label_end;
|
||||
ImFormatStringToTempBufferV(&label, &label_end, fmt, args);
|
||||
return TreeNodeBehavior(id, flags, label, label_end);
|
||||
ImStrv label;
|
||||
ImFormatStringToTempBufferV(&label, fmt, args);
|
||||
return TreeNodeBehavior(id, flags, label);
|
||||
}
|
||||
|
||||
bool ImGui::TreeNodeGetOpen(ImGuiID storage_id)
|
||||
@@ -6752,7 +6773,7 @@ static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags, float x1)
|
||||
}
|
||||
|
||||
// When using public API, currently 'id == storage_id' is always true, but we separate the values to facilitate advanced user code doing storage queries outside of UI loop.
|
||||
bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
|
||||
bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, ImStrv label)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@@ -6762,10 +6783,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0;
|
||||
const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y));
|
||||
|
||||
if (!label_end)
|
||||
label_end = FindRenderedTextEnd(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, label_end, false);
|
||||
label.End = FindRenderedTextEnd(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, false);
|
||||
|
||||
const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing
|
||||
const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it
|
||||
@@ -7016,9 +7035,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
|
||||
// Label
|
||||
if (display_frame)
|
||||
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
|
||||
RenderTextClipped(text_pos, frame_bb.Max, label, &label_size);
|
||||
else
|
||||
RenderText(text_pos, label, label_end, false);
|
||||
RenderText(text_pos, label, false);
|
||||
|
||||
if (span_all_columns_label)
|
||||
TablePopBackgroundChannel();
|
||||
@@ -7245,7 +7264,7 @@ bool ImGui::Selectable(ImStrv label, bool selected, ImGuiSelectableFlags flags,
|
||||
|
||||
// Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle.
|
||||
ImGuiID id = window->GetID(label);
|
||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
ImVec2 label_size = CalcTextSize(label, true);
|
||||
ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y);
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
pos.y += window->DC.CurrLineTextBaseOffset;
|
||||
@@ -7400,7 +7419,7 @@ bool ImGui::Selectable(ImStrv label, bool selected, ImGuiSelectableFlags flags,
|
||||
|
||||
// Text stays at the submission position. Alignment/clipping extents ignore SpanAllColumns.
|
||||
if (is_visible)
|
||||
RenderTextClipped(pos, ImVec2(ImMin(pos.x + size.x, window->WorkRect.Max.x), pos.y + size.y), label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
||||
RenderTextClipped(pos, ImVec2(ImMin(pos.x + size.x, window->WorkRect.Max.x), pos.y + size.y), label, &label_size, style.SelectableTextAlign, &bb);
|
||||
|
||||
// Automatically close popups
|
||||
if (pressed && !auto_selected && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_NoAutoClosePopups) && (g.LastItemData.ItemFlags & ImGuiItemFlags_AutoClosePopups))
|
||||
@@ -8573,7 +8592,7 @@ bool ImGui::BeginListBox(ImStrv label, const ImVec2& size_arg)
|
||||
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
|
||||
// Size default to hold ~7.25 items.
|
||||
// Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar.
|
||||
@@ -8692,7 +8711,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, ImStrv label, float (*values_getter)(
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImVec2 label_size = CalcTextSize(label, true);
|
||||
const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), label_size.y + style.FramePadding.y * 2.0f);
|
||||
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
|
||||
@@ -8788,7 +8807,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, ImStrv label, float (*values_getter)(
|
||||
|
||||
// Text overlay
|
||||
if (overlay_text)
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImVec2(0.5f, 0.0f));
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, ImVec2(0.5f, 0.0f));
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label);
|
||||
@@ -8844,17 +8863,17 @@ void ImGui::PlotHistogram(ImStrv label, float (*values_getter)(void* data, int i
|
||||
|
||||
void ImGui::Value(ImStrv prefix, bool b)
|
||||
{
|
||||
Text("%s: %s", prefix, (b ? "true" : "false"));
|
||||
Text("%.*s: %s", (int)prefix.length(), prefix.Begin, (b ? "true" : "false"));
|
||||
}
|
||||
|
||||
void ImGui::Value(ImStrv prefix, int v)
|
||||
{
|
||||
Text("%s: %d", prefix, v);
|
||||
Text("%.*s: %d", (int)prefix.length(), prefix.Begin, v);
|
||||
}
|
||||
|
||||
void ImGui::Value(ImStrv prefix, unsigned int v)
|
||||
{
|
||||
Text("%s: %d", prefix, v);
|
||||
Text("%.*s: %d", (int)prefix.length(), prefix.Begin, v);
|
||||
}
|
||||
|
||||
void ImGui::Value(ImStrv prefix, float v, ImStrv float_format)
|
||||
@@ -8862,12 +8881,12 @@ void ImGui::Value(ImStrv prefix, float v, ImStrv float_format)
|
||||
if (float_format)
|
||||
{
|
||||
char fmt[64];
|
||||
ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format);
|
||||
Text(fmt, prefix, v);
|
||||
ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%.*s: %.*s", (int)float_format.length(), float_format.Begin);
|
||||
Text(fmt, (int)prefix.length(), prefix.Begin, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
Text("%s: %.3f", prefix, v);
|
||||
Text("%.*s: %.3f", (int)prefix.length(), prefix.Begin, v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9156,7 +9175,7 @@ bool ImGui::BeginMenuEx(ImStrv label, ImStrv icon, bool enabled)
|
||||
// Tag menu as used. Next time BeginMenu() with same ID is called it will append to existing menu
|
||||
g.MenusIdSubmittedThisFrame.push_back(id);
|
||||
|
||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
ImVec2 label_size = CalcTextSize(label, true);
|
||||
|
||||
// Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent without always being a Child window)
|
||||
// This is only done for items for the menu set and not the full parent window.
|
||||
@@ -9198,7 +9217,7 @@ bool ImGui::BeginMenuEx(ImStrv label, ImStrv icon, bool enabled)
|
||||
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
|
||||
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.)
|
||||
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
|
||||
float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
|
||||
float icon_w = !icon.empty() ? CalcTextSize(icon, NULL).x : 0.0f;
|
||||
float checkmark_w = IM_TRUNC(g.FontSize * 1.20f);
|
||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame
|
||||
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||
@@ -9368,7 +9387,7 @@ bool ImGui::MenuItemEx(ImStrv label, ImStrv icon, ImStrv shortcut, bool selected
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiStyle& style = g.Style;
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
ImVec2 label_size = CalcTextSize(label, true);
|
||||
|
||||
// See BeginMenuEx() for comments about this.
|
||||
const bool menuset_is_open = IsRootOfOpenMenuSet();
|
||||
@@ -9404,8 +9423,8 @@ bool ImGui::MenuItemEx(ImStrv label, ImStrv icon, ImStrv shortcut, bool selected
|
||||
// Menu item inside a vertical menu
|
||||
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
|
||||
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.)
|
||||
float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
|
||||
float shortcut_w = (shortcut && shortcut[0]) ? CalcTextSize(shortcut, NULL).x : 0.0f;
|
||||
float icon_w = !icon.empty() ? CalcTextSize(icon).x : 0.0f;
|
||||
float shortcut_w = !shortcut.empty() ? CalcTextSize(shortcut).x : 0.0f;
|
||||
float checkmark_w = IM_TRUNC(g.FontSize * 1.20f);
|
||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
|
||||
float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||
@@ -9419,7 +9438,7 @@ bool ImGui::MenuItemEx(ImStrv label, ImStrv icon, ImStrv shortcut, bool selected
|
||||
{
|
||||
PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]);
|
||||
LogSetNextTextDecoration("(", ")");
|
||||
RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false);
|
||||
RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, false);
|
||||
PopStyleColor();
|
||||
}
|
||||
if (selected)
|
||||
@@ -10401,6 +10420,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, ImStrv label, bool* p_open, ImGui
|
||||
tab_bar->LastTabItemIdx = (ImS16)tab_bar->Tabs.index_from_ptr(tab);
|
||||
|
||||
// Calculate tab contents size
|
||||
label.End = FindRenderedTextEnd(label);
|
||||
ImVec2 size = TabItemCalcSize(label, (p_open != NULL) || (flags & ImGuiTabItemFlags_UnsavedDocument));
|
||||
tab->RequestedWidth = -1.0f;
|
||||
if (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasWidth)
|
||||
@@ -10426,7 +10446,9 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, ImStrv label, bool* p_open, ImGui
|
||||
else
|
||||
{
|
||||
tab->NameOffset = (ImS32)tab_bar->TabsNames.size();
|
||||
tab_bar->TabsNames.append(label, label + ImStrlen(label) + 1);
|
||||
tab_bar->TabsNames.append(label);
|
||||
char zero_c = 0;
|
||||
tab_bar->TabsNames.append(ImStrv(&zero_c, &zero_c + 1));
|
||||
}
|
||||
|
||||
// Update selected tab
|
||||
@@ -10586,7 +10608,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, ImStrv label, bool* p_open, ImGui
|
||||
// FIXME: We may want disabled tab to still display the tooltip?
|
||||
if (text_clipped && g.HoveredId == id && !held)
|
||||
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
||||
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
||||
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label.Begin), label.Begin);
|
||||
}
|
||||
|
||||
// Restore main window position so user can draw there
|
||||
@@ -10619,7 +10641,7 @@ void ImGui::SetTabItemClosed(ImStrv label)
|
||||
ImVec2 ImGui::TabItemCalcSize(ImStrv label, bool has_close_button_or_unsaved_marker)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
ImVec2 label_size = CalcTextSize(label, true);
|
||||
ImVec2 size = ImVec2(label_size.x + g.Style.FramePadding.x, label_size.y + g.Style.FramePadding.y * 2.0f);
|
||||
if (has_close_button_or_unsaved_marker)
|
||||
size.x += g.Style.FramePadding.x + (g.Style.ItemInnerSpacing.x + g.FontSize); // We use Y intentionally to fit the close button circle.
|
||||
@@ -10664,7 +10686,7 @@ void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabI
|
||||
void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, ImStrv label, ImGuiID tab_id, ImGuiID close_button_id, bool is_contents_visible, bool* out_just_closed, bool* out_text_clipped)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
ImVec2 label_size = CalcTextSize(label);
|
||||
|
||||
if (out_just_closed)
|
||||
*out_just_closed = false;
|
||||
@@ -10749,7 +10771,7 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
}
|
||||
}
|
||||
LogSetNextTextDecoration("/", "\\");
|
||||
RenderTextEllipsis(draw_list, text_ellipsis_clip_bb.Min, text_ellipsis_clip_bb.Max, ellipsis_max_x, label, NULL, &label_size);
|
||||
RenderTextEllipsis(draw_list, text_ellipsis_clip_bb.Min, text_ellipsis_clip_bb.Max, ellipsis_max_x, label, &label_size);
|
||||
|
||||
#if 0
|
||||
if (!is_contents_visible)
|
||||
|
Reference in New Issue
Block a user