Files
fn_registry/docs/capabilities/data_table_renderers.md
T
egutierrez 7e2fb05144 data_table: declarative cell renderers Phase 1 (Badge/Progress/Duration/Icon)
Adds TableInput.column_specs sidecar field enabling apps to declare Badge,
Progress, Duration and Icon renderers per column without writing ImGui inline.
Back-compat: apps without column_specs compile and behave identically.

- data_table_types.h: CellRenderer enum, BadgeRule, IconMapEntry, ColumnSpec types
- data_table.cpp: hex_to_imcolor helper, icon_name_to_glyph static map (~30 Tabler icons),
  draw_cell_custom dispatcher, integration in Stage-0 and Stage-N cell loops and draw_extra_panel
- Bump version 1.0.0 -> 1.1.0 with capability growth log
- cpp/tests/test_column_specs.cpp: 5 smoke/linker tests (back-compat + 4 renderer types)
- cpp/tests/CMakeLists.txt: register test_column_specs target linked against fn_table_viz
- types/core/{cell_renderer,badge_rule,icon_map_entry,column_spec}.md: registry type mds
- docs/capabilities/data_table_renderers.md: canonical doc with end-to-end examples
- docs/capabilities/INDEX.md: added data-table-renderers group

All tests green: test_column_specs 5/5, test_fn_table_viz_smoke 8/8,
tql_emit 41/41, tql_apply 88/88, Wave-1 tests 8/8.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-15 16:38:24 +02:00

5.1 KiB

data_table_renderers — declarative cell renderers (v1.1.0)

Tag: cpp-tables (mismo grupo que TQL; los renderers son parte del stack data_table).

Extiende data_table_cpp_viz con una API declarativa para renderizar columnas con Badge, Progress, Duration e Icon sin escribir ImGui inline. Activado via el campo opcional column_specs de TableInput. Back-compat 100%: apps sin column_specs no necesitan cambios.

Tipos nuevos en data_table_types.h

Tipo Que es
CellRenderer enum class: Text=0, Badge=1, Progress=2, Duration=3, Icon=4
BadgeRule value (exact match) + color_hex + label opcional
IconMapEntry value + icon_name (ej. "TI_BOLT") + color_hex opcional
ColumnSpec id + renderer + badges / progress fields / duration thresholds / icon_map
TableInput::column_specs std::vector<ColumnSpec> sidecar opcional (size 0 o == cols)

Ejemplo canonico: Recent Executions (status Badge + duration Duration)

#include "viz/data_table.h"
#include "core/data_table_types.h"

// --- Datos (owner externo) ---
static const char* g_exec_cells[] = {
    "ok",    "142",
    "error", "3850",
    "ok",    "72",
    "warn",  "1100",
};

// --- Setup (una vez, en init de la app o antes del loop) ---
data_table::TableInput t;
t.name    = "executions";
t.rows    = 4;
t.cols    = 2;
t.cells   = g_exec_cells;
t.headers = {"status", "duration_ms"};
t.types   = {data_table::ColumnType::String, data_table::ColumnType::Float};

// Columna 0: Badge por valor de status
data_table::ColumnSpec cs_status;
cs_status.id       = "status";
cs_status.renderer = data_table::CellRenderer::Badge;
cs_status.badges   = {
    data_table::BadgeRule{"ok",    "#22c55e", "OK"},
    data_table::BadgeRule{"error", "#ef4444", "ERROR"},
    data_table::BadgeRule{"warn",  "#f59e0b", "WARN"},
};

// Columna 1: Duration con gradiente verde/amarillo/rojo
data_table::ColumnSpec cs_dur;
cs_dur.id                = "duration_ms";
cs_dur.renderer          = data_table::CellRenderer::Duration;
cs_dur.duration_warn_ms  = 500.0f;
cs_dur.duration_error_ms = 2000.0f;

t.column_specs = {cs_status, cs_dur};

data_table::State st;  // persiste entre frames

// --- Render loop ---
ImGui::Begin("Executions");
ImGui::BeginChild("##exec_tbl", ImVec2(-1, -1));
data_table::render("##exec", {t}, st);
ImGui::EndChild();
ImGui::End();

Ejemplo: Progress bar + Icon

data_table::ColumnSpec cs_progress;
cs_progress.id                 = "completion";
cs_progress.renderer           = data_table::CellRenderer::Progress;
cs_progress.progress_scale_100 = true;   // cell value es 0..100
cs_progress.progress_color_hex = "#3b82f6";  // azul; "" -> ImPlot auto

data_table::ColumnSpec cs_icon;
cs_icon.id       = "kind";
cs_icon.renderer = data_table::CellRenderer::Icon;
cs_icon.icon_map = {
    data_table::IconMapEntry{"fn",   "TI_BOLT",     "#3b82f6"},
    data_table::IconMapEntry{"type", "TI_DATABASE", ""},
    data_table::IconMapEntry{"app",  "TI_SETTINGS", "#6b7280"},
};

t.column_specs = {cs_progress, cs_icon};

Iconos soportados en CellRenderer::Icon

El lookup es una tabla estatica de ~30 nombres frecuentes:

TI_CHECK    TI_X           TI_ALERT_CIRCLE   TI_CIRCLE_DOT
TI_CLOCK    TI_LOADER      TI_BAN            TI_PLAYER_PLAY
TI_PLAYER_PAUSE  TI_PLAYER_STOP  TI_DATABASE  TI_SETTINGS
TI_USER     TI_USERS       TI_FILE           TI_FOLDER
TI_REFRESH  TI_BOLT        TI_INFO_CIRCLE    TI_ARROW_UP
TI_ARROW_DOWN  TI_ARROW_RIGHT  TI_ARROW_LEFT  TI_DOTS
TI_EYE      TI_EYE_OFF     TI_EDIT          TI_TRASH
TI_COPY     TI_EXTERNAL_LINK

Si el icon_name no esta en la tabla, la celda se renderiza como texto plano.

Fronteras

  • Solo Column 0..N posicional: column_specs[i] aplica a la columna en posicion i del TableInput original. No se mapea por nombre (Phase 2).
  • No persiste en TQL: column_specs son responsabilidad del caller — se construyen cada frame o en el setup. tql_emit/tql_apply no los tocan (Phase 2 planificado).
  • No implementa Button/TextInput/Custom (Phase 2-3 separados).
  • Stage N (agregado): los renderers se aplican por posicion de columna del output agregado — si el breakout cambia el numero de columnas, revisar los indices.

Gotchas

  • column_specs.size() debe ser 0 (sin specs) o igual a t.cols. Mezcla de tamaños puede causar out-of-bounds silencioso (el render hace c < column_specs.size() guard, pero es mejor ser expliciito).
  • hex_to_imcolor acepta "#rrggbb" o "rrggbb". Alpha siempre 1.0. Sin soporte para rgba.
  • El ColorRule existente de State (st.color_rules) sigue funcionando — ambos sistemas coexisten. Si hay conflicto, column_specs toma prioridad para el contenido de la celda; color_rules pinta el fondo via TableSetBgColor.
  • En el renderer Badge el Selectable con background coloreado consume el item para hover/click — la seleccion de rango con drag puede verse afectada visualmente en columnas Badge.

Notas

  • Tests: cpp/tests/test_column_specs.cpp (5 tests: 1 back-compat + 4 renderer types). Smoke/linker; no requieren ImGui context.
  • TQL roundtrip pendiente: issue 0081-O (Phase 2).