Files
brahman/crates/apps/pineal-demo/src/main.rs
T
sergio 550c98f275 refactor(monorepo): reorganización lógica + renames + SDDs + split CHANGELOG
Reorganización física de crates/:
- core/ (mezclaba 6 propósitos) se divide en protocol/, init/, runtime/, compat/
- shared/ (3 crates) se redistribuye en protocol/ e init/
- lapaloma (sub-módulo de ui_engine) se promueve a modules/pineal/

Renames de proyectos:
- shipote → shuma (runtime de sandboxes)
- nouser → akasha (explorador de Mónadas)
- yahweh → nahual (motor GPUI, antes ui_engine/)
- lapaloma → pineal (data-viz agnóstica)

Fraccionamiento UI → core agnóstico:
- vista-core (DeckState + snap, 175 LOC, 5 tests verdes)
- barra-core (Task + render_html + sanitize, 90 LOC, 5 tests verdes)
- vista-web y barra-web ahora son thin DOM bindings

Documentación nueva:
- 16 SDDs por subdirectorio (≤80 LOC c/u): protocol/init/runtime/compat
  + 10 módulos + apps/
- docs/STATUS.md con cifras reales por proyecto
- docs/ROADMAP.md con plan a finalización (6 hitos, ~6-8 semanas)
- CHANGELOG.md particionado en docs/changelog/<proyecto>.md (7 buckets)

Automatización:
- scripts/reorg.py — script idempotente que: git mv directorios, renombra
  package names, recomputa path = refs, reescribe imports rust, actualiza
  workspace Cargo.toml. Soporta --dry-run.
- scripts/split-changelog.py — particiona CHANGELOG por componente.

Validación:
- cargo check --workspace pasa (124 crates + 2 nuevos cores).
- 10 tests adicionales (5 en vista-core + 5 en barra-core) verdes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 14:48:34 +00:00

232 lines
7.8 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! `pineal-demo` — demo visual de Lapaloma sobre nahual.
//!
//! Ventana 900×560 con un chart cartesiano de **3 series**
//! simultáneas sobre 1024 muestras:
//!
//! - `sin(x · 0.04)` — azul nórdico
//! - `cos(x · 0.04)` — naranja
//! - `0.5·sin(x · 0.02) + 0.5·cos(x · 0.08)` — verde
//!
//! Interacción: click+drag = pan, wheel = zoom, doble-click = reset.
use gpui::{
div, prelude::*, px, ClickEvent, Context, IntoElement, MouseButton, MouseDownEvent,
MouseMoveEvent, MouseUpEvent, Point, Render, ScrollDelta, ScrollWheelEvent, Window,
};
use pineal_cartesian::{chart_cache, ChartCacheHandle, ChartViewport, LapalomaChartElement};
use pineal_core::buffer::DataBuffer;
use pineal_render::{Color, StrokeStyle};
use nahual_launcher::launch_app;
use nahual_theme::Theme;
const N_SAMPLES: usize = 1024;
const WHEEL_SENSITIVITY: f64 = 0.0015;
fn main() {
launch_app(
"Lapaloma — multi-series (drag = pan, wheel = zoom, dbl-click = reset)",
(900., 560.),
Demo::new,
);
}
struct Demo {
series_sin: DataBuffer,
series_cos: DataBuffer,
series_mix: DataBuffer,
viewport: ChartViewport,
initial_viewport: ChartViewport,
drag: Option<DragAnchor>,
chart_cache: ChartCacheHandle,
}
#[derive(Clone, Copy)]
struct DragAnchor {
start_position: Point<gpui::Pixels>,
viewport_at_start: ChartViewport,
}
impl Demo {
fn new(_cx: &mut Context<Self>) -> Self {
let mut sin = DataBuffer::with_capacity(N_SAMPLES);
let mut cos = DataBuffer::with_capacity(N_SAMPLES);
let mut mix = DataBuffer::with_capacity(N_SAMPLES);
for i in 0..N_SAMPLES {
let x = i as f32;
sin.push(x, (x * 0.04).sin());
cos.push(x, (x * 0.04).cos());
mix.push(x, 0.5 * (x * 0.02).sin() + 0.5 * (x * 0.08).cos());
}
let viewport = ChartViewport::new(0.0, (N_SAMPLES - 1) as f64, -1.3, 1.3);
Self {
series_sin: sin,
series_cos: cos,
series_mix: mix,
viewport,
initial_viewport: viewport,
drag: None,
chart_cache: chart_cache(),
}
}
fn on_mouse_down(&mut self, e: &MouseDownEvent, _w: &mut Window, cx: &mut Context<Self>) {
self.drag = Some(DragAnchor {
start_position: e.position,
viewport_at_start: self.viewport,
});
cx.notify();
}
fn on_mouse_move(&mut self, e: &MouseMoveEvent, window: &mut Window, cx: &mut Context<Self>) {
let Some(anchor) = self.drag else { return };
let win = window.viewport_size();
let w: f32 = win.width.into();
let h: f32 = win.height.into();
if w <= 0.0 || h <= 0.0 {
return;
}
let sx: f32 = e.position.x.into();
let sy: f32 = e.position.y.into();
let ax: f32 = anchor.start_position.x.into();
let ay: f32 = anchor.start_position.y.into();
let dfx = ((sx - ax) / w) as f64;
let dfy = ((sy - ay) / h) as f64;
let mut vp = anchor.viewport_at_start;
vp.pan_fraction(dfx, dfy);
self.viewport = vp;
cx.notify();
}
fn on_mouse_up(&mut self, _e: &MouseUpEvent, _w: &mut Window, cx: &mut Context<Self>) {
if self.drag.take().is_some() {
cx.notify();
}
}
fn on_scroll(&mut self, e: &ScrollWheelEvent, window: &mut Window, cx: &mut Context<Self>) {
let win = window.viewport_size();
let w: f32 = win.width.into();
let h: f32 = win.height.into();
if w <= 0.0 || h <= 0.0 {
return;
}
let dy_px: f32 = match e.delta {
ScrollDelta::Pixels(p) => p.y.into(),
ScrollDelta::Lines(p) => p.y * 16.0,
};
let factor = (-dy_px as f64 * WHEEL_SENSITIVITY).exp();
let sx: f32 = e.position.x.into();
let sy: f32 = e.position.y.into();
let ax = (sx / w).clamp(0.0, 1.0) as f64;
let ay = (1.0 - sy / h).clamp(0.0, 1.0) as f64;
self.viewport.zoom_uniform(factor, (ax, ay));
cx.notify();
}
fn on_click(&mut self, e: &ClickEvent, _w: &mut Window, cx: &mut Context<Self>) {
if let ClickEvent::Mouse(m) = e {
if m.up.click_count >= 2 {
self.viewport = self.initial_viewport;
cx.notify();
}
}
}
}
/// Color helper para usar el mismo hex tanto en `pineal_render`
/// como en el body de texto del header del demo.
const COLOR_SIN: u32 = 0x88c0d0; // azul nórdico
const COLOR_COS: u32 = 0xd08770; // naranja
const COLOR_MIX: u32 = 0xa3be8c; // verde
impl Render for Demo {
fn render(&mut self, _w: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let theme = Theme::global(cx).clone();
let plot_bg = Color::rgba(0.10, 0.12, 0.16, 1.0);
let chart = LapalomaChartElement::new(self.viewport)
.background(plot_bg)
.with_cache(self.chart_cache.clone())
.add_series_named(
self.series_sin.clone(),
StrokeStyle::new(2.0, Color::from_hex(COLOR_SIN)),
"sin",
)
.add_series_named(
self.series_cos.clone(),
StrokeStyle::new(2.0, Color::from_hex(COLOR_COS)),
"cos",
)
.add_series_named(
self.series_mix.clone(),
StrokeStyle::new(2.0, Color::from_hex(COLOR_MIX)),
"mix",
);
let drag_active = self.drag.is_some();
let (pan_blits, rebuilds) = {
let c = self.chart_cache.lock().unwrap();
(c.pan_blits(), c.rebuilds())
};
div()
.id("pineal-demo-root")
.size_full()
.bg(theme.bg_app.clone())
.p(px(16.))
.flex()
.flex_col()
.gap(px(12.))
.child(
div()
.text_color(theme.fg_text)
.text_size(px(18.))
.child("Lapaloma — demo cartesian multi-series"),
)
.child(
div()
.flex()
.gap(px(14.))
.text_size(px(11.))
.child(
div()
.text_color(gpui::rgb(COLOR_SIN))
.child("■ sin(x · 0.04)"),
)
.child(
div()
.text_color(gpui::rgb(COLOR_COS))
.child("■ cos(x · 0.04)"),
)
.child(
div()
.text_color(gpui::rgb(COLOR_MIX))
.child("■ ½·sin(x · 0.02) + ½·cos(x · 0.08)"),
)
.child(
div()
.text_color(theme.fg_muted)
.child(format!(
"· cache: {} pan-blits / {} rebuilds {}",
pan_blits,
rebuilds,
if drag_active { "· dragging" } else { "" },
)),
),
)
.child(
div()
.id("pineal-chart-host")
.w_full()
.flex_grow()
.child(chart)
.on_mouse_down(MouseButton::Left, cx.listener(Self::on_mouse_down))
.on_mouse_move(cx.listener(Self::on_mouse_move))
.on_mouse_up(MouseButton::Left, cx.listener(Self::on_mouse_up))
.on_scroll_wheel(cx.listener(Self::on_scroll))
.on_click(cx.listener(Self::on_click)),
)
}
}