fdf7c82bd7
Anade 5 entradas a la gallery (treemap, sankey, chord, contour, voronoi) con datos sinteticos coherentes: - treemap: 6 items 'gastos por categoria' - sankey: 8 nodos clientes -> productos -> categorias (DAG) - chord: matriz 6x6 simetrica de flujos entre paises - contour: mezcla de 2 gaussianas 32x32 + 5 niveles - voronoi: 30 seeds aleatorias + colores aleatorios Wire-up additions only (demos.h, main.cpp k_demos[], CMakeLists.txt).
172 lines
7.1 KiB
C++
172 lines
7.1 KiB
C++
// primitives_gallery — catalogo visual interactivo de los primitivos UI
|
|
// del registry (cpp/functions/core y cpp/functions/viz).
|
|
//
|
|
// Sidebar izquierdo con lista de primitivos agrupados por dominio; panel
|
|
// derecho renderiza la demo del item seleccionado (+ snippet de codigo).
|
|
//
|
|
// Rol: smoke test visual + documentacion viva + build gate en CI.
|
|
// NO se conecta a sqlite_api ni a ningun backend. Datos sinteticos.
|
|
|
|
#include "app_base.h"
|
|
#include "imgui.h"
|
|
#include "core/fullscreen_window.h"
|
|
#include "core/tokens.h"
|
|
#include "core/page_header.h"
|
|
#include "core/toast.h"
|
|
#include "core/app_menubar.h"
|
|
#include "gfx/gl_loader.h"
|
|
|
|
#include "demos.h"
|
|
#include "demo.h"
|
|
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
struct DemoEntry {
|
|
const char* id; // id estable, apto para comparar seleccion
|
|
const char* label; // texto en sidebar
|
|
const char* category; // "Core" o "Viz"
|
|
void (*fn)(); // puntero a la demo_xxx
|
|
};
|
|
|
|
static const DemoEntry k_demos[] = {
|
|
// Core
|
|
{"button", "button", "Core", &gallery::demo_button},
|
|
{"icon_button", "icon_button", "Core", &gallery::demo_icon_button},
|
|
{"toolbar", "toolbar", "Core", &gallery::demo_toolbar},
|
|
{"modal_dialog", "modal_dialog", "Core", &gallery::demo_modal},
|
|
{"text_input", "text_input", "Core", &gallery::demo_text_input},
|
|
{"select", "select", "Core", &gallery::demo_select},
|
|
{"toast", "toast + inbox", "Core", &gallery::demo_toast},
|
|
{"tree_view", "tree_view", "Core", &gallery::demo_tree_view},
|
|
{"badge", "badge", "Core", &gallery::demo_badge},
|
|
{"empty_state", "empty_state", "Core", &gallery::demo_empty_state},
|
|
{"page_header", "page_header", "Core", &gallery::demo_page_header},
|
|
{"dashboard_panel", "dashboard_panel", "Core", &gallery::demo_dashboard_panel},
|
|
{"kpi_card", "kpi_card", "Core", &gallery::demo_kpi_card},
|
|
{"text_editor", "text_editor", "Core", &gallery::demo_text_editor}, // wave 1
|
|
{"file_watcher", "file_watcher", "Core", &gallery::demo_file_watcher}, // wave 1
|
|
{"process_runner", "process_runner", "Core", &gallery::demo_process_runner},
|
|
// Viz
|
|
{"bar_chart", "bar_chart", "Viz", &gallery::demo_bar_chart},
|
|
{"pie_chart", "pie_chart", "Viz", &gallery::demo_pie_chart},
|
|
{"line_plot", "line_plot", "Viz", &gallery::demo_line_plot},
|
|
{"scatter_plot", "scatter_plot", "Viz", &gallery::demo_scatter_plot},
|
|
{"histogram", "histogram", "Viz", &gallery::demo_histogram},
|
|
{"sparkline", "sparkline", "Viz", &gallery::demo_sparkline},
|
|
{"graph_viewport", "graph_viewport", "Viz", &gallery::demo_graph},
|
|
{"candlestick", "candlestick", "Viz", &gallery::demo_candlestick},
|
|
{"gauge", "gauge", "Viz", &gallery::demo_gauge},
|
|
{"heatmap", "heatmap", "Viz", &gallery::demo_heatmap},
|
|
{"table_view", "table_view", "Viz", &gallery::demo_table_view},
|
|
{"treemap", "treemap", "Viz", &gallery::demo_treemap},
|
|
{"sankey", "sankey", "Viz", &gallery::demo_sankey},
|
|
{"chord", "chord", "Viz", &gallery::demo_chord},
|
|
{"contour", "contour", "Viz", &gallery::demo_contour},
|
|
{"voronoi", "voronoi", "Viz", &gallery::demo_voronoi},
|
|
// Gfx (shaders_lab core)
|
|
{"shader_canvas", "shader_canvas", "Gfx", &gallery::demo_shader_canvas},
|
|
{"gl_texture", "gl_texture_load", "Gfx", &gallery::demo_gl_texture}, // wave 1
|
|
};
|
|
static constexpr int k_demo_count = sizeof(k_demos) / sizeof(k_demos[0]);
|
|
|
|
static std::string g_selected_id = "button";
|
|
|
|
static const DemoEntry* find_demo(const std::string& id) {
|
|
for (int i = 0; i < k_demo_count; i++) {
|
|
if (id == k_demos[i].id) return &k_demos[i];
|
|
}
|
|
return &k_demos[0];
|
|
}
|
|
|
|
static void draw_sidebar() {
|
|
using namespace fn_tokens;
|
|
ImGui::BeginChild("##gallery_sidebar", ImVec2(220, 0),
|
|
ImGuiChildFlags_Borders);
|
|
|
|
const char* current_category = nullptr;
|
|
for (int i = 0; i < k_demo_count; i++) {
|
|
const auto& d = k_demos[i];
|
|
if (!current_category || std::strcmp(current_category, d.category) != 0) {
|
|
if (current_category) ImGui::Dummy(ImVec2(0, spacing::sm));
|
|
ImGui::PushStyleColor(ImGuiCol_Text, colors::text_dim);
|
|
ImGui::TextUnformatted(d.category);
|
|
ImGui::PopStyleColor();
|
|
ImGui::Separator();
|
|
current_category = d.category;
|
|
}
|
|
|
|
const bool selected = (g_selected_id == d.id);
|
|
ImGui::PushStyleColor(ImGuiCol_Header, selected ? colors::surface_hover : ImVec4(0,0,0,0));
|
|
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, colors::surface_hover);
|
|
ImGui::PushStyleColor(ImGuiCol_HeaderActive, colors::surface);
|
|
ImGui::PushStyleColor(ImGuiCol_Text, selected ? colors::primary : colors::text);
|
|
|
|
char label[96];
|
|
std::snprintf(label, sizeof(label), "%s##sel_%s", d.label, d.id);
|
|
if (ImGui::Selectable(label, selected)) {
|
|
g_selected_id = d.id;
|
|
}
|
|
|
|
ImGui::PopStyleColor(4);
|
|
}
|
|
|
|
ImGui::EndChild();
|
|
}
|
|
|
|
static void render() {
|
|
static bool init_done = false;
|
|
if (!init_done) {
|
|
fn_tokens::apply_dark_theme();
|
|
// En Linux es no-op; en Windows resuelve los punteros GL via wglGetProcAddress.
|
|
// Imprescindible antes de invocar primitivos que usen OpenGL 2.0+ (graph_viewport,
|
|
// shader_canvas, etc).
|
|
fn::gfx::gl_loader_init();
|
|
init_done = true;
|
|
}
|
|
|
|
// MainMenuBar (solo Settings — la gallery no tiene paneles toggleables ni layouts)
|
|
fn_ui::app_menubar(nullptr, 0, nullptr);
|
|
|
|
fullscreen_window_begin("##gallery");
|
|
|
|
page_header_begin("Primitives Gallery",
|
|
"Visual catalog of fn_registry C++ UI primitives");
|
|
page_header_end();
|
|
|
|
if (ImGui::BeginTable("##layout", 2,
|
|
ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingFixedFit)) {
|
|
ImGui::TableSetupColumn("sidebar", ImGuiTableColumnFlags_WidthFixed, 220.0f);
|
|
ImGui::TableSetupColumn("content", ImGuiTableColumnFlags_WidthStretch);
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableSetColumnIndex(0);
|
|
draw_sidebar();
|
|
|
|
ImGui::TableSetColumnIndex(1);
|
|
ImGui::BeginChild("##gallery_content", ImVec2(0, 0),
|
|
ImGuiChildFlags_Borders,
|
|
ImGuiWindowFlags_HorizontalScrollbar);
|
|
const DemoEntry* d = find_demo(g_selected_id);
|
|
if (d && d->fn) d->fn();
|
|
ImGui::EndChild();
|
|
|
|
ImGui::EndTable();
|
|
}
|
|
|
|
fullscreen_window_end();
|
|
|
|
// Toasts se renderizan encima para que el demo de toast funcione aqui tambien.
|
|
fn_ui::toast_render();
|
|
}
|
|
|
|
int main(int /*argc*/, char** /*argv*/) {
|
|
return fn::run_app(
|
|
{.title = "fn_registry · Primitives Gallery",
|
|
.width = 1400, .height = 900, .viewports = true},
|
|
render
|
|
);
|
|
}
|