mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-28 00:39:02 +08:00
Log depth padding relative to start depth. Tree node and headers looking better when logged to text. Added LogText().
This commit is contained in:
parent
886d954e3d
commit
036a153cf4
85
imgui.cpp
85
imgui.cpp
@ -861,6 +861,7 @@ struct ImGuiState
|
|||||||
bool LogEnabled;
|
bool LogEnabled;
|
||||||
FILE* LogFile;
|
FILE* LogFile;
|
||||||
ImGuiTextBuffer* LogClipboard; // pointer so our GImGui static constructor doesn't call heap allocators.
|
ImGuiTextBuffer* LogClipboard; // pointer so our GImGui static constructor doesn't call heap allocators.
|
||||||
|
int LogStartDepth;
|
||||||
int LogAutoExpandMaxDepth;
|
int LogAutoExpandMaxDepth;
|
||||||
|
|
||||||
ImGuiState()
|
ImGuiState()
|
||||||
@ -887,6 +888,7 @@ struct ImGuiState
|
|||||||
PrivateClipboard = NULL;
|
PrivateClipboard = NULL;
|
||||||
LogEnabled = false;
|
LogEnabled = false;
|
||||||
LogFile = NULL;
|
LogFile = NULL;
|
||||||
|
LogStartDepth = 0;
|
||||||
LogAutoExpandMaxDepth = 2;
|
LogAutoExpandMaxDepth = 2;
|
||||||
LogClipboard = NULL;
|
LogClipboard = NULL;
|
||||||
}
|
}
|
||||||
@ -1158,23 +1160,24 @@ bool ImGuiTextFilter::PassFilter(const char* val) const
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Helper: Text buffer for logging/accumulating text
|
// Helper: Text buffer for logging/accumulating text
|
||||||
void ImGuiTextBuffer::append(const char* fmt, ...)
|
void ImGuiTextBuffer::appendv(const char* fmt, va_list args)
|
||||||
{
|
{
|
||||||
va_list args;
|
int len = vsnprintf(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass.
|
||||||
va_start(args, fmt);
|
|
||||||
int len = vsnprintf(NULL, 0, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const size_t write_off = Buf.size();
|
const size_t write_off = Buf.size();
|
||||||
if (write_off + (size_t)len >= Buf.capacity())
|
if (write_off + (size_t)len >= Buf.capacity())
|
||||||
Buf.reserve(Buf.capacity() * 2);
|
Buf.reserve(Buf.capacity() * 2);
|
||||||
|
|
||||||
Buf.resize(write_off + (size_t)len);
|
Buf.resize(write_off + (size_t)len);
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
ImFormatStringV(&Buf[write_off] - 1, (size_t)len+1, fmt, args);
|
ImFormatStringV(&Buf[write_off] - 1, (size_t)len+1, fmt, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiTextBuffer::append(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
appendv(fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1764,7 +1767,27 @@ static const char* FindTextDisplayEnd(const char* text, const char* text_end =
|
|||||||
return text_display_end;
|
return text_display_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log ImGui display into text output (tty or file or clipboard)
|
// Pass text data straight to log (without being displayed)
|
||||||
|
void ImGui::LogText(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
ImGuiState& g = GImGui;
|
||||||
|
if (!g.LogEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
if (g.LogFile)
|
||||||
|
{
|
||||||
|
vfprintf(g.LogFile, fmt, args);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g.LogClipboard->appendv(fmt, args);
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal version that takes a position to decide on newline placement and pad items according to their depth.
|
||||||
static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end)
|
static void LogText(const ImVec2& ref_pos, const char* text, const char* text_end)
|
||||||
{
|
{
|
||||||
ImGuiState& g = GImGui;
|
ImGuiState& g = GImGui;
|
||||||
@ -1777,7 +1800,9 @@ static void LogText(const ImVec2& ref_pos, const char* text, const char* text_en
|
|||||||
window->DC.LogLineHeight = ref_pos.y;
|
window->DC.LogLineHeight = ref_pos.y;
|
||||||
|
|
||||||
const char* text_remaining = text;
|
const char* text_remaining = text;
|
||||||
const int tree_depth = window->DC.TreeDepth;
|
if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth
|
||||||
|
g.LogStartDepth = window->DC.TreeDepth;
|
||||||
|
const int tree_depth = (window->DC.TreeDepth - g.LogStartDepth);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
const char* line_end = text_remaining;
|
const char* line_end = text_remaining;
|
||||||
@ -1799,20 +1824,10 @@ static void LogText(const ImVec2& ref_pos, const char* text, const char* text_en
|
|||||||
if (line_end != NULL && !(is_last_line && (line_end - text_remaining)==0))
|
if (line_end != NULL && !(is_last_line && (line_end - text_remaining)==0))
|
||||||
{
|
{
|
||||||
const int char_count = (int)(line_end - text_remaining);
|
const int char_count = (int)(line_end - text_remaining);
|
||||||
if (g.LogFile)
|
|
||||||
{
|
|
||||||
if (log_new_line || !is_first_line)
|
if (log_new_line || !is_first_line)
|
||||||
fprintf(g.LogFile, "\n%*s%.*s", tree_depth*4, "", char_count, text_remaining);
|
ImGui::LogText("\n%*s%.*s", tree_depth*4, "", char_count, text_remaining);
|
||||||
else
|
else
|
||||||
fprintf(g.LogFile, " %.*s", char_count, text_remaining);
|
ImGui::LogText(" %.*s", char_count, text_remaining);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (log_new_line || !is_first_line)
|
|
||||||
g.LogClipboard->append("\n%*s%.*s", tree_depth*4, "", char_count, text_remaining);
|
|
||||||
else
|
|
||||||
g.LogClipboard->append(" %.*s", char_count, text_remaining);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_last_line)
|
if (is_last_line)
|
||||||
@ -3434,10 +3449,13 @@ static bool CloseWindowButton(bool* p_opened)
|
|||||||
void ImGui::LogToTTY(int max_depth)
|
void ImGui::LogToTTY(int max_depth)
|
||||||
{
|
{
|
||||||
ImGuiState& g = GImGui;
|
ImGuiState& g = GImGui;
|
||||||
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g.LogEnabled = true;
|
g.LogEnabled = true;
|
||||||
g.LogFile = stdout;
|
g.LogFile = stdout;
|
||||||
|
g.LogStartDepth = window->DC.TreeDepth;
|
||||||
if (max_depth >= 0)
|
if (max_depth >= 0)
|
||||||
g.LogAutoExpandMaxDepth = max_depth;
|
g.LogAutoExpandMaxDepth = max_depth;
|
||||||
}
|
}
|
||||||
@ -3446,12 +3464,15 @@ void ImGui::LogToTTY(int max_depth)
|
|||||||
void ImGui::LogToFile(int max_depth, const char* filename)
|
void ImGui::LogToFile(int max_depth, const char* filename)
|
||||||
{
|
{
|
||||||
ImGuiState& g = GImGui;
|
ImGuiState& g = GImGui;
|
||||||
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
return;
|
return;
|
||||||
if (!filename)
|
if (!filename)
|
||||||
filename = g.IO.LogFilename;
|
filename = g.IO.LogFilename;
|
||||||
|
|
||||||
g.LogEnabled = true;
|
g.LogEnabled = true;
|
||||||
g.LogFile = fopen(filename, "at");
|
g.LogFile = fopen(filename, "at");
|
||||||
|
g.LogStartDepth = window->DC.TreeDepth;
|
||||||
if (max_depth >= 0)
|
if (max_depth >= 0)
|
||||||
g.LogAutoExpandMaxDepth = max_depth;
|
g.LogAutoExpandMaxDepth = max_depth;
|
||||||
}
|
}
|
||||||
@ -3459,11 +3480,14 @@ void ImGui::LogToFile(int max_depth, const char* filename)
|
|||||||
// Start logging ImGui output to clipboard
|
// Start logging ImGui output to clipboard
|
||||||
void ImGui::LogToClipboard(int max_depth)
|
void ImGui::LogToClipboard(int max_depth)
|
||||||
{
|
{
|
||||||
|
ImGuiWindow* window = GetCurrentWindow();
|
||||||
ImGuiState& g = GImGui;
|
ImGuiState& g = GImGui;
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g.LogEnabled = true;
|
g.LogEnabled = true;
|
||||||
g.LogFile = NULL;
|
g.LogFile = NULL;
|
||||||
|
g.LogStartDepth = window->DC.TreeDepth;
|
||||||
if (max_depth >= 0)
|
if (max_depth >= 0)
|
||||||
g.LogAutoExpandMaxDepth = max_depth;
|
g.LogAutoExpandMaxDepth = max_depth;
|
||||||
}
|
}
|
||||||
@ -3473,10 +3497,11 @@ void ImGui::LogFinish()
|
|||||||
ImGuiState& g = GImGui;
|
ImGuiState& g = GImGui;
|
||||||
if (!g.LogEnabled)
|
if (!g.LogEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ImGui::LogText("\n");
|
||||||
g.LogEnabled = false;
|
g.LogEnabled = false;
|
||||||
if (g.LogFile != NULL)
|
if (g.LogFile != NULL)
|
||||||
{
|
{
|
||||||
fprintf(g.LogFile, "\n");
|
|
||||||
if (g.LogFile == stdout)
|
if (g.LogFile == stdout)
|
||||||
fflush(g.LogFile);
|
fflush(g.LogFile);
|
||||||
else
|
else
|
||||||
@ -3485,7 +3510,6 @@ void ImGui::LogFinish()
|
|||||||
}
|
}
|
||||||
if (g.LogClipboard->size() > 1)
|
if (g.LogClipboard->size() > 1)
|
||||||
{
|
{
|
||||||
g.LogClipboard->append("\n");
|
|
||||||
if (g.IO.SetClipboardTextFn)
|
if (g.IO.SetClipboardTextFn)
|
||||||
g.IO.SetClipboardTextFn(g.LogClipboard->begin());
|
g.IO.SetClipboardTextFn(g.LogClipboard->begin());
|
||||||
g.LogClipboard->clear();
|
g.LogClipboard->clear();
|
||||||
@ -3591,7 +3615,18 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, const bool d
|
|||||||
// Framed type
|
// Framed type
|
||||||
RenderFrame(bb.Min, bb.Max, col, true);
|
RenderFrame(bb.Min, bb.Max, col, true);
|
||||||
RenderCollapseTriangle(bb.Min + style.FramePadding, opened, 1.0f, true);
|
RenderCollapseTriangle(bb.Min + style.FramePadding, opened, 1.0f, true);
|
||||||
|
if (g.LogEnabled)
|
||||||
|
{
|
||||||
|
// 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[] = "\n##";
|
||||||
|
LogText(bb.Min + style.FramePadding, log_prefix, log_prefix+3);
|
||||||
|
}
|
||||||
RenderText(bb.Min + style.FramePadding + ImVec2(window->FontSize() + style.FramePadding.x*2,0), label);
|
RenderText(bb.Min + style.FramePadding + ImVec2(window->FontSize() + style.FramePadding.x*2,0), label);
|
||||||
|
if (g.LogEnabled)
|
||||||
|
{
|
||||||
|
const char log_suffix[] = "##";
|
||||||
|
LogText(bb.Min + style.FramePadding, log_suffix, log_suffix+2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3599,6 +3634,8 @@ bool ImGui::CollapsingHeader(const char* label, const char* str_id, const bool d
|
|||||||
if ((held && hovered) || hovered)
|
if ((held && hovered) || hovered)
|
||||||
RenderFrame(bb.Min, bb.Max, col, false);
|
RenderFrame(bb.Min, bb.Max, col, false);
|
||||||
RenderCollapseTriangle(bb.Min + ImVec2(style.FramePadding.x, window->FontSize()*0.15f), opened, 0.70f, false);
|
RenderCollapseTriangle(bb.Min + ImVec2(style.FramePadding.x, window->FontSize()*0.15f), opened, 0.70f, false);
|
||||||
|
if (g.LogEnabled)
|
||||||
|
LogText(bb.Min, ">");
|
||||||
RenderText(bb.Min + ImVec2(window->FontSize() + style.FramePadding.x*2,0), label);
|
RenderText(bb.Min + ImVec2(window->FontSize() + style.FramePadding.x*2,0), label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
imgui.h
2
imgui.h
@ -286,6 +286,7 @@ namespace ImGui
|
|||||||
IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard
|
IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard
|
||||||
IMGUI_API void LogFinish(); // stop logging (close file, etc.)
|
IMGUI_API void LogFinish(); // stop logging (close file, etc.)
|
||||||
IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard
|
IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard
|
||||||
|
IMGUI_API void LogText(const char* fmt, ...); // pass text data straight to log (without being displayed)
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
IMGUI_API bool IsItemHovered(); // was the last item active area hovered by mouse?
|
IMGUI_API bool IsItemHovered(); // was the last item active area hovered by mouse?
|
||||||
@ -605,6 +606,7 @@ struct ImGuiTextBuffer
|
|||||||
bool empty() { return Buf.empty(); }
|
bool empty() { return Buf.empty(); }
|
||||||
void clear() { Buf.clear(); Buf.push_back(0); }
|
void clear() { Buf.clear(); Buf.push_back(0); }
|
||||||
IMGUI_API void append(const char* fmt, ...);
|
IMGUI_API void append(const char* fmt, ...);
|
||||||
|
IMGUI_API void appendv(const char* fmt, va_list args);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper: Key->value storage
|
// Helper: Key->value storage
|
||||||
|
Loading…
Reference in New Issue
Block a user