From e9369371dbae3c3ae944d674e0d272f619938b7f Mon Sep 17 00:00:00 2001 From: sergio Date: Mon, 18 May 2026 16:26:34 +0000 Subject: [PATCH] =?UTF-8?q?fix(tahuantinsuyu):=20crash=20al=20abrir=20moda?= =?UTF-8?q?l=20+=20simplificaci=C3=B3n=20de=20anillos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Crash fix (panic en gpui entity_map.rs:138 / double_lease): `render_chart_form` hacía `cx.entity().read(cx)` mientras estaba dentro del `render()` del tree — la entity ya estaba leased como `&mut self` y un read concurrente disparaba el double_lease_panic. Se cambió la firma para recibir `picker_open` y `city_atlas` como parámetros desde `render_modal` (que sí tiene `&self`). - Simplificación de anillos: el carril de planetas se acerca (bodies 0.60·r / bodies_inner 0.57·r) — antes 0.05 de separación, ahora 0.03, se ve como "carril" en lugar de dos anillos sueltos. El stroke visible del círculo de aspectos se elimina — `radii.aspects` queda solo como punto de anclaje para las líneas. El `bodies_inner` cambia a stroke plano más sutil (no 3D) para no competir con `bodies`. Co-Authored-By: Claude Opus 4.7 --- .../tahuantinsuyu-canvas/src/lib.rs | 48 +++++++++++-------- .../tahuantinsuyu-tree/src/lib.rs | 36 +++++++++----- 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/crates/modules/tahuantinsuyu/tahuantinsuyu-canvas/src/lib.rs b/crates/modules/tahuantinsuyu/tahuantinsuyu-canvas/src/lib.rs index 6739525..a18161a 100644 --- a/crates/modules/tahuantinsuyu/tahuantinsuyu-canvas/src/lib.rs +++ b/crates/modules/tahuantinsuyu/tahuantinsuyu-canvas/src/lib.rs @@ -1533,15 +1533,19 @@ impl Radii { houses_outer: r * 0.78, houses_inner: r * 0.66, midpoints: r * 0.62, - bodies: r * 0.58, - bodies_inner: r * 0.53, - // aspects pegado al cinturón de cuerpos pero adentro: - // las líneas entran al "círculo de aspectos" justo bajo - // los glyphs en lugar de cruzar el centro. - aspects: r * 0.49, - progression: r * 0.43, - solar_arc: r * 0.36, - composite: r * 0.28, + bodies: r * 0.60, + // bodies_inner cerca de bodies — los dos anillos juntos + // forman un "carril" estrecho que delimita la franja de + // planetas, no dos líneas separadas que confunden. + bodies_inner: r * 0.57, + // aspects justo bajo el carril de cuerpos. Las líneas + // de aspecto entran a este radio, pero el círculo en sí + // no se pinta — son las líneas las que importan, no + // un anillo extra que sume ruido. + aspects: r * 0.54, + progression: r * 0.46, + solar_arc: r * 0.38, + composite: r * 0.30, } } @@ -1690,20 +1694,22 @@ fn paint_wheel( } } - // 2.5. Cinturón de planetas + círculo de aspectos. El cinturón - // (bodies + bodies_inner) marca la franja donde viven los - // glyphs natales. El círculo de aspectos queda apenas más - // adentro — las líneas de aspecto se anclan ahí, no en el - // centro, así "conectan" cuerpos cercanos a su anillo en lugar - // de cruzar toda la rueda. + // 2.5. Carril de planetas. `bodies` + `bodies_inner` muy juntos + // delimitan la franja estrecha donde viven los glyphs natales. + // El círculo de aspectos NO se pinta — `radii.aspects` solo + // existe como punto donde se anclan las líneas; un stroke ahí + // sería un anillo extra que confunde sin aportar. if show(LayerKind::Bodies) { let belt_color = with_alpha(palette.dial_ring, 0.55); - stroke_circle_3d(window, cx, cy, radii.bodies, 1.0, belt_color, theme); - stroke_circle_3d(window, cx, cy, radii.bodies_inner, 0.9, belt_color, theme); - } - if show(LayerKind::Aspects) { - let aspect_ring_color = with_alpha(palette.dial_ring, 0.45); - stroke_circle_3d(window, cx, cy, radii.aspects, 0.9, aspect_ring_color, theme); + stroke_circle_3d(window, cx, cy, radii.bodies, 0.9, belt_color, theme); + stroke_circle( + window, + cx, + cy, + radii.bodies_inner, + 0.6, + with_alpha(palette.dial_ring, 0.35), + ); } // 3. Aspectos. Cada module_id usa su par de radios — natal-natal diff --git a/crates/modules/tahuantinsuyu/tahuantinsuyu-tree/src/lib.rs b/crates/modules/tahuantinsuyu/tahuantinsuyu-tree/src/lib.rs index 2919c69..380c066 100644 --- a/crates/modules/tahuantinsuyu/tahuantinsuyu-tree/src/lib.rs +++ b/crates/modules/tahuantinsuyu/tahuantinsuyu-tree/src/lib.rs @@ -1370,12 +1370,24 @@ impl TahuantinsuyuTree { input.clone(), "Enter = crear — Escape = cancelar", ), - Modal::CreateChart { form, error, .. } => { - render_chart_form(theme, "Nueva carta natal", form, error.clone(), cx) - } - Modal::EditChart { form, error, .. } => { - render_chart_form(theme, "Editar carta natal", form, error.clone(), cx) - } + Modal::CreateChart { form, error, .. } => render_chart_form( + theme, + "Nueva carta natal", + form, + error.clone(), + self.city_picker_open, + &self.city_atlas, + cx, + ), + Modal::EditChart { form, error, .. } => render_chart_form( + theme, + "Editar carta natal", + form, + error.clone(), + self.city_picker_open, + &self.city_atlas, + cx, + ), }; div() @@ -1454,6 +1466,12 @@ fn render_chart_form( title: &str, form: &ChartForm, error: Option, + // Datos del tree que el form necesita renderizar — recibidos por + // parámetro porque esta función se llama desde `render()` y la + // entity del tree ya está leased; un `cx.entity().read(cx)` + // adentro causa double_lease_panic en gpui. + picker_open: bool, + city_atlas: &[CityPreset], cx: &mut Context<'_, TahuantinsuyuTree>, ) -> gpui::Div { let labeled = |label: &'static str, input: Entity| -> gpui::Div { @@ -1526,10 +1544,6 @@ fn render_chart_form( // Header del form: title + botón "Ciudad rápida" con dropdown // que autocompleta place/lat/lon/tz al elegir un preset. - let (picker_open, atlas_snapshot) = { - let me = cx.entity().read(cx); - (me.city_picker_open, me.city_atlas.clone()) - }; let city_btn = div() .id("tts-form-city-btn") .px(px(10.0)) @@ -1580,7 +1594,7 @@ fn render_chart_form( .flex() .flex_col() .overflow_y_scroll(); - for preset in atlas_snapshot.iter().cloned() { + for preset in city_atlas.iter().cloned() { let row_id: SharedString = SharedString::from(format!("tts-city-{}", preset.name)); let label = preset.name.clone();