feat(tahuantinsuyu): fase 8 — slider interactivo + slider de edad en progression

Los `Control::Slider` del panel ya no son display-only — son arrastrables
con el mismo patrón del splitter (canvas absoluto sobre el track + window
mouse handlers en cada frame). El `ProgressionModule` ahora expone un
slider de `target_age_years` (0..120) que el shell inicializa con la
edad actual del sujeto al cargar la carta.

- panel: SliderDrag struct + slider_state HashMap + slider_drag Option
  + métodos start/continue/end_slider_drag + apply_slider_position que
  calcula fraction desde la posición del mouse relativa al track y
  emite ControlChanged con el valor float. set_slider(module, key, val)
  para sincronización externa. set_active_kind ahora inicializa también
  los sliders desde sus defaults. render_slider pinta track + portion
  filled + thumb circular + canvas overlay con handlers de drag.
  Los Slider tienen un valor visible "X.X (min...max)" en el header.
- modules: ProgressionModule agrega Control::Slider target_age_years
  con range 0..120, step 0.25, default 30 (placeholder — el shell lo
  reescribe con la edad real al cargar la carta).
- shell: apply_selection(Chart) ahora calcula current_age, lo inserta
  en module_configs["progression"]["target_age_years"], y empuja al
  panel via set_slider. build_requests ya leía target_age_years desde
  el map (de fase 7), así que ahora el slider lo controla.

Mecánica: si activás "Progresión secundaria", el slider arranca en la
edad actual del sujeto. Arrastralo a la izquierda y la rueda recompone
la carta progresada para esa edad simbólica — vas viendo cómo el sujeto
"evoluciona" o "involuciona" a través de su línea temporal interna,
con los planetas progresados moviéndose por el anillo interno y los
cross aspects con la natal reorganizándose en tiempo real.

Same pattern aplica de aquí en más para cualquier slider futuro
(harmonic en NatalModule, target_year en SolarArc, orb_multiplier, …).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-17 10:54:06 +00:00
parent 42e09fd7cd
commit e0c5c02b8e
3 changed files with 385 additions and 135 deletions
+15 -2
View File
@@ -115,11 +115,24 @@ impl Shell {
return;
}
};
let age = current_age_years(&chart.birth_data);
self.current_chart = Some(chart.clone());
self.current_offset_minutes = 0;
// Inicializar la edad objetivo del módulo de progresión
// con la edad actual del sujeto, así el slider arranca
// "donde corresponde" si el usuario lo activa.
let prog_entry = self
.module_configs
.entry("progression".into())
.or_insert_with(|| serde_json::json!({}));
if let serde_json::Value::Object(map) = prog_entry {
map.insert("target_age_years".into(), serde_json::json!(age));
}
self.render_current(cx);
self.panel
.update(cx, |p, cx| p.set_active_kind(Some(chart.kind), cx));
self.panel.update(cx, |p, cx| {
p.set_active_kind(Some(chart.kind), cx);
p.set_slider("progression", "target_age_years", age, cx);
});
}
TreeSelection::Contact(id) => {
self.current_chart = None;