- toast.cpp: TI_BELL en lugar de \xf0\x9f\x94\x94 (fuera del rango cargado por icon_font, renderizaba como ?)
- candlestick.cpp: SetupAxes/SetupAxisScale/SetupAxisLimits movidos dentro de BeginPlot/EndPlot — antes el plot desaparecia al entrar
- pie_chart.cpp: SetupLegend(East, Outside, NoButtons), eliminado NoLegend
- kpi_card.cpp: layout 2 cols con sparkline a la derecha centrado verticalmente
- docs/adr/0002-apps-analyses-as-dataforge-master.md: decision arquitectural
con contexto, alternativas descartadas y cambios concretos del 2026-04-28.
- CHANGELOG.md: entrada 2026-04-28 con Added/Changed/Fixed.
- .claude/CLAUDE.md: nota sobre /full-git-push y dataforge/<name>+master.
- .claude/rules/apps_tbd.md: tronco unico master + init.defaultBranch.
- cpp/functions/core/app_menubar.md: notas del submenu Settings con About.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cpp/core: nuevo modulo app_about — ventana About con project/version/desc,
componible via about_window_set_info() en el init de la app y rendererizada
automaticamente por fn::run_app al final de cada frame.
app_menubar: el item top-level "Settings..." pasa a ser un BeginMenu
"Settings" con dos subitems: "Settings..." (existente) y "About..." (nuevo).
bash/infra: nueva pipeline ensure_repo_synced que compone gitea_create_repo
y gitea_push_directory para garantizar repo Gitea existente + sync de un
directorio local en una sola llamada idempotente.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Timeline widget with:
- Header: play/pause + reset + duration drag + loop checkbox
- Ruler: 0.5s ticks, scrub via click+drag
- Tracks: horizontal rows with diamond-shaped draggable keyframes
- Playhead: vertical primary_light line + ruler triangle marker
State and types:
- Keyframe { time, value, ease }
- Track { name, vector<Keyframe> }
- TimelineState { tracks, current_time, duration, playing, loop }
Pure functions:
- track_value_at(track, t): interp between keys, ease applied via the
destination keyframe (Maya/AfterEffects convention)
- timeline_update(state, dt): advance current_time, wrap or saturate
Render with fn_tokens for visual coherence with the rest of the design
system. Keys are sorted by time on every changed frame to keep order
consistent during drag.
ImGui canvas with 4 draggable control points (p0/p3 locked at (0,0)/(1,1)
by default for use as easing curves). Pure evaluation via De Casteljau
(bezier_point) plus sampling-based y(x) lookup (bezier_eval).
Render uses fn_tokens for visual coherence: bg, border, primary curve,
text_dim diagonal reference, text_muted handle tangents.
p1.x and p2.x clamped to [0,1] to keep the curve usable as easing; Y
values are free to allow deliberate overshoot.
16 easing curves (linear, quad, cubic, expo, elastic, bounce in/out/inOut)
header-mostly so the compiler inlines on hot paths. Pure, no I/O, no state.
Includes:
- tween::apply(Ease, t) dispatcher for data-driven uses (timeline keyframe.ease,
dropdown selection)
- tween::name(Ease) for UI labels
- tween::ease_count for iteration
Tested values documented in tween_curves.md.
5 primitivas que componen el chrome de una app fn_ui completa:
- app_settings_cpp_core (function, impure) ventana flotante de
settings globales (Display + Typography + secciones extra registrables) con
persistencia automatica en app_settings.ini junto al ejecutable.
- app_menubar_cpp_core (component, pure) MainMenuBar unificada
con menu View (toggles de paneles) y Layouts. Punto de entrada de la
menubar de cualquier app fn_ui.
- layouts_menu_cpp_core (component, pure) menu para guardar/aplicar/
borrar/reset layouts de ImGui via callbacks (no I/O propio).
- panel_menu_cpp_core (component, pure) menu checkable para
abrir/cerrar paneles, composable dentro de la MainMenuBar.
- layout_storage_sqlite_cpp_core (function, impure) primitivas CRUD de bajo
nivel para persistir blobs INI de ImGui en sqlite (ui_layouts table).
Permiten que apps como shaders_lab y registry_dashboard ofrezcan: panel
toggles, layouts persistentes en BD, ventana de settings con preview en
vivo. Todas usan tokens_cpp_core para el styling.
Anade 9 primitivas reutilizables al registry C++ que replican el comportamiento
de los componentes correspondientes de @fn_library / Mantine v9, todas
estilizadas con tokens_cpp_core (colores Mantine dark + indigo):
- button_cpp_core (component, pure) variantes primary/secondary/subtle/danger + sm/md/lg
- icon_button_cpp_core (component, pure) cuadrado 28x28 con glyph centrado + tooltip
- toolbar_cpp_core (component, pure) grupo horizontal de acciones con separadores
- modal_dialog_cpp_core (component, pure) popup modal centrada + close con Escape
- text_input_cpp_core (component, impure) InputText con label muted + placeholder
- select_cpp_core (component, impure) dropdown con label + opcion '(none)' opcional
- toast_cpp_core (component, impure) notificaciones efimeras + inbox con badge
- tree_view_cpp_core (component, impure) jerarquia low-level con tree_node_clicked helper
- process_runner_cpp_core (component, impure) tarea en std::thread + spinner inline
Cada primitiva tiene su .md con frontmatter completo (params/output) y se
indexa via fn index. Son la base del primitives_gallery y de cualquier
app fn_ui futura.
icon_font_cpp_core (impure): carga Karla-Regular como texto vectorial y
mergea Tabler Icons al mismo tamano en el atlas de ImGui. Tras el call,
los TI_* renderizan inline con el texto.
icons_tabler.h: header con macros TI_<NAME> que apuntan a los codepoints
del set Tabler (UTF-8 escapado). Generado a partir del CSS del vendor con
cpp/vendor/tabler-icons/gen_header.py — re-ejecutable si se actualiza el
set sin tocar a mano los ~5500 codepoints.
Justifica la regla cpp_icons.md: todas las apps C++ usan TI_* en lugar de
emoji o hex inline.
Wave 1 de parallel-fix-issues integrada a master:
- 0025: text_editor_cpp_core + file_watcher_cpp_core
- 0026: gl_texture_load_cpp_gfx (vendor: stb_image v2.30)
Ademas se commitea WIP previo de master que estaba sin commitear (cambios
en shaders_lab, dag_*, framework, tokens, kpi_card, gl_loader.md, etc.)
para dejar HEAD buildable.
Notas:
- Algunos deps del gallery (button.cpp, toolbar.cpp, modal_dialog.cpp...)
siguen UNTRACKED — gating con FN_BUILD_GALLERY=ON (default OFF) para
que master build (sin flag) no los necesite.
- Build OK con y sin flag. fn index registra 904 functions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Watcher de archivos no bloqueante con backend nativo por plataforma:
- Linux: inotify_init1(IN_NONBLOCK | IN_CLOEXEC), inotify_add_watch con
mascara MODIFY|CREATE|DELETE|CLOSE_WRITE|MOVED_*. Drain en cada poll().
- Windows: ReadDirectoryChangesW overlapped + GetOverlappedResult no
bloqueante. Para vigilar un archivo, registra el directorio padre y filtra
por nombre exacto en el poll().
- Otros: stub — poll() devuelve vacio y last_error() reporta no soportado.
API en namespace fn:: con tipos opacos (FileWatcher PIMPL). Errores via
last_error() en vez de excepciones. Documentadas las limitaciones (limite de
inotify watches en Linux, granularidad directorio-level en Windows, no
recursividad).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wrapper en namespace fn:: sobre ImGuiColorTextEdit. La API publica solo expone
TextEditorState como tipo opaco; el TextEditor del vendor vive dentro del .cpp.
Soporta CodeLang::{Generic, GLSL, SQL, Cpp} (highlighting via las
LanguageDefinition del vendor). text_editor_render() devuelve true en el frame
en que el contenido cambia; flag dirty manejado independientemente para casos
"editado pero aun no guardado".
text_editor_get_text() cachea el resultado en un std::string del state para
mantener el const char* valido entre llamadas (el GetText() del vendor devuelve
std::string por valor).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nuevo primitivo compartido:
- cpp/functions/viz/plot_static.h: header-only con flags ImPlotFlags /
ImPlotAxisFlags agrupados (NoFrame|NoMenus|NoBoxSelect|NoMouseText +
Lock|NoInitialFit|NoHighlight) para visualizacion estatica en
dashboards. Lo usan todos los charts de viz/.
Charts refactorizados a v1.1 con parametro `height` explicito (rompe el
feedback loop con contenedores AutoResizeY que producia vibracion al
redimensionar) y ejes pineados con ImPlotCond_Always:
- bar_chart v1.2: tooltip al hover (label + valor) + auto-rotacion de
labels a 45 cuando no caben horizontalmente (medidos con CalcTextSize
vs ancho del plot). Los labels rotados se dibujan manualmente con
ImDrawList::PrimQuadUV + ImFontBaked::FindGlyph (API ImGui 1.92+).
- pie_chart v1.1: tooltip por slice (detecta cual via atan2 desde centro
en sentido CCW matematico, que es como ImPlot dibuja los slices desde
angle0=90) con label + valor + porcentaje. Aspect 1:1 mantenido.
- line_plot, scatter_plot, histogram v1.1: ejes pineados con limites
calculados de min/max + 5% headroom (histogram usa AutoFit por los
bins dinamicos, con Lock para bloquear pan/zoom).
kpi_card v1.2: card mas compacta — altura 78px (antes 108), font scale
1.4x (antes 1.8x), padding sm (antes md). Apto para densidades altas
de KPIs en dashboards.
fullscreen_window v0.2: NoScrollbar|NoScrollWithMouse para eliminar el
scrollbar fugaz que aparecia cuando el contenido excedia por 1-2px la
ventana, reflow de ancho y vibracion visible al redimensionar.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Trasladar principios del DESIGN_SYSTEM.md de @fn_library (Mantine/React)
al mundo C++/ImGui sin añadir deps externas:
cpp/functions/core/
tokens — colors/spacing/radius/font_size como constexpr +
apply_dark_theme() al ImGuiStyle global. Dark + indigo
primary (Mantine-inspired).
badge — etiqueta inline 6 variantes (Default/Success/Warning/
Error/Info/Outline). <Badge> de @fn_library en C++.
empty_state — placeholder centrado para tablas/listas vacías.
page_header — header con title + subtitle + separator + hueco
para acciones (patrón begin/end).
Scope limitado (KISS) a fases 1-2 del plan: tokens + 3 primitivos.
No se duplica dashboard_panel con un "card" — el existente ya cumple
el rol. Fases 3-5 (charts ImPlot line/area, app_shell con navbar,
toast/alert) quedan fuera hasta que el dashboard crezca en alcance.
Resultado:
- 869 funciones (+4) en registry.db.
- Dashboard con header homogéneo y empty states en todas las tablas.
- Sin hardcode de ImVec4 disperso en views.cpp.
Diary + CHANGELOG actualizados.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Componente que crea una ventana ImGui fullscreen sin decoraciones, eliminando
la necesidad de usar el sistema de ventanas interno. Usado por registry_dashboard.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Añade soporte C++ al registry: vendor submodules (glfw, imgui, implot, tracy),
sistema de build con CMake y toolchains cross-platform, runner C++ en fn CLI,
parser de tests Google Test, y funciones bash para build Linux/Windows.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>