feat(cpp/core): logger + log_window + selectable_text widgets

Logger global thread-safe con ring buffer in-memory de 2000 entradas + escritura
opcional a archivo. log_window flotante consume el ring buffer con filtros por
nivel, busqueda y autoscroll; se abre desde Settings -> Logs en la menubar.
selectable_text cubre el patron drag-to-select + Ctrl+C en cualquier ventana.

app_menubar y framework run_app integran log_window_render() en el frame loop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-04 11:50:57 +02:00
parent d55b8fea5d
commit f1a5e04d4f
17 changed files with 1280 additions and 64 deletions
+39
View File
@@ -115,6 +115,13 @@ struct AppConfig {
// llama fn_ui::app_menubar(panels, panel_count, layouts_cb) cada frame.
fn_ui::LayoutCallbacks* layouts_cb = nullptr;
// Items extra dentro del menu "View", al final tras los toggles de
// paneles. Si view_extras != nullptr, run_app lo pasa a app_menubar.
// El callback se invoca dentro de un BeginMenu("View") ya abierto:
// la app llama directamente a ImGui::Separator(), MenuItem(), etc.
// NO debe abrir/cerrar el menu View.
std::function<bool()> view_extras{};
// Si true, run_app llama fn::gfx::gl_loader_init() tras crear el contexto
// GL y antes del primer frame. Necesario para apps que llaman gl* directo
// en Windows (en Linux es no-op).
@@ -136,3 +143,35 @@ int run_app(AppConfig config, std::function<void()> render_fn);
int run_app(std::function<void()> render_fn);
} // namespace fn
// ----------------------------------------------------------------------------
// E2E testing — Dear ImGui Test Engine integration.
// ----------------------------------------------------------------------------
//
// Only available when the registry is built with -DFN_BUILD_TESTS=ON. The
// CMake option defines IMGUI_ENABLE_TEST_ENGINE on imgui+fn_framework and
// links the imgui_test_engine static lib. Without the option, run_app_test is
// not declared and apps build identically to today.
#ifdef IMGUI_ENABLE_TEST_ENGINE
struct ImGuiTestEngine;
namespace fn {
// Run an app under Dear ImGui Test Engine. Same as run_app, but:
// 1. Creates a test engine and binds it to the ImGui context.
// 2. Calls register_tests(engine) once before the main loop. Tests are
// registered with IM_REGISTER_TEST(engine, "category", "name") and
// assigned a TestFunc lambda that drives the UI.
// 3. Queues all tests matching `filter` (default "all") and ticks frames
// until the queue empties.
// 4. Exits with code 0 if all tests pass, 1 if any failed or crashed.
//
// register_tests must be non-null and must register at least one test or the
// function returns 1.
int run_app_test(AppConfig config,
std::function<void()> render_fn,
std::function<void(ImGuiTestEngine*)> register_tests,
const char* filter = "all");
} // namespace fn
#endif // IMGUI_ENABLE_TEST_ENGINE