feat(tahuantinsuyu): fase 5 — overlay de tránsitos (bi-wheel natal × ahora)
Activá el toggle "Tránsitos (ahora)" en el panel (o hotkey [T] sobre el wheel): la engine computa una segunda NatalChart al instante SystemTime::now() con el mismo observer y dibuja un anillo externo de planet glyphs encima del natal, más las cross-aspects entre ambos charts (sólo mayores). Las líneas cross van del ring de cuerpos natales al ring externo de tránsitos, con stroke más fino y opacidad más baja para no taparle el ojo a las aspectos natal-natal. - engine/bridge.rs: extraídas build_eternal_inputs y compute_natal_chart como helpers reutilizables. Nueva compute_with_transits(chart, offset, transit_at) que llama find_synastry_aspects entre natal y transit (AspectKind::MAJORS). Atajo compute_with_transits_at_now usa ESInstant::now(). Las capas extra van con module_id = "transit" y LayerKind::Outer / LayerKind::Aspects para que el canvas las distinga. - engine/lib.rs: re-export de compute_with_transits_at_now con el mismo fallback al mock cuando feature `eternal-bridge` está off. - canvas: nueva Radii::transits = 0.82, layout del wheel re-balanceado (houses_outer 0.78, houses_inner 0.66, bodies 0.58, aspects 0.50) para hacer lugar al anillo externo sin colisiones. paint_wheel: detecta layers de transit por module_id, pinta dots + glifos en el anillo nuevo + anillos guía sutiles. paint_cross_aspect_line con stroke 0.7 entre los dos radios. Glyph overlay para Outer ring con alpha 0.9 y font_size más chico que el natal. Hotkey [T] en on_key_down toggle LayerKind::Outer. - modules: NatalModule.controls() agrega toggle show_transits con hotkey [T] (default false — no recomputar transits si nadie pidió). - shell: nuevo show_transits flag. render_current despacha entre compute_at_offset y compute_with_transits_at_now según el flag. on_panel_event traduce ControlChanged show_transits a flip + redraw. on_canvas_event: el toggle de LayerKind::Outer dispara show_transits flip + render (no es un visibility toggle puro). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,7 @@ use gpui::{
|
||||
use tahuantinsuyu_canvas::{
|
||||
AstrologyCanvas, CanvasEvent, CanvasMode, ThumbnailItem, ThumbnailScope,
|
||||
};
|
||||
use tahuantinsuyu_engine::{LayerKind, compute_at_offset};
|
||||
use tahuantinsuyu_engine::{LayerKind, compute_at_offset, compute_with_transits_at_now};
|
||||
use tahuantinsuyu_model::{Chart, TreeSelection};
|
||||
use tahuantinsuyu_panel::{ControlPanel, PanelEvent};
|
||||
use tahuantinsuyu_store::Store;
|
||||
@@ -44,6 +44,9 @@ pub struct Shell {
|
||||
/// recomputarla con time-offsets sin re-leer la DB cada vez.
|
||||
current_chart: Option<Chart>,
|
||||
current_offset_minutes: i64,
|
||||
/// Overlay de tránsitos al instante actual sobre la natal. Disparado
|
||||
/// por el toggle `show_transits` del panel o la hotkey `[T]`.
|
||||
show_transits: bool,
|
||||
}
|
||||
|
||||
impl Shell {
|
||||
@@ -78,6 +81,7 @@ impl Shell {
|
||||
panel,
|
||||
current_chart: None,
|
||||
current_offset_minutes: 0,
|
||||
show_transits: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,12 +168,20 @@ impl Shell {
|
||||
let Some(chart) = self.current_chart.as_ref() else {
|
||||
return;
|
||||
};
|
||||
let render = match compute_at_offset(chart, self.current_offset_minutes) {
|
||||
let result = if self.show_transits {
|
||||
compute_with_transits_at_now(chart, self.current_offset_minutes)
|
||||
} else {
|
||||
compute_at_offset(chart, self.current_offset_minutes)
|
||||
};
|
||||
let render = match result {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"[shell] compute_at_offset {} (+{}min): {}",
|
||||
chart.id, self.current_offset_minutes, e
|
||||
"[shell] compute {}{} (+{}min): {}",
|
||||
chart.id,
|
||||
if self.show_transits { " +transits" } else { "" },
|
||||
self.current_offset_minutes,
|
||||
e
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -193,8 +205,17 @@ impl Shell {
|
||||
}
|
||||
}
|
||||
CanvasEvent::LayerVisibilityChanged { kind, visible } => {
|
||||
// Sync el panel para que el toggle visual coincida con
|
||||
// lo que disparó el hotkey en el canvas.
|
||||
// El toggle de Outer (hotkey [T]) significa "transit
|
||||
// overlay" — no es solo un layer hide, dispara un
|
||||
// recompute distinto. El resto son visibility puros.
|
||||
if matches!(kind, LayerKind::Outer) {
|
||||
self.show_transits = *visible;
|
||||
self.panel.update(cx, |p, cx| {
|
||||
p.set_toggle("natal", "show_transits", *visible, cx)
|
||||
});
|
||||
self.render_current(cx);
|
||||
return;
|
||||
}
|
||||
let key = match kind {
|
||||
LayerKind::SignDial => "show_sign_dial",
|
||||
LayerKind::Houses => "show_houses",
|
||||
@@ -213,9 +234,19 @@ impl Shell {
|
||||
|
||||
fn on_panel_event(&mut self, ev: &PanelEvent, cx: &mut Context<Self>) {
|
||||
match ev {
|
||||
PanelEvent::ControlChanged { module_id, key, value } => {
|
||||
PanelEvent::ControlChanged {
|
||||
module_id, key, value,
|
||||
} => {
|
||||
let visible = value.as_bool().unwrap_or(true);
|
||||
if module_id == "natal" {
|
||||
if key == "show_transits" {
|
||||
self.show_transits = visible;
|
||||
self.canvas.update(cx, |c, cx| {
|
||||
c.set_layer_visible(LayerKind::Outer, visible, cx)
|
||||
});
|
||||
self.render_current(cx);
|
||||
return;
|
||||
}
|
||||
let kind = match key.as_str() {
|
||||
"show_sign_dial" => Some(LayerKind::SignDial),
|
||||
"show_houses" => Some(LayerKind::Houses),
|
||||
@@ -230,7 +261,7 @@ impl Shell {
|
||||
}
|
||||
}
|
||||
PanelEvent::ModuleToggled { .. } => {
|
||||
// Fase 5: encender/apagar módulos enteros (Transit,
|
||||
// Fase 6: encender/apagar módulos enteros (Progression,
|
||||
// Synastry, Uranian).
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user