115 lines
3.9 KiB
C++
115 lines
3.9 KiB
C++
#include <ctime>
|
|
#include <imgui/imgui.h>
|
|
|
|
#include "../misc.h"
|
|
#include "../log.h"
|
|
#include "logs.h"
|
|
|
|
static inline void render_table_item_context_menu(const LogEntry& log_entry) {
|
|
struct tm tm;
|
|
char time_as_str[128] = {0};
|
|
strftime(time_as_str, 127 * sizeof(char), "%c", localtime_r(&log_entry.time, &tm));
|
|
|
|
ImGui::TextDisabled("[%s] %s", time_as_str, log_entry.message.c_str());
|
|
ImGui::Separator();
|
|
ImGui::PushFont(nullptr);
|
|
|
|
if (ImGui::Selectable("Copy")) ImGui::SetClipboardText(to_string(log_entry).c_str());
|
|
if (ImGui::Selectable("Copy Time")) ImGui::SetClipboardText(time_as_str);
|
|
if (ImGui::Selectable("Copy Message")) ImGui::SetClipboardText(log_entry.message.c_str());
|
|
|
|
ImGui::PopFont();
|
|
}
|
|
|
|
static inline void render_table_item(const LogEntry& log_entry, size_t log_entry_index, size_t* copying_entry_index) {
|
|
auto table_item_popup = [&]() {
|
|
bool popup_was_open = ImGui::IsPopupOpen("copy_popup");
|
|
ImGui::OpenPopupOnItemClick("copy_popup");
|
|
if (!popup_was_open) {
|
|
*copying_entry_index = log_entry_index;
|
|
}
|
|
};
|
|
|
|
ImGui::TableNextRow();
|
|
if (ImGui::TableSetColumnIndex(0)) {
|
|
struct tm tm;
|
|
char time_as_str[128] = {0};
|
|
strftime(time_as_str, 127 * sizeof(char), "%c", localtime_r(&log_entry.time, &tm));
|
|
|
|
ImGui::TextUnformatted(time_as_str);
|
|
table_item_popup();
|
|
}
|
|
if (ImGui::TableSetColumnIndex(1)) { ImGui::TextUnformatted(log_entry.message); table_item_popup(); }
|
|
}
|
|
|
|
static inline void render_table(ImFont* monospace_font, bool* autoscrolling) {
|
|
static size_t copying_entry_index;
|
|
|
|
ImGui::TableSetupScrollFreeze(0, 1);
|
|
ImGui::TableSetupColumn("Time", ImGuiTableColumnFlags_None);
|
|
ImGui::TableSetupColumn("Message", ImGuiTableColumnFlags_None);
|
|
ImGui::TableHeadersRow();
|
|
|
|
ImGui::PushFont(monospace_font);
|
|
|
|
ImGuiListClipper clipper;
|
|
clipper.Begin(static_cast<int>(log_entries.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<size_t>(i_u);
|
|
|
|
render_table_item(log_entries[i], i, ©ing_entry_index);
|
|
}
|
|
}
|
|
clipper.End();
|
|
|
|
if (ImGui::BeginPopup("copy_popup")) {
|
|
render_table_item_context_menu(log_entries[copying_entry_index]);
|
|
ImGui::EndPopup();
|
|
}
|
|
|
|
ImGui::PopFont();
|
|
|
|
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
|
|
*autoscrolling = true;
|
|
ImGui::SetScrollHereY(1.0f);
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
void logs_window(ImFont* monospace_font, bool* __restrict autoscrolling, bool* __restrict p_open) {
|
|
if (!ImGui::BeginWithCloseShortcut("LogMeow Logs", p_open)) {
|
|
ImGui::End();
|
|
return;
|
|
}
|
|
|
|
if (ImGui::Button("Clear")) {
|
|
log_entries.clear();
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::Button("Copy")) {
|
|
std::string text;
|
|
for (const LogEntry& entry : log_entries) {
|
|
if (!text.empty()) {
|
|
text += '\n';
|
|
}
|
|
text += to_string(entry);
|
|
}
|
|
ImGui::SetClipboardText(text.c_str());
|
|
}
|
|
|
|
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()
|
|
// and Tables/Vertical scrolling, with clipping
|
|
const constexpr ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_ScrollX | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable;
|
|
if (ImGui::BeginTable("logs", 2, flags)) {
|
|
render_table(monospace_font, autoscrolling);
|
|
}
|
|
ImGui::End();
|
|
}
|