mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-11-04 07:01:04 +01:00 
			
		
		
		
	Moved Logging/Capturing section above Docking to facilitate master<>docking merges.
This commit is contained in:
		
							
								
								
									
										402
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										402
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -73,8 +73,8 @@ CODE
 | 
				
			|||||||
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION
 | 
					// [SECTION] KEYBOARD/GAMEPAD NAVIGATION
 | 
				
			||||||
// [SECTION] COLUMNS
 | 
					// [SECTION] COLUMNS
 | 
				
			||||||
// [SECTION] DRAG AND DROP
 | 
					// [SECTION] DRAG AND DROP
 | 
				
			||||||
// [SECTION] DOCKING
 | 
					 | 
				
			||||||
// [SECTION] LOGGING/CAPTURING
 | 
					// [SECTION] LOGGING/CAPTURING
 | 
				
			||||||
 | 
					// [SECTION] DOCKING
 | 
				
			||||||
// [SECTION] SETTINGS
 | 
					// [SECTION] SETTINGS
 | 
				
			||||||
// [SECTION] PLATFORM DEPENDENT HELPERS
 | 
					// [SECTION] PLATFORM DEPENDENT HELPERS
 | 
				
			||||||
// [SECTION] METRICS/DEBUG WINDOW
 | 
					// [SECTION] METRICS/DEBUG WINDOW
 | 
				
			||||||
@@ -10100,6 +10100,207 @@ void ImGui::EndDragDropTarget()
 | 
				
			|||||||
    g.DragDropWithinSourceOrTarget = false;
 | 
					    g.DragDropWithinSourceOrTarget = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// [SECTION] LOGGING/CAPTURING
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					// All text output from the interface can be captured into tty/file/clipboard. 
 | 
				
			||||||
 | 
					// By default, tree nodes are automatically opened during logging.
 | 
				
			||||||
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Pass text data straight to log (without being displayed)
 | 
				
			||||||
 | 
					void ImGui::LogText(const char* fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
 | 
					    if (!g.LogEnabled)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    va_list args;
 | 
				
			||||||
 | 
					    va_start(args, fmt);
 | 
				
			||||||
 | 
					    if (g.LogFile)
 | 
				
			||||||
 | 
					        vfprintf(g.LogFile, fmt, args);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        g.LogBuffer.appendfv(fmt, args);
 | 
				
			||||||
 | 
					    va_end(args);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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
 | 
				
			||||||
 | 
					void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
 | 
					    ImGuiWindow* window = g.CurrentWindow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!text_end)
 | 
				
			||||||
 | 
					        text_end = FindRenderedTextEnd(text, text_end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + 1);
 | 
				
			||||||
 | 
					    if (ref_pos)
 | 
				
			||||||
 | 
					        g.LogLinePosY = ref_pos->y;
 | 
				
			||||||
 | 
					    if (log_new_line)
 | 
				
			||||||
 | 
					        g.LogLineFirstItem = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const char* text_remaining = text;
 | 
				
			||||||
 | 
					    if (g.LogDepthRef > window->DC.TreeDepth)  // Re-adjust padding if we have popped out of our starting depth
 | 
				
			||||||
 | 
					        g.LogDepthRef = window->DC.TreeDepth;
 | 
				
			||||||
 | 
					    const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef);
 | 
				
			||||||
 | 
					    for (;;)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Split the string. Each new line (after a '\n') is followed by spacing 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.
 | 
				
			||||||
 | 
					        const char* line_start = text_remaining;
 | 
				
			||||||
 | 
					        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);
 | 
				
			||||||
 | 
					        if (!is_last_line || (line_start != line_end))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            const int char_count = (int)(line_end - line_start);
 | 
				
			||||||
 | 
					            if (log_new_line || !is_first_line)
 | 
				
			||||||
 | 
					                LogText(IM_NEWLINE "%*s%.*s", tree_depth * 4, "", char_count, 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;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (log_new_line)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // An empty "" string at a different Y position should output a carriage return.
 | 
				
			||||||
 | 
					            LogText(IM_NEWLINE);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (is_last_line)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        text_remaining = line_end + 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Start logging/capturing text output
 | 
				
			||||||
 | 
					void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
 | 
					    ImGuiWindow* window = g.CurrentWindow;
 | 
				
			||||||
 | 
					    IM_ASSERT(g.LogEnabled == false);
 | 
				
			||||||
 | 
					    IM_ASSERT(g.LogFile == NULL);
 | 
				
			||||||
 | 
					    IM_ASSERT(g.LogBuffer.empty());
 | 
				
			||||||
 | 
					    g.LogEnabled = true;
 | 
				
			||||||
 | 
					    g.LogType = type;
 | 
				
			||||||
 | 
					    g.LogDepthRef = window->DC.TreeDepth;
 | 
				
			||||||
 | 
					    g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault);
 | 
				
			||||||
 | 
					    g.LogLinePosY = FLT_MAX;
 | 
				
			||||||
 | 
					    g.LogLineFirstItem = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ImGui::LogToTTY(int auto_open_depth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
 | 
					    if (g.LogEnabled)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    LogBegin(ImGuiLogType_TTY, auto_open_depth);
 | 
				
			||||||
 | 
					    g.LogFile = stdout;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Start logging/capturing text output to given file
 | 
				
			||||||
 | 
					void ImGui::LogToFile(int auto_open_depth, const char* filename)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
 | 
					    if (g.LogEnabled)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // FIXME: We could probably open the file in text mode "at", however note that clipboard/buffer logging will still 
 | 
				
			||||||
 | 
					    // be subject to outputting OS-incompatible carriage return if within strings the user doesn't use IM_NEWLINE.
 | 
				
			||||||
 | 
					    // By opening the file in binary mode "ab" we have consistent output everywhere.
 | 
				
			||||||
 | 
					    if (!filename)
 | 
				
			||||||
 | 
					        filename = g.IO.LogFilename;
 | 
				
			||||||
 | 
					    if (!filename || !filename[0])
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    FILE* f = ImFileOpen(filename, "ab");
 | 
				
			||||||
 | 
					    if (f == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        IM_ASSERT(0);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LogBegin(ImGuiLogType_File, auto_open_depth);
 | 
				
			||||||
 | 
					    g.LogFile = f;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Start logging/capturing text output to clipboard
 | 
				
			||||||
 | 
					void ImGui::LogToClipboard(int auto_open_depth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
 | 
					    if (g.LogEnabled)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    LogBegin(ImGuiLogType_Clipboard, auto_open_depth);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ImGui::LogToBuffer(int auto_open_depth)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
 | 
					    if (g.LogEnabled)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    LogBegin(ImGuiLogType_Buffer, auto_open_depth);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ImGui::LogFinish()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
 | 
					    if (!g.LogEnabled)
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LogText(IM_NEWLINE);
 | 
				
			||||||
 | 
					    switch (g.LogType)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    case ImGuiLogType_TTY:
 | 
				
			||||||
 | 
					        fflush(g.LogFile);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ImGuiLogType_File:
 | 
				
			||||||
 | 
					        fclose(g.LogFile);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ImGuiLogType_Buffer:
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ImGuiLogType_Clipboard:
 | 
				
			||||||
 | 
					        if (!g.LogBuffer.empty())
 | 
				
			||||||
 | 
					            SetClipboardText(g.LogBuffer.begin());
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case ImGuiLogType_None:
 | 
				
			||||||
 | 
					        IM_ASSERT(0);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g.LogEnabled = false;
 | 
				
			||||||
 | 
					    g.LogType = ImGuiLogType_None;
 | 
				
			||||||
 | 
					    g.LogFile = NULL;
 | 
				
			||||||
 | 
					    g.LogBuffer.clear();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Helper to display logging buttons
 | 
				
			||||||
 | 
					// FIXME-OBSOLETE: We should probably obsolete this and let the user have their own helper (this is one of the oldest function alive!)
 | 
				
			||||||
 | 
					void ImGui::LogButtons()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ImGuiContext& g = *GImGui;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PushID("LogButtons");
 | 
				
			||||||
 | 
					    const bool log_to_tty = Button("Log To TTY"); SameLine();
 | 
				
			||||||
 | 
					    const bool log_to_file = Button("Log To File"); SameLine();
 | 
				
			||||||
 | 
					    const bool log_to_clipboard = Button("Log To Clipboard"); SameLine();
 | 
				
			||||||
 | 
					    PushItemWidth(80.0f);
 | 
				
			||||||
 | 
					    PushAllowKeyboardFocus(false);
 | 
				
			||||||
 | 
					    SliderInt("Default Depth", &g.LogDepthToExpandDefault, 0, 9, NULL);
 | 
				
			||||||
 | 
					    PopAllowKeyboardFocus();
 | 
				
			||||||
 | 
					    PopItemWidth();
 | 
				
			||||||
 | 
					    PopID();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Start logging at the end of the function so that the buttons don't appear in the log
 | 
				
			||||||
 | 
					    if (log_to_tty)
 | 
				
			||||||
 | 
					        LogToTTY();
 | 
				
			||||||
 | 
					    if (log_to_file)
 | 
				
			||||||
 | 
					        LogToFile();
 | 
				
			||||||
 | 
					    if (log_to_clipboard)
 | 
				
			||||||
 | 
					        LogToClipboard();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//-----------------------------------------------------------------------------
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
// [SECTION] DOCKING
 | 
					// [SECTION] DOCKING
 | 
				
			||||||
//-----------------------------------------------------------------------------
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
@@ -13194,205 +13395,6 @@ static void ImGui::DockSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettings
 | 
				
			|||||||
    buf->appendf("\n");
 | 
					    buf->appendf("\n");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//-----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// [SECTION] LOGGING/CAPTURING
 | 
					 | 
				
			||||||
//-----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// All text output from the interface can be captured into tty/file/clipboard. 
 | 
					 | 
				
			||||||
// By default, tree nodes are automatically opened during logging.
 | 
					 | 
				
			||||||
//-----------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Pass text data straight to log (without being displayed)
 | 
					 | 
				
			||||||
void ImGui::LogText(const char* fmt, ...)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					 | 
				
			||||||
    if (!g.LogEnabled)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    va_list args;
 | 
					 | 
				
			||||||
    va_start(args, fmt);
 | 
					 | 
				
			||||||
    if (g.LogFile)
 | 
					 | 
				
			||||||
        vfprintf(g.LogFile, fmt, args);
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        g.LogBuffer.appendfv(fmt, args);
 | 
					 | 
				
			||||||
    va_end(args);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 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
 | 
					 | 
				
			||||||
void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					 | 
				
			||||||
    ImGuiWindow* window = g.CurrentWindow;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!text_end)
 | 
					 | 
				
			||||||
        text_end = FindRenderedTextEnd(text, text_end);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + 1);
 | 
					 | 
				
			||||||
    if (ref_pos)
 | 
					 | 
				
			||||||
        g.LogLinePosY = ref_pos->y;
 | 
					 | 
				
			||||||
    if (log_new_line)
 | 
					 | 
				
			||||||
        g.LogLineFirstItem = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const char* text_remaining = text;
 | 
					 | 
				
			||||||
    if (g.LogDepthRef > window->DC.TreeDepth)  // Re-adjust padding if we have popped out of our starting depth
 | 
					 | 
				
			||||||
        g.LogDepthRef = window->DC.TreeDepth;
 | 
					 | 
				
			||||||
    const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef);
 | 
					 | 
				
			||||||
    for (;;)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Split the string. Each new line (after a '\n') is followed by spacing 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.
 | 
					 | 
				
			||||||
        const char* line_start = text_remaining;
 | 
					 | 
				
			||||||
        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);
 | 
					 | 
				
			||||||
        if (!is_last_line || (line_start != line_end))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            const int char_count = (int)(line_end - line_start);
 | 
					 | 
				
			||||||
            if (log_new_line || !is_first_line)
 | 
					 | 
				
			||||||
                LogText(IM_NEWLINE "%*s%.*s", tree_depth * 4, "", char_count, 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;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (log_new_line)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // An empty "" string at a different Y position should output a carriage return.
 | 
					 | 
				
			||||||
            LogText(IM_NEWLINE);
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (is_last_line)
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        text_remaining = line_end + 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Start logging/capturing text output
 | 
					 | 
				
			||||||
void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					 | 
				
			||||||
    ImGuiWindow* window = g.CurrentWindow;
 | 
					 | 
				
			||||||
    IM_ASSERT(g.LogEnabled == false);
 | 
					 | 
				
			||||||
    IM_ASSERT(g.LogFile == NULL);
 | 
					 | 
				
			||||||
    IM_ASSERT(g.LogBuffer.empty());
 | 
					 | 
				
			||||||
    g.LogEnabled = true;
 | 
					 | 
				
			||||||
    g.LogType = type;
 | 
					 | 
				
			||||||
    g.LogDepthRef = window->DC.TreeDepth;
 | 
					 | 
				
			||||||
    g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault);
 | 
					 | 
				
			||||||
    g.LogLinePosY = FLT_MAX;
 | 
					 | 
				
			||||||
    g.LogLineFirstItem = true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ImGui::LogToTTY(int auto_open_depth)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					 | 
				
			||||||
    if (g.LogEnabled)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    LogBegin(ImGuiLogType_TTY, auto_open_depth);
 | 
					 | 
				
			||||||
    g.LogFile = stdout;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Start logging/capturing text output to given file
 | 
					 | 
				
			||||||
void ImGui::LogToFile(int auto_open_depth, const char* filename)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					 | 
				
			||||||
    if (g.LogEnabled)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // FIXME: We could probably open the file in text mode "at", however note that clipboard/buffer logging will still 
 | 
					 | 
				
			||||||
    // be subject to outputting OS-incompatible carriage return if within strings the user doesn't use IM_NEWLINE.
 | 
					 | 
				
			||||||
    // By opening the file in binary mode "ab" we have consistent output everywhere.
 | 
					 | 
				
			||||||
    if (!filename)
 | 
					 | 
				
			||||||
        filename = g.IO.LogFilename;
 | 
					 | 
				
			||||||
    if (!filename || !filename[0])
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    FILE* f = ImFileOpen(filename, "ab");
 | 
					 | 
				
			||||||
    if (f == NULL)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        IM_ASSERT(0);
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    LogBegin(ImGuiLogType_File, auto_open_depth);
 | 
					 | 
				
			||||||
    g.LogFile = f;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Start logging/capturing text output to clipboard
 | 
					 | 
				
			||||||
void ImGui::LogToClipboard(int auto_open_depth)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					 | 
				
			||||||
    if (g.LogEnabled)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    LogBegin(ImGuiLogType_Clipboard, auto_open_depth);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ImGui::LogToBuffer(int auto_open_depth)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					 | 
				
			||||||
    if (g.LogEnabled)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
    LogBegin(ImGuiLogType_Buffer, auto_open_depth);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ImGui::LogFinish()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					 | 
				
			||||||
    if (!g.LogEnabled)
 | 
					 | 
				
			||||||
        return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    LogText(IM_NEWLINE);
 | 
					 | 
				
			||||||
    switch (g.LogType)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    case ImGuiLogType_TTY:
 | 
					 | 
				
			||||||
        fflush(g.LogFile);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    case ImGuiLogType_File:
 | 
					 | 
				
			||||||
        fclose(g.LogFile);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    case ImGuiLogType_Buffer:
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    case ImGuiLogType_Clipboard:
 | 
					 | 
				
			||||||
        if (!g.LogBuffer.empty())
 | 
					 | 
				
			||||||
            SetClipboardText(g.LogBuffer.begin());
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    case ImGuiLogType_None:
 | 
					 | 
				
			||||||
        IM_ASSERT(0);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    g.LogEnabled = false;
 | 
					 | 
				
			||||||
    g.LogType = ImGuiLogType_None;
 | 
					 | 
				
			||||||
    g.LogFile = NULL;
 | 
					 | 
				
			||||||
    g.LogBuffer.clear();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Helper to display logging buttons
 | 
					 | 
				
			||||||
// FIXME-OBSOLETE: We should probably obsolete this and let the user have their own helper (this is one of the oldest function alive!)
 | 
					 | 
				
			||||||
void ImGui::LogButtons()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    PushID("LogButtons");
 | 
					 | 
				
			||||||
    const bool log_to_tty = Button("Log To TTY"); SameLine();
 | 
					 | 
				
			||||||
    const bool log_to_file = Button("Log To File"); SameLine();
 | 
					 | 
				
			||||||
    const bool log_to_clipboard = Button("Log To Clipboard"); SameLine();
 | 
					 | 
				
			||||||
    PushItemWidth(80.0f);
 | 
					 | 
				
			||||||
    PushAllowKeyboardFocus(false);
 | 
					 | 
				
			||||||
    SliderInt("Default Depth", &g.LogDepthToExpandDefault, 0, 9, NULL);
 | 
					 | 
				
			||||||
    PopAllowKeyboardFocus();
 | 
					 | 
				
			||||||
    PopItemWidth();
 | 
					 | 
				
			||||||
    PopID();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Start logging at the end of the function so that the buttons don't appear in the log
 | 
					 | 
				
			||||||
    if (log_to_tty)
 | 
					 | 
				
			||||||
        LogToTTY();
 | 
					 | 
				
			||||||
    if (log_to_file)
 | 
					 | 
				
			||||||
        LogToFile();
 | 
					 | 
				
			||||||
    if (log_to_clipboard)
 | 
					 | 
				
			||||||
        LogToClipboard();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
//-----------------------------------------------------------------------------
 | 
					//-----------------------------------------------------------------------------
 | 
				
			||||||
// [SECTION] SETTINGS
 | 
					// [SECTION] SETTINGS
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user