feat(tahuantinsuyu): fase 4 — jog-dial perimetral, hotkeys y panel interactivo
Time scrubbing por drag en el aro exterior del wheel: rota visualmente mientras dura el drag, al soltar traduce el delta angular a minutos (1° = 4 min sideral, CW = forward) y emite CanvasEvent::TimeOffsetChanged. La Shell recomputa con engine::compute_at_offset y el ascendant rotado queda en la nueva posición. Snap visual a 0° tras commit. - engine: nueva variante compute_at_offset(chart, minutes) que suma segundos al UTC base via add_seconds + Instant::from_utc y corre la pipeline normal. compute() es ahora wrapper con offset=0. - canvas: estado nuevo layer_visibility + drag_jog. Mouse handlers registrados desde el paint callback (mismo patrón que splitter/tiled). Hotkeys D/H/X/P toggle SignDial/Houses/Aspects/Bodies, R resetea offset. FocusHandle + click-to-focus para recibir teclas. Indicador ⏱ ±Xd HH:MM en el footer con color highlight cuando el offset != 0. paint_wheel + glyph overlays respetan layer_visibility (skip capas ocultas). - modules: NatalModule.controls() ahora expone show_sign_dial / show_houses / show_aspects / show_bodies con hotkeys [D/H/X/P], más el slider de armónico. - panel: ControlPanel mantiene toggle_state cache (module_id, key) → bool, inicializa desde defaults al cambiar de ChartKind. Click invierte el toggle visualmente y emite ControlChanged. Nuevo set_toggle(module, key, value) para que la Shell mantenga sync cuando el canvas se autotogglea por hotkey. - shell: nuevo current_chart + current_offset_minutes. render_current() delega a compute_at_offset. Suscripción a CanvasEvent traduce TimeOffsetChanged → re-render, LayerVisibilityChanged → panel sync. Suscripción a PanelEvent::ControlChanged traduce show_* keys a set_layer_visible sobre el canvas. Todos los tests verdes. La fase 5 sumará módulos extra (transit, progression, synastry, uranian) + extracción de eternal de lo que falte. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -154,12 +154,21 @@ pub enum EngineError {
|
||||
/// Computa el RenderModel real contra eternal-astrology si el feature
|
||||
/// está prendido; sino cae al mock.
|
||||
pub fn compute(chart: &Chart) -> Result<RenderModel, EngineError> {
|
||||
compute_at_offset(chart, 0)
|
||||
}
|
||||
|
||||
/// Variante con offset temporal en minutos sobre el instante del chart.
|
||||
/// Útil para time-scrubbing: el jog-dial del canvas pasa el offset
|
||||
/// acumulado y la engine recompone toda la pipeline (Asc, casas,
|
||||
/// posiciones planetarias, aspectos) para ese instante desplazado.
|
||||
pub fn compute_at_offset(chart: &Chart, offset_minutes: i64) -> Result<RenderModel, EngineError> {
|
||||
#[cfg(feature = "eternal-bridge")]
|
||||
{
|
||||
bridge::compute(chart)
|
||||
bridge::compute_at_offset(chart, offset_minutes)
|
||||
}
|
||||
#[cfg(not(feature = "eternal-bridge"))]
|
||||
{
|
||||
let _ = offset_minutes;
|
||||
Ok(compute_mock(chart))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user