// Demos faltantes: process_runner (Core), candlestick / gauge / heatmap / // table_view (Viz). Aniade cobertura sobre los primitivos del registry que // no tenian su entry en la gallery. #include "demos.h" #include "demo.h" #include "core/process_runner.h" #include "viz/candlestick.h" #include "viz/gauge.h" #include "viz/heatmap.h" #include "viz/table_view.h" #include #include #include #include #include #include namespace gallery { // --------------------------------------------------------------------------- // process_runner (Core) // --------------------------------------------------------------------------- void demo_process_runner() { demo_header("process_runner", "v1.0.0", "Ejecuta una tarea en std::thread en background y expone estado thread-safe " "(idle/running/success/error). El widget runner_status() dibuja inline un " "spinner mientras corre y un mensaje de Success/Error al terminar."); static fn_ui::ProcessRunner runner; section("Tarea simulada (sleep 2s)"); { if (ImGui::Button("Run task")) { if (!runner.is_busy()) { fn_ui::runner_trigger(runner, [](std::string& out) -> bool { std::this_thread::sleep_for(std::chrono::seconds(2)); out = "task done in 2s"; return true; }); } } ImGui::SameLine(); if (ImGui::Button("Run failing task")) { if (!runner.is_busy()) { fn_ui::runner_trigger(runner, [](std::string& out) -> bool { std::this_thread::sleep_for(std::chrono::seconds(1)); out = "simulated failure"; return false; }); } } ImGui::SameLine(); if (ImGui::Button("Reset")) runner.reset(); fn_ui::runner_status(runner, "Working..."); } code_block( "static fn_ui::ProcessRunner r;\n" "if (button(\"Run\", Primary) && !r.is_busy()) {\n" " fn_ui::runner_trigger(r, [](std::string& out) -> bool {\n" " return do_work(&out);\n" " });\n" "}\n" "fn_ui::runner_status(r, \"Working...\");" ); } // --------------------------------------------------------------------------- // candlestick (Viz) // --------------------------------------------------------------------------- void demo_candlestick() { demo_header("candlestick", "v1.0.0", "Grafico de velas OHLC con ImPlot custom rendering. Verde si close >= open, " "rojo si bajista. Tooltip al hover muestra OHLC del dia."); section("OHLC sintetico (30 dias)"); { static std::vector dates, opens, closes, lows, highs; if (dates.empty()) { dates.reserve(30); opens.reserve(30); closes.reserve(30); lows.reserve(30); highs.reserve(30); double price = 100.0; for (int i = 0; i < 30; ++i) { double drift = std::sin(i * 0.4) * 1.2; double o = price; double c = price + drift + (i % 3 == 0 ? -0.6 : 0.4); double l = std::min(o, c) - 0.8 - (i % 5) * 0.1; double h = std::max(o, c) + 0.8 + (i % 4) * 0.1; dates.push_back(double(i)); opens.push_back(o); closes.push_back(c); lows.push_back(l); highs.push_back(h); price = c; } } candlestick("##cs", dates.data(), opens.data(), closes.data(), lows.data(), highs.data(), int(dates.size())); } code_block( "candlestick(\"##cs\", dates, opens, closes, lows, highs, n,\n" " /*width_percent=*/0.25f, /*tooltip=*/true);" ); } // --------------------------------------------------------------------------- // gauge (Viz) // --------------------------------------------------------------------------- void demo_gauge() { demo_header("gauge", "v1.0.0", "Indicador circular tipo velocimetro con ImGui DrawList. Color interpolado " "verde -> amarillo -> rojo segun el valor normalizado."); static float v_cpu = 0.32f, v_mem = 0.78f, v_gpu = 0.55f; section("Tres gauges con sliders"); { ImGui::SliderFloat("cpu", &v_cpu, 0.0f, 1.0f); ImGui::SliderFloat("mem", &v_mem, 0.0f, 1.0f); ImGui::SliderFloat("gpu", &v_gpu, 0.0f, 1.0f); ImGui::Spacing(); ImGui::BeginGroup(); gauge("CPU", v_cpu, 0.0f, 1.0f, 60.0f); ImGui::EndGroup(); ImGui::SameLine(0.0f, 24.0f); ImGui::BeginGroup(); gauge("MEM", v_mem, 0.0f, 1.0f, 60.0f); ImGui::EndGroup(); ImGui::SameLine(0.0f, 24.0f); ImGui::BeginGroup(); gauge("GPU", v_gpu, 0.0f, 1.0f, 60.0f); ImGui::EndGroup(); } code_block("gauge(\"CPU\", 0.32f, 0.0f, 1.0f, 60.0f);"); } // --------------------------------------------------------------------------- // heatmap (Viz) // --------------------------------------------------------------------------- void demo_heatmap() { demo_header("heatmap", "v1.0.0", "Mapa de calor 2D con ImPlot. Datos row-major. Util para correlation " "matrices, attention maps, distribuciones 2D discretas."); constexpr int R = 12; constexpr int C = 12; static float values[R * C] = {0}; static bool init = false; if (!init) { for (int r = 0; r < R; ++r) { for (int c = 0; c < C; ++c) { float dx = (c - C * 0.5f) / float(C); float dy = (r - R * 0.5f) / float(R); values[r * C + c] = std::exp(-(dx * dx + dy * dy) * 6.0f); } } init = true; } section("Gaussian 12x12"); { heatmap("##hm", values, R, C, 0.0f, 1.0f); } code_block( "float values[R * C];\n" "// fill row-major: values[r * C + c] = ...\n" "heatmap(\"##hm\", values, R, C, /*min=*/0.0f, /*max=*/1.0f);" ); } // --------------------------------------------------------------------------- // table_view (Viz) // --------------------------------------------------------------------------- void demo_table_view() { demo_header("table_view", "v1.0.0", "Tabla interactiva con sorting indicators y scroll usando la ImGui Tables API. " "Headers + cells row-major. Util para dashboards y inspectores."); section("Lenguajes del registry"); { const char* headers[] = {"id", "lang", "domain", "purity"}; // 6 filas x 4 cols, row-major const char* cells[] = { "filter_slice_go_core", "go", "core", "pure", "metabase_setup_py_infra", "py", "infra", "impure", "rsync_deploy_bash_infra", "sh", "infra", "impure", "button_cpp_core", "cpp", "core", "pure", "gl_texture_load_cpp_gfx", "cpp", "gfx", "impure", "audio_fft_cpp_core", "cpp", "core", "pure", }; const int row_count = 6; const int col_count = 4; table_view("##tbl", headers, col_count, cells, row_count); } code_block( "const char* headers[] = {\"id\", \"lang\", \"domain\"};\n" "const char* cells[] = {/* row-major: r0c0,r0c1,r0c2, r1c0,... */};\n" "table_view(\"##tbl\", headers, 3, cells, n_rows);" ); } } // namespace gallery