Skip to main content

custom_paint/
custom_paint.rs

1//! custom_paint — headless bundle dump for the "custom-painted commit
2//! graph" pattern from `examples/src/bin/custom_paint.rs`.
3//!
4//! No GPU, no winit, no shader compilation — just the CPU bundle path.
5//! Inspecting the artifacts answers two of the host-paint questions
6//! whisper-git would ask of aetna:
7//!
8//! - **Custom-shader Els are visible in the artifact stream.** Each
9//!   shader-bound row appears in `out/custom_paint.draw_ops.txt` as a
10//!   `Quad shader=custom::commit_node ...` with its full uniform set,
11//!   and the shader manifest groups every instance under
12//!   `custom::commit_node used N times`. A host's commit-graph paint is
13//!   not a black box to the agent loop.
14//!
15//! - **The SVG fallback degrades gracefully.** Custom-shader rects emit
16//!   the documented dashed-magenta placeholder; the surrounding text
17//!   and chrome render normally.
18//!
19//! Run: `cargo run -p aetna-core --example custom_paint`
20
21use aetna_core::prelude::*;
22
23const ROW_HEIGHT: f32 = 28.0;
24const GRAPH_WIDTH: f32 = 140.0;
25const LANE_COUNT: u8 = 4;
26
27struct FakeCommit {
28    sha: &'static str,
29    subject: &'static str,
30    author: &'static str,
31    when: &'static str,
32    lane: u8,
33}
34
35fn lane_palette(lane: u8) -> Color {
36    match lane % LANE_COUNT {
37        0 => Color::rgb(96, 165, 230),
38        1 => Color::rgb(96, 200, 200),
39        2 => Color::rgb(140, 200, 110),
40        _ => Color::rgb(230, 180, 90),
41    }
42}
43
44fn graph_cell(lane: u8, selected: bool) -> El {
45    let lane_color = lane_palette(lane);
46    let ring_color = if selected {
47        Color::rgb(245, 245, 250)
48    } else {
49        lane_color
50    };
51    let ring_w = if selected { 2.5 } else { 1.5 };
52    let radius = 5.0;
53    let line_w = 2.0;
54    let lane_frac = (lane as f32 + 0.5) / LANE_COUNT as f32;
55
56    El::new(Kind::Custom("graph_cell"))
57        .width(Size::Fixed(GRAPH_WIDTH))
58        .height(Size::Fixed(ROW_HEIGHT))
59        .shader(
60            ShaderBinding::custom("commit_node")
61                .color("vec_a", tokens::BACKGROUND)
62                .color("vec_b", ring_color)
63                .vec4("vec_c", [radius, ring_w, line_w, lane_frac]),
64        )
65        .fill(lane_color)
66}
67
68fn build_row(c: &FakeCommit, idx: usize, selected: bool) -> El {
69    row([
70        graph_cell(c.lane, selected),
71        text(c.sha).mono().muted(),
72        text(c.subject),
73        spacer(),
74        text(format!("{} · {}", c.author, c.when)).muted(),
75    ])
76    .key(format!("commit-{idx}"))
77    .gap(tokens::SPACE_3)
78    .padding(Sides::xy(tokens::SPACE_2, 0.0))
79    .height(Size::Fixed(ROW_HEIGHT))
80    .align(Align::Center)
81}
82
83fn fixture() -> El {
84    #[rustfmt::skip]
85    let commits = [
86        FakeCommit { sha: "8a3f1c9", subject: "fix race condition in scheduler", author: "ada",     when: "12m", lane: 0 },
87        FakeCommit { sha: "1b07d4e", subject: "tweak token tooltip wording",     author: "linus",   when: "1h",  lane: 0 },
88        FakeCommit { sha: "9f2e4a1", subject: "wire avatar fallback identicon",  author: "joelle",  when: "3h",  lane: 1 },
89        FakeCommit { sha: "44ab8d2", subject: "diff: word-level highlight pass", author: "raphael", when: "5h",  lane: 1 },
90        FakeCommit { sha: "61c0fe7", subject: "ci: bump rust toolchain to 1.85", author: "mei",     when: "7h",  lane: 2 },
91        FakeCommit { sha: "a90215b", subject: "switch logging to env_logger",    author: "isabel",  when: "1d",  lane: 2 },
92        FakeCommit { sha: "0d7e3c4", subject: "drop unused commit_detail cache", author: "noor",    when: "1d",  lane: 1 },
93        FakeCommit { sha: "33b2118", subject: "context-menu spacing pass",       author: "kira",    when: "2d",  lane: 3 },
94    ];
95    let selected_idx = 3;
96    let rows = commits
97        .iter()
98        .enumerate()
99        .map(|(i, c)| build_row(c, i, i == selected_idx))
100        .collect::<Vec<_>>();
101
102    column([
103        h2("Custom-painted commit graph"),
104        text("8 commits · custom shader paints lane line + circle node").muted(),
105        column(rows).gap(0.0),
106    ])
107    .padding(tokens::SPACE_4)
108    .gap(tokens::SPACE_2)
109}
110
111fn main() -> std::io::Result<()> {
112    let mut root = fixture();
113    let viewport = Rect::new(0.0, 0.0, 900.0, 360.0);
114    let bundle = render_bundle(&mut root, viewport);
115
116    let out_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("out");
117    let written = write_bundle(&bundle, &out_dir, "custom_paint")?;
118    for p in &written {
119        println!("wrote {}", p.display());
120    }
121
122    if !bundle.lint.findings.is_empty() {
123        eprintln!("\nlint findings ({}):", bundle.lint.findings.len());
124        eprint!("{}", bundle.lint.text());
125    }
126
127    Ok(())
128}