--- name: data_table_grid kind: function lang: cpp domain: viz version: "1.0.0" purity: impure signature: "void data_table::render_grid_stage0(const char* id, State& st, const char* const* cells, int row_count, int orig_cols, int eff_cols, const char* const* eff_headers, const ColumnType* eff_types, const int* src_for_eff, const std::vector& visible_rows, const TableInput& main_t, std::vector* events_out)" description: "Render del grid de datos de la tabla TQL: ImGui::BeginTable con freeze de cabecera, headers clicables (sort), drag-drop de columnas para reordenar, renderers declarativos por ColumnSpec (Badge/Progress/Duration/Icon/Button/Dots/CategoricalChip/ColorScale), aplicacion de ColorRules por celda, seleccion de rango (Ctrl+C TSV), stats overlay en encabezados. Dos entrypoints: render_grid_stage0 (datos crudos + derived Lua) y render_grid_stage_n (output materializado de compute_stage). Sub-funcion extraida de modules/data_table/data_table.cpp (issue 0107c)." tags: [viz, table, imgui, ui, grid, cell-renderer, sorting, tql, cpp-tables] uses_functions: - data_table_color_rules_cpp_viz - data_table_cpp_viz uses_types: - data_table_types_cpp_core returns: [] returns_optional: false error_type: "error_go_core" imports: [imgui] tested: false tests: [] test_file_path: "" file_path: "cpp/functions/viz/data_table_grid.cpp" framework: imgui params: - name: id desc: "ID unico de ImGui para BeginTable (ej. '##my_table'). Debe ser unico por instancia en la ventana." - name: st desc: "State mutable. El grid lee st.col_order, st.col_visible, st.color_rules, st.sel_anchor/end, st.stages[active].sorts. Lo muta en respuesta a clicks, drag-drop, seleccion." - name: cells desc: "Puntero a cells originales row-major [rows * orig_cols]. Para stage0; stage_n recibe cur_cells ya materializados." - name: row_count / orig_cols / eff_cols desc: "Dimensiones de la tabla. orig_cols = columnas del input; eff_cols = orig_cols + derived cols del stage 0." - name: eff_headers / eff_types desc: "Headers y tipos efectivos (size eff_cols). Usados para headers del BeginTable y para render de celda." - name: src_for_eff desc: "Mapeo eff_col_idx -> src_col_idx en la tabla original. Necesario para leer cells[row * orig_cols + src]. Solo para stage0." - name: visible_rows desc: "Indices de filas visibles tras filtrado (output de compute_visible_rows). Solo para stage0." - name: main_t desc: "TableInput principal: proporciona column_specs para draw_cell_custom y los column_spec ids para eventos." - name: events_out desc: "Si no null, recibe TableEvent (ButtonClick, RowDoubleClick, RowRightClick) generados este frame." output: "Void. Mutates st (sort, selection, col_order). Appends to events_out si no null." --- ## Documentacion Sub-funcion que encapsula el render del grid de celdas de la tabla TQL. Es el bloque mas grande del refactor 0107c (~1300 LOC del fuente original). ### Renderers declarativos (draw_cell_custom) | Renderer | Que muestra | |---|---| | `Text` | Selectable de texto, tooltip on-hover si `tooltip_on_hover=true` | | `Badge` | Pastilla de color (background del spec) con texto | | `Progress` | Barra de progreso ImGui [0..100] | | `Duration` | Formato "Xh Ym Zs" desde segundos enteros | | `Icon` | Glyph Tabler (usa `icons_tabler.h`) | | `Button` | Boton clickable; emite `TableEventKind::ButtonClick` con `action_id` | | `Dots` | Circulos coloreados por reglas de chips del ColumnSpec | | `CategoricalChip` | Pastilla con borde coloreado; color por palette hash | | `ColorScale` | Degradado de fondo segun valor numerico normalizado | ### Flujo render_grid_stage0 1. Setup `ImGuiTableFlags` (Borders + RowBg + Resizable + ScrollY). 2. `BeginTable` → `TableSetupColumn` por cada col visible en `st.col_order`. 3. `TableSetupScrollFreeze(0, 1)` para freeze de header. 4. Header row: `Selectable` con sort-click (`apply_header_sort_click`), drag-drop source/target para reordenar columnas. 5. Por cada fila en `visible_rows`: por cada col visible en `st.col_order`: `apply_color_rules_for_cell` → `draw_cell_custom`. 6. Seleccion de rango: mouse drag con `sel_anchor/sel_end`; Ctrl+C genera TSV al portapapeles. 7. `EndTable` + `PopStyleColor(3)`. ### Flujo render_grid_stage_n Igual pero opera sobre `cur_cells` ya materializados del chain `compute_stage`. Ademas: - Stats overlay en headers (histograma/top-categories de `st.stats_cache`). - Drill popup: right-click en celda de breakout col ofrece "Drill into: col = val". ## Ejemplo ```cpp // Dentro del render() principal, path stage == 0: if (st.display == data_table::ViewMode::Table && visible_cols > 0) { data_table::render_grid_stage0(id, st, cells_in, row_count_in, orig_cols, eff_cols, eff_headers.data(), eff_types.data(), src_for_eff.data(), visible_rows, main_t, events_out); } ``` ## Cuando usarla Llamar desde el entrypoint thin `data_table::render()` tras calcular `visible_rows` (stage 0) o materializar el chain (stage > 0). No llamar directamente desde apps — la API publica es `data_table::render()`. ## Gotchas - `render_grid_stage0` y `render_grid_stage_n` deben llamarse dentro de un `ImGui::BeginChild` o contexto de ventana activo. No funcionan fuera de un frame ImGui. - La funcion hace `PushStyleColor` para Header/HeaderHovered/HeaderActive y debe hacer el correspondiente `PopStyleColor(3)`. No anidar pushes adicionales sin su pop. - `draw_cell_custom` con renderer `Button` emite eventos; si `events_out` es null se ignoran silenciosamente (back-compat). - El `thread_local` en el entrypoint original (main_hdr_ptrs, joinables_v) no se mueve a esta funcion — esos son responsabilidad del entrypoint thin. - Despues del split, `apply_color_rules_for_cell` vive en `data_table_color_rules_cpp_viz` — no re-implementar aqui.