Files
allwpilib/glass/src/lib/native/cpp/other/Log.cpp
2025-11-07 23:09:21 -08:00

85 lines
2.2 KiB
C++

// 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 "wpi/glass/other/Log.hpp"
#include <string>
#include <imgui.h>
using namespace wpi::glass;
LogData::LogData(size_t maxLines) : m_maxLines{maxLines} {}
void LogData::Clear() {
m_buf.clear();
m_lineOffsets.clear();
m_lineOffsets.push_back(0);
}
void LogData::Append(std::string_view msg) {
if (m_lineOffsets.size() >= m_maxLines) {
Clear();
}
size_t oldSize = m_buf.size();
m_buf.append(msg);
for (size_t newSize = m_buf.size(); oldSize < newSize; ++oldSize) {
if (m_buf[oldSize] == '\n') {
m_lineOffsets.push_back(oldSize + 1);
}
}
}
const std::string& LogData::GetBuffer() {
return m_buf;
}
void wpi::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() {
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());
}
}
bool LogView::HasSettings() {
return true;
}