2020-12-29 20:47:58 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
|
|
|
|
|
|
|
|
|
#include "glass/other/Log.h"
|
|
|
|
|
|
|
|
|
|
#include <imgui.h>
|
|
|
|
|
|
|
|
|
|
using namespace glass;
|
|
|
|
|
|
2021-01-01 10:27:49 -08:00
|
|
|
LogData::LogData(size_t maxLines) : m_maxLines{maxLines} {}
|
|
|
|
|
|
2020-12-29 20:47:58 -08:00
|
|
|
void LogData::Clear() {
|
|
|
|
|
m_buf.clear();
|
|
|
|
|
m_lineOffsets.clear();
|
|
|
|
|
m_lineOffsets.push_back(0);
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
void LogData::Append(std::string_view msg) {
|
2020-12-29 20:47:58 -08:00
|
|
|
if (m_lineOffsets.size() >= m_maxLines) {
|
|
|
|
|
Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t oldSize = m_buf.size();
|
2021-06-06 16:13:58 -07:00
|
|
|
m_buf.append(msg);
|
2020-12-29 20:47:58 -08:00
|
|
|
for (size_t newSize = m_buf.size(); oldSize < newSize; ++oldSize) {
|
|
|
|
|
if (m_buf[oldSize] == '\n') {
|
|
|
|
|
m_lineOffsets.push_back(oldSize + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-06 23:19:49 +03:00
|
|
|
const std::string& LogData::GetBuffer() {
|
|
|
|
|
return m_buf;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-29 20:47:58 -08:00
|
|
|
void glass::DisplayLog(LogData* data, bool autoScroll) {
|
|
|
|
|
if (data->m_buf.empty()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
|
|
|
|
const char* buf = data->m_buf.data();
|
|
|
|
|
const char* bufEnd = buf + data->m_buf.size();
|
|
|
|
|
ImGuiListClipper clipper;
|
|
|
|
|
clipper.Begin(data->m_lineOffsets.size());
|
|
|
|
|
while (clipper.Step()) {
|
|
|
|
|
for (size_t lineNum = clipper.DisplayStart;
|
|
|
|
|
lineNum < static_cast<size_t>(clipper.DisplayEnd); lineNum++) {
|
|
|
|
|
const char* lineStart = buf + data->m_lineOffsets[lineNum];
|
|
|
|
|
const char* lineEnd = (lineNum + 1 < data->m_lineOffsets.size())
|
|
|
|
|
? (buf + data->m_lineOffsets[lineNum + 1] - 1)
|
|
|
|
|
: bufEnd;
|
|
|
|
|
ImGui::TextUnformatted(lineStart, lineEnd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
clipper.End();
|
|
|
|
|
ImGui::PopStyleVar();
|
|
|
|
|
|
|
|
|
|
if (autoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
|
|
|
|
|
ImGui::SetScrollHereY(1.0f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LogView::Display() {
|
2023-01-01 21:05:09 -07:00
|
|
|
DisplayLog(m_data, m_autoScroll);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LogView::Settings() {
|
|
|
|
|
ImGui::Checkbox("Auto-scroll", &m_autoScroll);
|
|
|
|
|
if (ImGui::Selectable("Clear")) {
|
|
|
|
|
m_data->Clear();
|
|
|
|
|
}
|
|
|
|
|
const auto& buf = m_data->GetBuffer();
|
|
|
|
|
if (ImGui::Selectable("Copy to Clipboard", false,
|
|
|
|
|
buf.empty() ? ImGuiSelectableFlags_Disabled : 0)) {
|
|
|
|
|
ImGui::SetClipboardText(buf.c_str());
|
2020-12-29 20:47:58 -08:00
|
|
|
}
|
2023-01-01 21:05:09 -07:00
|
|
|
}
|
2020-12-29 20:47:58 -08:00
|
|
|
|
2023-01-01 21:05:09 -07:00
|
|
|
bool LogView::HasSettings() {
|
|
|
|
|
return true;
|
2020-12-29 20:47:58 -08:00
|
|
|
}
|