From 2cd34c82da7e745a2f9cfac90715f745f4487036 Mon Sep 17 00:00:00 2001 From: sergio Date: Sun, 17 May 2026 12:07:45 +0000 Subject: [PATCH] =?UTF-8?q?feat(tahuantinsuyu):=20fase=2018=20=E2=80=94=20?= =?UTF-8?q?aspect=20list=20+=20hover=20tooltips=20+=20dignidades=20+=20exp?= =?UTF-8?q?ort=20SVG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fase grande con 4 features que aprovechan toda la infraestructura ya construida. Engine ganó 2 módulos nuevos (dignity table data-only + svg_export), el RenderModel se enriqueció con AspectSummary y los glyphs con dignity_marker, y el canvas trae hit-test pasivo + lista textual + botón de export. ## C — Lista textual de aspectos - engine: nuevo `AspectSummary { module_id, from_body, to_body, kind, orb_deg, applying }` + campo `aspect_summary: Vec` en RenderModel. populate_natal_aspect_summary y populate_cross_aspect_summary se llaman desde compose por cada pasada (natal + 4 overlays). Ordenado por orb_deg asc (los más exactos primero). - canvas: nuevo aspect_unicode helper (☌ ☍ △ □ ⚹ ⚻ ⚺ ∠ ⚼ Q bQ). Footer agrega un grid flex-wrap con las top 12 entries del summary, cada una formateada como "[module_id] ☉ △ ☾ · 2.3° A" coloreado por palette.aspect(kind). ## A — Tooltips al hover - canvas: nuevo HoverInfo { module_id, symbol, deg, house, retrograde, dignity_marker, annotation, local_x, local_y } + state.hover. on_hover_check ejecuta hit-test sobre todos los glyphs Bodies + Outer (threshold 14px); se llama desde el handler MouseMoveEvent cuando NO está dragging (handler reescrito para soportar drag y hover en mismo callback). Cuando mouse sale del wheel, hover=None. - Tooltip absoluto: "☉ Tauro · 23.4° · Casa 5 · ℞" con border angle_highlight. Posición offset arriba-derecha del planeta, clampada al wheel para no salirse. ## B — Dignidades esenciales clásicas - engine: nuevo mod `dignity` con `Dignity { Rulership/Exaltation/ Detriment/Fall }` + tabla rules_classical (7 planetas tradicionales) + exalts_at table. `essential_dignity(body, sign_index) -> Option`. 4 tests cubren rulership/detriment/exaltation/fall + edge case modernos (Urano/Nept/Plutón sin dignidad clásica). 4 markers: + (domicilio), · (exaltación), − (exilio), * (caída). - engine: Glyph gana campo `dignity_marker: Option`. Default derive en Glyph para no romper N construction sites. bridge:: annotate_dignities mutua RenderModel post-build agregando markers a glyphs natales según el signo de cada placement. - NatalOptions agrega show_dignities. NatalModule.controls() agrega Toggle "Dignidades esenciales (+ · − *)" default false. - canvas: glyph render append dignity_marker al texto después del ᴿ. ## D — Export SVG - engine: nuevo `pub mod svg_export` con `render_to_svg(&RenderModel) -> String`. Reproduce la geometría del canvas en un SVG standalone 800×800 escalable: anillos zodiacales, cusps, planetas con retrograde+dignity markers, aspectos coloreados por kind (cross conocen rings de origen/destino vía aspect_radii), labels ASC/MC/ DESC/IC. Sin dependencias nuevas — write! sobre String. Test asserts well-formed XML. - canvas: CanvasEvent::ExportSvgRequested + botón pequeño "⬇ SVG" en el header del wheel (al lado del title). - shell: on_canvas_event ExportSvgRequested → export_current_to_svg recompose actual + svg_export::render_to_svg + write a $XDG_DATA_HOME/tahuantinsuyu/exports/