Debug Tools: Debug Log: add and use ImGuiTextLineIndex.

This is needed for next commit where we want to parse hovered Debug Log line.
This commit is contained in:
ocornut 2022-10-21 18:55:47 +02:00
parent 578df14f27
commit 178aee4b1c
2 changed files with 47 additions and 3 deletions

View File

@ -65,7 +65,7 @@ CODE
// [SECTION] MISC HELPERS/UTILITIES (Color functions)
// [SECTION] ImGuiStorage
// [SECTION] ImGuiTextFilter
// [SECTION] ImGuiTextBuffer
// [SECTION] ImGuiTextBuffer, ImGuiTextIndex
// [SECTION] ImGuiListClipper
// [SECTION] STYLING
// [SECTION] RENDER HELPERS
@ -2457,7 +2457,7 @@ bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
}
//-----------------------------------------------------------------------------
// [SECTION] ImGuiTextBuffer
// [SECTION] ImGuiTextBuffer, ImGuiTextIndex
//-----------------------------------------------------------------------------
// On some platform vsnprintf() takes va_list by reference and modifies it.
@ -2525,6 +2525,20 @@ void ImGuiTextBuffer::appendfv(const char* fmt, va_list args)
va_end(args_copy);
}
void ImGuiTextIndex::append(const char* base, int old_size, int new_size)
{
IM_ASSERT(old_size >= 0 && new_size >= old_size && new_size >= EndOffset);
if (old_size == new_size)
return;
if (EndOffset == 0 || base[EndOffset - 1] == '\n')
LineOffsets.push_back(EndOffset);
const char* base_end = base + new_size;
for (const char* p = base + old_size; (p = (const char*)memchr(p, '\n', base_end - p)) != 0; )
if (++p < base_end) // Don't push a trailing offset on last \n
LineOffsets.push_back((int)(intptr_t)(p - base));
EndOffset = ImMax(EndOffset, new_size);
}
//-----------------------------------------------------------------------------
// [SECTION] ImGuiListClipper
// This is currently not as flexible/powerful as it should be and really confusing/spaghetti, mostly because we changed
@ -4798,6 +4812,7 @@ void ImGui::Shutdown()
}
g.LogBuffer.clear();
g.DebugLogBuf.clear();
g.DebugLogIndex.clear();
g.Initialized = false;
}
@ -13430,6 +13445,7 @@ void ImGui::DebugLogV(const char* fmt, va_list args)
g.DebugLogBuf.appendfv(fmt, args);
if (g.DebugLogFlags & ImGuiDebugLogFlags_OutputToTTY)
IMGUI_DEBUG_PRINTF("%s", g.DebugLogBuf.begin() + old_size);
g.DebugLogIndex.append(g.DebugLogBuf.c_str(), old_size, g.DebugLogBuf.size());
}
void ImGui::ShowDebugLogWindow(bool* p_open)
@ -13454,12 +13470,24 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
SameLine(); CheckboxFlags("IO", &g.DebugLogFlags, ImGuiDebugLogFlags_EventIO);
if (SmallButton("Clear"))
{
g.DebugLogBuf.clear();
g.DebugLogIndex.clear();
}
SameLine();
if (SmallButton("Copy"))
SetClipboardText(g.DebugLogBuf.c_str());
BeginChild("##log", ImVec2(0.0f, 0.0f), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar);
TextUnformatted(g.DebugLogBuf.begin(), g.DebugLogBuf.end()); // FIXME-OPT: Could use a line index, but TextUnformatted() has a semi-decent fast path for large text.
ImGuiListClipper clipper;
clipper.Begin(g.DebugLogIndex.size());
while (clipper.Step())
for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++)
{
const char* line_begin = g.DebugLogIndex.get_line_begin(g.DebugLogBuf.c_str(), line_no);
const char* line_end = g.DebugLogIndex.get_line_end(g.DebugLogBuf.c_str(), line_no);
TextUnformatted(line_begin, line_end);
}
if (GetScrollY() >= GetScrollMaxY())
SetScrollHereY(1.0f);
EndChild();

View File

@ -302,6 +302,7 @@ namespace ImStb
// - Helper: ImSpan<>, ImSpanAllocator<>
// - Helper: ImPool<>
// - Helper: ImChunkStream<>
// - Helper: ImGuiTextIndex
//-----------------------------------------------------------------------------
// Helpers: Hashing
@ -694,6 +695,20 @@ struct ImChunkStream
};
// Helper: ImGuiTextIndex<>
// Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API.
struct ImGuiTextIndex
{
ImVector<int> LineOffsets;
int EndOffset = 0; // Because we don't own text buffer we need to maintain EndOffset (may bake in LineOffsets?)
void clear() { LineOffsets.clear(); EndOffset = 0; }
int size() { return LineOffsets.Size; }
const char* get_line_begin(const char* base, int n) { return base + LineOffsets[n]; }
const char* get_line_end(const char* base, int n) { return base + (n + 1 < LineOffsets.Size ? (LineOffsets[n + 1] - 1) : EndOffset); }
void append(const char* base, int old_size, int new_size);
};
//-----------------------------------------------------------------------------
// [SECTION] ImDrawList support
//-----------------------------------------------------------------------------
@ -1850,6 +1865,7 @@ struct ImGuiContext
// Debug Tools
ImGuiDebugLogFlags DebugLogFlags;
ImGuiTextBuffer DebugLogBuf;
ImGuiTextIndex DebugLogIndex;
bool DebugItemPickerActive; // Item picker is active (started with DebugStartItemPicker())
ImU8 DebugItemPickerMouseButton;
ImGuiID DebugItemPickerBreakId; // Will call IM_DEBUG_BREAK() when encountering this ID