1
0
mirror of https://github.com/ocornut/imgui.git synced 2024-12-01 02:37:24 +01:00

Log/Capture: Fixes for handling \n in strings. Improve the look of various widgets. Added LogSetNextTextDecoration helper. Fixup/amend dbaf74d75.

For now removed LogRenderedTextNewLine() - it is eventually desirable but currently carries too much ambiguities, so reverted until we have a better system and test suite.
This commit is contained in:
ocornut 2021-02-02 09:42:23 +01:00
parent dbaf74d758
commit 929563c3a7
6 changed files with 87 additions and 71 deletions

View File

@ -30,15 +30,6 @@ HOW TO UPDATE?
and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users. and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users.
- Please report any issue! - Please report any issue!
-----------------------------------------------------------------------
VERSION 1.81 (In Progress)
-----------------------------------------------------------------------
Other Changes:
- Log/Capture: Fix various new line/spacing issue by using same render text position when there are both
RenderText and LogRenderedText call in widget code.
Also Buttons are now enclosed in bracket. [@Xipiryon]
----------------------------------------------------------------------- -----------------------------------------------------------------------
VERSION 1.81 WIP (In Progress) VERSION 1.81 WIP (In Progress)
@ -71,6 +62,8 @@ Other Changes:
to have enough space when provided width precisely calculated with CalcTextSize().x. (#3776) to have enough space when provided width precisely calculated with CalcTextSize().x. (#3776)
Note that the rounding of either positions and widths are technically undesirable (e.g. #3437, #791) but Note that the rounding of either positions and widths are technically undesirable (e.g. #3437, #791) but
variety of code is currently on it so we are first fixing current behavior before we'll eventually change it. variety of code is currently on it so we are first fixing current behavior before we'll eventually change it.
- Log/Capture: Fix various new line/spacing issue when logging widgets. [@Xipiryon, @ocornut]
- Log/Capture: Improved the ascii look of various widgets, making large dumps more easily human readable.
- ImDrawList: Fixed AddCircle()/AddCircleFilled() with (rad > 0.0f && rad < 1.0f && num_segments == 0). (#3738) - ImDrawList: Fixed AddCircle()/AddCircleFilled() with (rad > 0.0f && rad < 1.0f && num_segments == 0). (#3738)
Would lead to a buffer read overflow. Would lead to a buffer read overflow.
- Backends: Win32: Dynamically loading XInput DLL instead of linking with it, facilite compiling with - Backends: Win32: Dynamically loading XInput DLL instead of linking with it, facilite compiling with

View File

@ -247,12 +247,14 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners. - style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners.
- style editor: color child window height expressed in multiple of line height. - style editor: color child window height expressed in multiple of line height.
- log: improve logging of ArrowButton, ListBox, TabItem
- log: carry on indent / tree depth when opening a child window
- log: enabling log ends up pushing and growing vertices buffers because we don't distinguish layout vs render clipping
- log: have more control over the log scope (e.g. stop logging when leaving current tree node scope) - log: have more control over the log scope (e.g. stop logging when leaving current tree node scope)
- log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard) - log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard)
- log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs. - log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs.
- log: obsolete LogButtons() all together. - log: obsolete LogButtons() all together.
- log: LogButtons() options for specifying depth and/or hiding depth slider - log: LogButtons() options for specifying depth and/or hiding depth slider
- log: enabling log ends up pushing and growing vertices buffersbecause we don't distinguish layout vs render clipping
- filters: set a current filter that tree node can automatically query to hide themselves - filters: set a current filter that tree node can automatically query to hide themselves
- filters: handle wild-cards (with implicit leading/trailing *), reg-exprs - filters: handle wild-cards (with implicit leading/trailing *), reg-exprs

View File

@ -4944,6 +4944,7 @@ void ImGui::EndChild()
} }
} }
g.WithinEndChild = false; g.WithinEndChild = false;
g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
} }
// Helper to create a child window / scrolling region that looks like a normal widget frame. // Helper to create a child window / scrolling region that looks like a normal widget frame.
@ -7572,7 +7573,7 @@ void ImGui::BeginGroup()
window->DC.CursorMaxPos = window->DC.CursorPos; window->DC.CursorMaxPos = window->DC.CursorPos;
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f); window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
if (g.LogEnabled) if (g.LogEnabled)
LogRenderedTextNewLine(); g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
} }
void ImGui::EndGroup() void ImGui::EndGroup()
@ -7593,7 +7594,7 @@ void ImGui::EndGroup()
window->DC.CurrLineSize = group_data.BackupCurrLineSize; window->DC.CurrLineSize = group_data.BackupCurrLineSize;
window->DC.CurrLineTextBaseOffset = group_data.BackupCurrLineTextBaseOffset; window->DC.CurrLineTextBaseOffset = group_data.BackupCurrLineTextBaseOffset;
if (g.LogEnabled) if (g.LogEnabled)
LogRenderedTextNewLine(); g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
if (!group_data.EmitItem) if (!group_data.EmitItem)
{ {
@ -9859,11 +9860,16 @@ void ImGui::LogText(const char* fmt, ...)
// Internal version that takes a position to decide on newline placement and pad items according to their depth. // Internal version that takes a position to decide on newline placement and pad items according to their depth.
// We split text into individual lines to add current tree level padding // We split text into individual lines to add current tree level padding
// FIXME: This code is a little complicated perhaps, considering simplifying the whole system.
void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end) void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
const char* prefix = g.LogNextPrefix;
const char* suffix = g.LogNextSuffix;
g.LogNextPrefix = g.LogNextSuffix = NULL;
if (!text_end) if (!text_end)
text_end = FindRenderedTextEnd(text, text_end); text_end = FindRenderedTextEnd(text, text_end);
@ -9871,52 +9877,46 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char*
if (ref_pos) if (ref_pos)
g.LogLinePosY = ref_pos->y; g.LogLinePosY = ref_pos->y;
if (log_new_line) if (log_new_line)
{
LogText(IM_NEWLINE);
g.LogLineFirstItem = true; g.LogLineFirstItem = true;
}
const char* text_remaining = text; if (prefix)
if (g.LogDepthRef > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth LogRenderedText(ref_pos, prefix, prefix + strlen(prefix)); // Calculate end ourself to ensure "##" are included here.
// Re-adjust padding if we have popped out of our starting depth
if (g.LogDepthRef > window->DC.TreeDepth)
g.LogDepthRef = window->DC.TreeDepth; g.LogDepthRef = window->DC.TreeDepth;
const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef); const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef);
const char* text_remaining = text;
for (;;) for (;;)
{ {
// Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry. // Split the string. Each new line (after a '\n') is followed by indentation corresponding to the current depth of our log entry.
// We don't add a trailing \n to allow a subsequent item on the same line to be captured. // We don't add a trailing \n yet to allow a subsequent item on the same line to be captured.
const char* line_start = text_remaining; const char* line_start = text_remaining;
const char* line_end = ImStreolRange(line_start, text_end); const char* line_end = ImStreolRange(line_start, text_end);
const bool is_first_line = (line_start == text);
const bool is_last_line = (line_end == text_end); const bool is_last_line = (line_end == text_end);
if (!is_last_line || (line_start != line_end)) if (line_start != line_end || !is_last_line)
{ {
const int char_count = (int)(line_end - line_start); const int line_length = (int)(line_end - line_start);
if (log_new_line || !is_first_line) const int indentation = g.LogLineFirstItem ? tree_depth * 4 : 1;
LogText(IM_NEWLINE "%*s%.*s", tree_depth * 4, "", char_count, line_start); LogText("%*s%.*s", indentation, "", line_length, line_start);
else if (g.LogLineFirstItem)
LogText("%*s%.*s", tree_depth * 4, "", char_count, line_start);
else
LogText(" %.*s", char_count, line_start);
g.LogLineFirstItem = false; g.LogLineFirstItem = false;
if (*line_end == '\n') if (*line_end == '\n')
LogRenderedTextNewLine();
}
else if (log_new_line)
{ {
// An empty "" string at a different Y position should output a carriage return.
LogText(IM_NEWLINE); LogText(IM_NEWLINE);
break; g.LogLineFirstItem = true;
}
} }
if (is_last_line) if (is_last_line)
break; break;
text_remaining = line_end + 1; text_remaining = line_end + 1;
} }
}
void ImGui::LogRenderedTextNewLine() if (suffix)
{ LogRenderedText(ref_pos, suffix, suffix + strlen(suffix));
// To enforce Log carriage return
ImGuiContext& g = *GImGui;
g.LogLinePosY = -FLT_MAX;
} }
// Start logging/capturing text output // Start logging/capturing text output
@ -9929,12 +9929,21 @@ void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth)
IM_ASSERT(g.LogBuffer.empty()); IM_ASSERT(g.LogBuffer.empty());
g.LogEnabled = true; g.LogEnabled = true;
g.LogType = type; g.LogType = type;
g.LogNextPrefix = g.LogNextSuffix = NULL;
g.LogDepthRef = window->DC.TreeDepth; g.LogDepthRef = window->DC.TreeDepth;
g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault); g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault);
g.LogLinePosY = FLT_MAX; g.LogLinePosY = FLT_MAX;
g.LogLineFirstItem = true; g.LogLineFirstItem = true;
} }
// Important: doesn't copy underlying data, use carefully (prefix/suffix must be in scope at the time of the next LogRenderedText)
void ImGui::LogSetNextTextDecoration(const char* prefix, const char* suffix)
{
ImGuiContext& g = *GImGui;
g.LogNextPrefix = prefix;
g.LogNextSuffix = suffix;
}
void ImGui::LogToTTY(int auto_open_depth) void ImGui::LogToTTY(int auto_open_depth)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;

View File

@ -1469,6 +1469,8 @@ struct ImGuiContext
ImGuiLogType LogType; // Capture target ImGuiLogType LogType; // Capture target
ImFileHandle LogFile; // If != NULL log to stdout/ file ImFileHandle LogFile; // If != NULL log to stdout/ file
ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators.
const char* LogNextPrefix;
const char* LogNextSuffix;
float LogLinePosY; float LogLinePosY;
bool LogLineFirstItem; bool LogLineFirstItem;
int LogDepthRef; int LogDepthRef;
@ -1620,6 +1622,7 @@ struct ImGuiContext
LogEnabled = false; LogEnabled = false;
LogType = ImGuiLogType_None; LogType = ImGuiLogType_None;
LogNextPrefix = LogNextSuffix = NULL;
LogFile = NULL; LogFile = NULL;
LogLinePosY = FLT_MAX; LogLinePosY = FLT_MAX;
LogLineFirstItem = false; LogLineFirstItem = false;
@ -2253,6 +2256,8 @@ namespace ImGui
// Logging/Capture // Logging/Capture
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name. IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer
IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL);
IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix);
// Popups, Modals, Tooltips // Popups, Modals, Tooltips
IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags); IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags);
@ -2391,8 +2396,6 @@ namespace ImGui
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0); IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0);
IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL);
IMGUI_API void LogRenderedTextNewLine();
// Render helpers (those functions don't access any ImGui state!) // Render helpers (those functions don't access any ImGui state!)
IMGUI_API void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir dir, float scale = 1.0f); IMGUI_API void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir dir, float scale = 1.0f);

View File

@ -1654,6 +1654,10 @@ void ImGui::TableEndRow(ImGuiTable* table)
if (table->CurrentColumn != -1) if (table->CurrentColumn != -1)
TableEndCell(table); TableEndCell(table);
// Logging
if (g.LogEnabled)
LogRenderedText(NULL, "|");
// Position cursor at the bottom of our row so it can be used for e.g. clipping calculation. However it is // Position cursor at the bottom of our row so it can be used for e.g. clipping calculation. However it is
// likely that the next call to TableBeginCell() will reposition the cursor to take account of vertical padding. // likely that the next call to TableBeginCell() will reposition the cursor to take account of vertical padding.
window->DC.CursorPos.y = table->RowPosY2; window->DC.CursorPos.y = table->RowPosY2;
@ -1890,6 +1894,14 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
SetWindowClipRectBeforeSetChannel(window, column->ClipRect); SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
table->DrawSplitter.SetCurrentChannel(window->DrawList, column->DrawChannelCurrent); table->DrawSplitter.SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
} }
// Logging
ImGuiContext& g = *GImGui;
if (g.LogEnabled && !column->IsSkipItems)
{
LogRenderedText(&window->DC.CursorPos, "|");
g.LogLinePosY = FLT_MAX;
}
} }
// [Internal] Called by TableNextRow()/TableSetColumnIndex()/TableNextColumn() // [Internal] Called by TableNextRow()/TableSetColumnIndex()/TableNextColumn()

View File

@ -693,12 +693,9 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
RenderNavHighlight(bb, id); RenderNavHighlight(bb, id);
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
ImRect render_text_pos = ImRect(bb.Min + style.FramePadding, bb.Max - style.FramePadding);
if (g.LogEnabled) if (g.LogEnabled)
LogRenderedText(&render_text_pos.Min, "["); LogSetNextTextDecoration("[", "]");
RenderTextClipped(render_text_pos.Min, render_text_pos.Max ,label, NULL, &label_size, style.ButtonTextAlign, &bb); RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb);
if (g.LogEnabled)
LogRenderedText(&render_text_pos.Min, "]");
// Automatically close popups // Automatically close popups
//if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup)) //if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
@ -1103,12 +1100,11 @@ bool ImGui::Checkbox(const char* label, bool* v)
RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f); RenderCheckMark(window->DrawList, check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad * 2.0f);
} }
ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
ImVec2 render_text_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
if (g.LogEnabled) if (g.LogEnabled)
LogRenderedText(&render_text_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]"); LogRenderedText(&label_pos, mixed_value ? "[~]" : *v ? "[x]" : "[ ]");
if (label_size.x > 0.0f) if (label_size.x > 0.0f)
RenderText(render_text_pos, label); RenderText(label_pos, label);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0)); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return pressed; return pressed;
@ -1206,11 +1202,11 @@ bool ImGui::RadioButton(const char* label, bool active)
window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize); window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize);
} }
ImVec2 render_text_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y); ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y);
if (g.LogEnabled) if (g.LogEnabled)
LogRenderedText(&render_text_pos, active ? "(x)" : "( )"); LogRenderedText(&label_pos, active ? "(x)" : "( )");
if (label_size.x > 0.0f) if (label_size.x > 0.0f)
RenderText(render_text_pos, label); RenderText(label_pos, label);
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags); IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags);
return pressed; return pressed;
@ -1394,10 +1390,7 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
// Draw // Draw
window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator)); window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator));
if (g.LogEnabled) if (g.LogEnabled)
{ LogRenderedText(&bb.Min, "--------------------------------\n");
LogRenderedText(&bb.Min, "--------------------------------");
LogRenderedTextNewLine(); // Separator isn't tall enough to trigger a new line automatically in LogRenderText
}
} }
if (columns) if (columns)
@ -1589,7 +1582,12 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
} }
RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding); RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding);
if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview)) if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview))
RenderTextClipped(frame_bb.Min + style.FramePadding, ImVec2(value_x2, frame_bb.Max.y), preview_value, NULL, NULL, ImVec2(0.0f, 0.0f)); {
ImVec2 preview_pos = frame_bb.Min + style.FramePadding;
if (g.LogEnabled)
LogSetNextTextDecoration("{", "}");
RenderTextClipped(preview_pos, ImVec2(value_x2, frame_bb.Max.y), preview_value, NULL, NULL, ImVec2(0.0f, 0.0f));
}
if (label_size.x > 0) if (label_size.x > 0)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
@ -2339,6 +2337,8 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value. // Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
char value_buf[64]; char value_buf[64];
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format); 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, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
if (label_size.x > 0.0f) if (label_size.x > 0.0f)
@ -2951,6 +2951,8 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value. // Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
char value_buf[64]; char value_buf[64];
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, p_data, format); 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, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
if (label_size.x > 0.0f) if (label_size.x > 0.0f)
@ -4602,7 +4604,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Log as text // Log as text
if (g.LogEnabled && (!is_password || is_displaying_hint)) if (g.LogEnabled && (!is_password || is_displaying_hint))
{
LogSetNextTextDecoration("{", "}");
LogRenderedText(&draw_pos, buf_display, buf_display_end); LogRenderedText(&draw_pos, buf_display, buf_display_end);
}
if (label_size.x > 0) if (label_size.x > 0)
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
@ -5809,18 +5814,10 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
text_pos.x -= text_offset_x; text_pos.x -= text_offset_x;
if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton) if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton)
frame_bb.Max.x -= g.FontSize + style.FramePadding.x; frame_bb.Max.x -= g.FontSize + style.FramePadding.x;
if (g.LogEnabled) if (g.LogEnabled)
{ LogSetNextTextDecoration("###", "###");
// NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here.
const char log_prefix[] = "##";
LogRenderedText(&text_pos, log_prefix, log_prefix + 2);
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size); RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
LogRenderedText(&text_pos, log_prefix, log_prefix + 2);
}
else
{
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
}
} }
else else
{ {
@ -5836,7 +5833,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
else if (!is_leaf) else if (!is_leaf)
RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f); RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
if (g.LogEnabled) if (g.LogEnabled)
LogRenderedText(&text_pos, ">"); LogSetNextTextDecoration(">", NULL);
RenderText(text_pos, label, label_end, false); RenderText(text_pos, label, label_end, false);
} }