Split windows up into different files
This commit is contained in:
parent
430ed098a6
commit
49eca27204
|
@ -26,15 +26,17 @@ set(LIBS -lpcre2-8 -lpcre2-posix SDL2 imgui)
|
||||||
set(IMGUI_LIBS SDL2 Freetype::Freetype)
|
set(IMGUI_LIBS SDL2 Freetype::Freetype)
|
||||||
|
|
||||||
set(INCLUDES imgui imgui/backends imgui/misc/cpp imgui/freetype /usr/include/SDL2)
|
set(INCLUDES imgui imgui/backends imgui/misc/cpp imgui/freetype /usr/include/SDL2)
|
||||||
set(SOURCES main.cpp event_loop.cpp logcat_thread.cpp logcat_entry.cpp log.cpp config.cpp misc.cpp pcre2_wrapper.cpp)
|
set(SOURCES main.cpp event_loop.cpp logcat_thread.cpp logcat_entry.cpp log.cpp config.cpp misc.cpp pcre2_wrapper.cpp
|
||||||
|
windows/logs.cpp windows/settings.cpp windows/main.cpp)
|
||||||
set(IMGUI_SOURCES imgui/imgui.cpp imgui/imgui_draw.cpp imgui/imgui_widgets.cpp imgui/imgui_tables.cpp
|
set(IMGUI_SOURCES imgui/imgui.cpp imgui/imgui_draw.cpp imgui/imgui_widgets.cpp imgui/imgui_tables.cpp
|
||||||
imgui/misc/cpp/imgui_stdlib.cpp imgui/misc/freetype/imgui_freetype.cpp
|
imgui/misc/cpp/imgui_stdlib.cpp imgui/misc/freetype/imgui_freetype.cpp
|
||||||
imgui/backends/imgui_impl_sdl.cpp imgui/backends/imgui_impl_opengl3.cpp)
|
imgui/backends/imgui_impl_sdl.cpp imgui/backends/imgui_impl_opengl3.cpp)
|
||||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
set(SOURCES ${SOURCES} windows/debug.cpp)
|
||||||
set(IMGUI_SOURCES ${IMGUI_SOURCES} imgui/imgui_demo.cpp)
|
set(IMGUI_SOURCES ${IMGUI_SOURCES} imgui/imgui_demo.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(FLAGS "-fsanitize=undefined,thread")
|
set(FLAGS "-fsanitize=undefined,thread -DIMGUI_USER_CONFIG='\"../myimconfig.h\"'")
|
||||||
# https://t.me/NightShadowsHangout/670691
|
# https://t.me/NightShadowsHangout/670691
|
||||||
set(FLAGS "${FLAGS} -Werror -Wall -Wextra -Wshadow -Wpedantic -Wno-gnu-anonymous-struct -fno-rtti -fPIC -Wconversion -Wno-unused-parameter -Wimplicit-fallthrough")
|
set(FLAGS "${FLAGS} -Werror -Wall -Wextra -Wshadow -Wpedantic -Wno-gnu-anonymous-struct -fno-rtti -fPIC -Wconversion -Wno-unused-parameter -Wimplicit-fallthrough")
|
||||||
# https://sourceforge.net/p/valgrind/mailman/valgrind-users/thread/Ygze8PzaQAYWlKDj%40wildebeest.org/
|
# https://sourceforge.net/p/valgrind/mailman/valgrind-users/thread/Ygze8PzaQAYWlKDj%40wildebeest.org/
|
||||||
|
@ -69,7 +71,7 @@ add_library(imgui STATIC ${IMGUI_SOURCES})
|
||||||
target_include_directories(imgui PRIVATE ${INCLUDES})
|
target_include_directories(imgui PRIVATE ${INCLUDES})
|
||||||
target_link_libraries(imgui PRIVATE ${IMGUI_LIBS})
|
target_link_libraries(imgui PRIVATE ${IMGUI_LIBS})
|
||||||
# dear imgui has some fucky wucky with -Wconversion, hence -Wno-conversion
|
# dear imgui has some fucky wucky with -Wconversion, hence -Wno-conversion
|
||||||
target_compile_options(imgui PRIVATE -Wno-conversion -DIMGUI_USER_CONFIG="../myimconfig.h")
|
target_compile_options(imgui PRIVATE -Wno-conversion)
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE ${INCLUDES})
|
target_include_directories(${PROJECT_NAME} PRIVATE ${INCLUDES})
|
||||||
|
|
207
event_loop.cpp
207
event_loop.cpp
|
@ -1,21 +1,15 @@
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <imgui_stdlib.h>
|
|
||||||
|
|
||||||
// for Test user assert
|
|
||||||
#ifndef NDEBUG
|
|
||||||
#include "myimconfig.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "logcat_thread.h"
|
#include "logcat_thread.h"
|
||||||
|
|
||||||
static std::string leftpad(std::string str, size_t characters) {
|
#include "windows/logs.h"
|
||||||
if (str.size() < characters) {
|
#include "windows/settings.h"
|
||||||
return str.insert(0, characters - str.size(), ' ');
|
#include "windows/main.h"
|
||||||
}
|
#ifndef NDEBUG
|
||||||
return str;
|
#include "windows/debug.h"
|
||||||
}
|
#endif
|
||||||
|
|
||||||
static inline void write_config_and_update_structures(const Config& config) {
|
static inline void write_config_and_update_structures(const Config& config) {
|
||||||
try {
|
try {
|
||||||
|
@ -42,195 +36,6 @@ static inline void check_for_logcat_items(LogcatThread& logcat_thread, std::vect
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void settings_window(Config& config, float* config_write_timer, bool* show_settings_window) {
|
|
||||||
if (!ImGui::Begin("Settings", show_settings_window)) {
|
|
||||||
ImGui::End();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// TODO actually have process control
|
|
||||||
ImGui::Text("Logcat command only takes effect when logcat is not running");
|
|
||||||
if (ImGui::InputTextWithHint("Logcat command", "adb logcat -Dv 'threadtime UTC epoch usec uid'", &config.logcat_command)) {
|
|
||||||
*config_write_timer = *config_write_timer > 0.0f ? *config_write_timer : 5.0f;
|
|
||||||
}
|
|
||||||
ImGui::Text("Font sizes only take effect when LogMeow is restarted");
|
|
||||||
#ifdef USE_FONTCONFIG
|
|
||||||
if (ImGui::InputFloat("Normal font size", &config.normal_font_size, 0.5f, 1.0f, "%.3f")) {
|
|
||||||
*config_write_timer = *config_write_timer > 0.0f ? *config_write_timer : 5.0f;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (ImGui::InputFloat("Monospace font size", &config.monospace_font_size, 0.5f, 1.0f, "%.3f")) {
|
|
||||||
*config_write_timer = *config_write_timer > 0.0f ? *config_write_timer : 5.0f;
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void logs_window(ImFont* monospace_font, bool* autoscrolling, bool* show_logs_window) {
|
|
||||||
if (!ImGui::Begin("LogMeow Logs", show_logs_window)) {
|
|
||||||
ImGui::End();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::Button("Clear")) {
|
|
||||||
log_entries.clear();
|
|
||||||
log_entry_line_offsets = {0};
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (ImGui::Button("Copy")) {
|
|
||||||
ImGui::SetClipboardText(log_entries.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()
|
|
||||||
if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar)) {
|
|
||||||
ImGui::PushFont(monospace_font);
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
|
||||||
|
|
||||||
ImGuiListClipper clipper;
|
|
||||||
clipper.Begin(static_cast<int>(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<size_t>(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;
|
|
||||||
ImGui::SetScrollHereY(1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndChild();
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void main_window(bool latest_log_entries_read, ImFont* monospace_font, std::vector<LogcatEntry>& filtered_logcat_entries,
|
|
||||||
bool* show_settings_window, bool* show_logs_window, bool* run_event_loop) {
|
|
||||||
if (!ImGui::Begin("LogMeow", run_event_loop)) {
|
|
||||||
ImGui::End();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::Button("Settings")) {
|
|
||||||
*show_settings_window = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (!latest_log_entries_read) {
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0.0f, 0.6f, 0.6f));
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(0.0f, 0.7f, 0.7f));
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(0.0f, 0.8f, 0.8f));
|
|
||||||
}
|
|
||||||
if (ImGui::Button("Logs")) {
|
|
||||||
*show_logs_window = true;
|
|
||||||
}
|
|
||||||
if (!latest_log_entries_read) {
|
|
||||||
ImGui::PopStyleColor(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
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::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
|
||||||
|
|
||||||
ImGuiListClipper clipper;
|
|
||||||
clipper.Begin(static_cast<int>(filtered_logcat_entries.size()));
|
|
||||||
while (clipper.Step()) {
|
|
||||||
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
|
||||||
LogcatEntry* logcat_entry = &filtered_logcat_entries[static_cast<size_t>(i)];
|
|
||||||
char time_as_str[128] = {0};
|
|
||||||
strftime(time_as_str, 127 * sizeof(char), "%c", localtime(&logcat_entry->time));
|
|
||||||
|
|
||||||
std::string header = std::string(1, '[') + time_as_str + ' '
|
|
||||||
+ leftpad(logcat_entry->user.value_or(" "), 5) + ' '
|
|
||||||
+ leftpad(std::to_string(logcat_entry->pid), 5) + ' '
|
|
||||||
+ leftpad(std::to_string(logcat_entry->tid), 5) + ' '
|
|
||||||
+ leftpad(buffer_to(logcat_entry->buffer), 6) + ' '
|
|
||||||
+ leftpad(priority_to(logcat_entry->priority), 7) + "] ";
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]);
|
|
||||||
ImGui::TextUnformatted(header.data(), &header[header.size()]);
|
|
||||||
ImGui::PopStyleColor();
|
|
||||||
|
|
||||||
std::string line = logcat_entry->tag + ": " + logcat_entry->message;
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextUnformatted(line.data(), &line[line.size()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clipper.End();
|
|
||||||
|
|
||||||
ImGui::PopStyleVar();
|
|
||||||
ImGui::PopFont();
|
|
||||||
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
|
|
||||||
ImGui::SetScrollHereY(1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndChild();
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
static inline void debug_window(LogcatThread& logcat_thread) {
|
|
||||||
static bool show_demo_window = false;
|
|
||||||
static size_t add_log_entry_presses = 1;
|
|
||||||
static bool log_entry_every_second = false;
|
|
||||||
static float log_entry_every_second_delta;
|
|
||||||
|
|
||||||
if (show_demo_window) {
|
|
||||||
ImGui::ShowDemoWindow(&show_demo_window);
|
|
||||||
}
|
|
||||||
if (!ImGui::Begin("LogMeow Debug")) {
|
|
||||||
ImGui::End();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
|
||||||
ImGui::Checkbox("Show Dear ImGui Demo Window", &show_demo_window);
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
if (ImGui::Button("Add Log Entry")) {
|
|
||||||
log(std::string("Debug log entry #") + std::to_string(add_log_entry_presses++) + " (activated via manual button press)");
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
// returns true when it's pressed
|
|
||||||
if (ImGui::Checkbox("Add log entry every second", &log_entry_every_second)) {
|
|
||||||
log_entry_every_second_delta = 0.0f;
|
|
||||||
}
|
|
||||||
if (ImGui::Button("Add Log Entry with Newlines")) {
|
|
||||||
log("The following should have five spaces: \"\n\n\n\n\n\"");
|
|
||||||
}
|
|
||||||
if (ImGui::Button("Test user assert")) {
|
|
||||||
IM_ASSERT_USER_ERROR(0, "User assert tested");
|
|
||||||
}
|
|
||||||
if (ImGui::Button("Request log entry from Logcat thread")) {
|
|
||||||
logcat_thread.debug_log_request.test_and_set();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log_entry_every_second) {
|
|
||||||
log_entry_every_second_delta += ImGui::GetIO().DeltaTime;
|
|
||||||
if (log_entry_every_second_delta >= 1.0f) {
|
|
||||||
log_entry_every_second_delta = 0.0f;
|
|
||||||
log(std::string("Debug log entry #") + std::to_string(add_log_entry_presses++) + " (activated by add log entry every second)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void event_loop(ImFont* monospace_font, Config& config, float* config_write_timer, LogcatThread& logcat_thread, bool* run_event_loop) {
|
void event_loop(ImFont* monospace_font, Config& config, float* config_write_timer, LogcatThread& logcat_thread, bool* run_event_loop) {
|
||||||
static bool show_settings_window = false;
|
static bool show_settings_window = false;
|
||||||
static bool show_logs_window = false;
|
static bool show_logs_window = false;
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include <imgui.cpp>
|
||||||
|
#include "../myimconfig.h"
|
||||||
|
|
||||||
|
#include "../log.h"
|
||||||
|
#include "../logcat_thread.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
void debug_window(LogcatThread& logcat_thread) {
|
||||||
|
static bool show_demo_window = false;
|
||||||
|
static size_t add_log_entry_presses = 1;
|
||||||
|
static bool log_entry_every_second = false;
|
||||||
|
static float log_entry_every_second_delta;
|
||||||
|
|
||||||
|
if (show_demo_window) {
|
||||||
|
ImGui::ShowDemoWindow(&show_demo_window);
|
||||||
|
}
|
||||||
|
if (!ImGui::Begin("LogMeow Debug")) {
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||||
|
ImGui::Checkbox("Show Dear ImGui Demo Window", &show_demo_window);
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::Button("Add Log Entry")) {
|
||||||
|
log(std::string("Debug log entry #") + std::to_string(add_log_entry_presses++) + " (activated via manual button press)");
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
// returns true when it's pressed
|
||||||
|
if (ImGui::Checkbox("Add log entry every second", &log_entry_every_second)) {
|
||||||
|
log_entry_every_second_delta = 0.0f;
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Add Log Entry with Newlines")) {
|
||||||
|
log("The following should have five spaces: \"\n\n\n\n\n\"");
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Test user assert")) {
|
||||||
|
IM_ASSERT_USER_ERROR(0, "User assert tested");
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Request log entry from Logcat thread")) {
|
||||||
|
logcat_thread.debug_log_request.test_and_set();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (log_entry_every_second) {
|
||||||
|
log_entry_every_second_delta += ImGui::GetIO().DeltaTime;
|
||||||
|
if (log_entry_every_second_delta >= 1.0f) {
|
||||||
|
log_entry_every_second_delta = 0.0f;
|
||||||
|
log(std::string("Debug log entry #") + std::to_string(add_log_entry_presses++) + " (activated by add log entry every second)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../logcat_thread.h"
|
||||||
|
|
||||||
|
void debug_window(LogcatThread& logcat_thread);
|
|
@ -0,0 +1,60 @@
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
#include "../log.h"
|
||||||
|
#include "logs.h"
|
||||||
|
|
||||||
|
static inline void logs_scrolling_region(ImFont* monospace_font, bool* autoscrolling) {
|
||||||
|
ImGui::PushFont(monospace_font);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||||
|
|
||||||
|
ImGuiListClipper clipper;
|
||||||
|
clipper.Begin(static_cast<int>(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<size_t>(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;
|
||||||
|
ImGui::SetScrollHereY(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void logs_window(ImFont* monospace_font, bool* autoscrolling, bool* p_open) {
|
||||||
|
if (!ImGui::Begin("LogMeow Logs", p_open)) {
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Clear")) {
|
||||||
|
log_entries.clear();
|
||||||
|
log_entry_line_offsets = {0};
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Copy")) {
|
||||||
|
ImGui::SetClipboardText(log_entries.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()
|
||||||
|
if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar)) {
|
||||||
|
logs_scrolling_region(monospace_font, autoscrolling);
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
ImGui::End();
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
void logs_window(ImFont* monospace_font, bool* autoscrolling, bool* p_open);
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <ctime>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../logcat_entry.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
static std::string leftpad(std::string str, size_t characters) {
|
||||||
|
if (str.size() < characters) {
|
||||||
|
return str.insert(0, characters - str.size(), ' ');
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void main_scrolling_region(ImFont* monospace_font, std::vector<LogcatEntry>& filtered_logcat_entries) {
|
||||||
|
ImGui::PushFont(monospace_font);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
|
||||||
|
|
||||||
|
ImGuiListClipper clipper;
|
||||||
|
clipper.Begin(static_cast<int>(filtered_logcat_entries.size()));
|
||||||
|
while (clipper.Step()) {
|
||||||
|
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
||||||
|
LogcatEntry* logcat_entry = &filtered_logcat_entries[static_cast<size_t>(i)];
|
||||||
|
char time_as_str[128] = {0};
|
||||||
|
strftime(time_as_str, 127 * sizeof(char), "%c", localtime(&logcat_entry->time));
|
||||||
|
|
||||||
|
std::string header = std::string(1, '[') + time_as_str + ' '
|
||||||
|
+ leftpad(logcat_entry->user.value_or(" "), 5) + ' '
|
||||||
|
+ leftpad(std::to_string(logcat_entry->pid), 5) + ' '
|
||||||
|
+ leftpad(std::to_string(logcat_entry->tid), 5) + ' '
|
||||||
|
+ leftpad(buffer_to(logcat_entry->buffer), 6) + ' '
|
||||||
|
+ leftpad(priority_to(logcat_entry->priority), 7) + "] ";
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]);
|
||||||
|
ImGui::TextUnformatted(header.data(), &header[header.size()]);
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
|
||||||
|
std::string line = logcat_entry->tag + ": " + logcat_entry->message;
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextUnformatted(line.data(), &line[line.size()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clipper.End();
|
||||||
|
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
ImGui::PopFont();
|
||||||
|
if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
|
||||||
|
ImGui::SetScrollHereY(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_window(bool latest_log_entries_read, ImFont* monospace_font, std::vector<LogcatEntry>& filtered_logcat_entries,
|
||||||
|
bool* show_settings_window, bool* show_logs_window, bool* run_event_loop) {
|
||||||
|
if (!ImGui::Begin("LogMeow", run_event_loop)) {
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Settings")) {
|
||||||
|
*show_settings_window = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (!latest_log_entries_read) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(0.0f, 0.6f, 0.6f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(0.0f, 0.7f, 0.7f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(0.0f, 0.8f, 0.8f));
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Logs")) {
|
||||||
|
*show_logs_window = true;
|
||||||
|
}
|
||||||
|
if (!latest_log_entries_read) {
|
||||||
|
ImGui::PopStyleColor(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
main_scrolling_region(monospace_font, filtered_logcat_entries);
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
ImGui::End();
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../logcat_entry.h"
|
||||||
|
|
||||||
|
void main_window(bool latest_log_entries_read, ImFont* monospace_font, std::vector<LogcatEntry>& filtered_logcat_entries,
|
||||||
|
bool* show_settings_window, bool* show_logs_window, bool* run_event_loop);
|
|
@ -0,0 +1,27 @@
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_stdlib.h>
|
||||||
|
|
||||||
|
#include "../config.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
void settings_window(Config& config, float* config_write_timer, bool* p_open) {
|
||||||
|
if (!ImGui::Begin("Settings", p_open)) {
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO actually have process control
|
||||||
|
ImGui::Text("Logcat command only takes effect when logcat is not running");
|
||||||
|
if (ImGui::InputTextWithHint("Logcat command", "adb logcat -Dv 'threadtime UTC epoch usec uid'", &config.logcat_command)) {
|
||||||
|
*config_write_timer = *config_write_timer > 0.0f ? *config_write_timer : 5.0f;
|
||||||
|
}
|
||||||
|
ImGui::Text("Font sizes only take effect when LogMeow is restarted");
|
||||||
|
#ifdef USE_FONTCONFIG
|
||||||
|
if (ImGui::InputFloat("Normal font size", &config.normal_font_size, 0.5f, 1.0f, "%.3f")) {
|
||||||
|
*config_write_timer = *config_write_timer > 0.0f ? *config_write_timer : 5.0f;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ImGui::InputFloat("Monospace font size", &config.monospace_font_size, 0.5f, 1.0f, "%.3f")) {
|
||||||
|
*config_write_timer = *config_write_timer > 0.0f ? *config_write_timer : 5.0f;
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
|
void settings_window(Config& config, float* config_write_timer, bool* p_open);
|
Loading…
Reference in New Issue