diff --git a/event_loop.cpp b/event_loop.cpp index 3d82e94..624a366 100644 --- a/event_loop.cpp +++ b/event_loop.cpp @@ -19,10 +19,7 @@ static inline void check_for_logcat_items(LogcatThread& logcat_thread) { while ((logcat_thread_item = logcat_thread.atomic_ring_buffer.get())) { if (std::holds_alternative(*logcat_thread_item)) { - if (!log_entries.empty()) { - log_entries += '\n'; - } - log_entries += std::move(std::get(*logcat_thread_item)); + log_raw(std::move(std::get(*logcat_thread_item)), false); } else if (std::holds_alternative(*logcat_thread_item)) { LogcatEntry logcat_entry = std::move(std::get(*logcat_thread_item)); log("Received new logcat entry"); @@ -74,6 +71,7 @@ static inline void logs_window(ImFont* monospace_font, bool* autoscrolling, bool if (ImGui::Button("Clear")) { log_entries.clear(); + log_entry_line_offsets = {0}; } ImGui::SameLine(); if (ImGui::Button("Copy")) { @@ -82,9 +80,30 @@ static inline void logs_window(ImFont* monospace_font, bool* autoscrolling, bool ImGui::Separator(); // copied from imgui/imgui_demo.cpp: [SECTION] Example App: Debug Console / ShowExampleAppConsole() + // and [SECTION] Example App: Long Text / ShowExampleAppLongText() + // and [SECTION] Example App: Debug Log / ShowExampleAppLog() if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar)) { ImGui::PushFont(monospace_font); - ImGui::TextUnformatted(log_entries.data(), &log_entries[log_entries.size()]); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + + ImGuiListClipper clipper; + clipper.Begin(static_cast(log_entry_line_offsets.size())); + while (clipper.Step()) { + for (int i_u = clipper.DisplayStart; i_u < clipper.DisplayEnd; i_u++) { + // what'd we do if we log the error about an error failing to show logs + assert(i_u >= 0); + size_t i = static_cast(i_u); + + const char* start_offset = &log_entries[log_entry_line_offsets[i]]; + const char* end_offset = log_entry_line_offsets.size() > i + 1 + ? &log_entries[log_entry_line_offsets[i + 1] - 1] + : &log_entries[log_entries.size()]; + ImGui::TextUnformatted(start_offset, end_offset); + } + } + clipper.End(); + + ImGui::PopStyleVar(); ImGui::PopFont(); if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) { *autoscrolling = true; diff --git a/log.cpp b/log.cpp index 9e7cc42..565c6b7 100644 --- a/log.cpp +++ b/log.cpp @@ -6,6 +6,7 @@ #include "log.h" std::string log_entries; +std::vector log_entry_line_offsets = {0}; std::string format_log(std::string entry, time_t time) { size_t newline_pos; @@ -23,10 +24,13 @@ std::string format_log(std::string entry) { return format_log(std::move(entry), time(nullptr)); } -void log_raw(std::string line) { - printf("%s\n", line.c_str()); +void log_raw(std::string line, bool print) { + if (print) { + printf("%s\n", line.c_str()); + } if (!log_entries.empty()) { log_entries += '\n'; + log_entry_line_offsets.push_back(log_entries.size()); } log_entries += std::move(line); } diff --git a/log.h b/log.h index 02369f6..bb8086a 100644 --- a/log.h +++ b/log.h @@ -5,9 +5,10 @@ #include extern std::string log_entries; +extern std::vector log_entry_line_offsets; std::string format_log(std::string entry, time_t time); std::string format_log(std::string entry); -void log_raw(std::string line); +void log_raw(std::string line, bool print = true); void log(std::string entry, time_t time); void log(std::string entry); diff --git a/myimconfig.h b/myimconfig.h index 1e5f525..a574533 100644 --- a/myimconfig.h +++ b/myimconfig.h @@ -3,6 +3,7 @@ #include "log.h" #define IM_ASSERT_USER_ERROR(expr,msg) do { if (!(expr)) { log(msg); } } while (0); +#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef NDEBUG #define IMGUI_DEBUG_PARANOID