Skip to main content

blockworx/
font_editor.rs

1//! Live font-size editor (`--font-editor`).
2//!
3//! Opens a second OS window (an egui *immediate* viewport) with one row per
4//! canvas font size and a [`egui::DragValue`] to tune it. Like the theme editor,
5//! it runs inside the app's `ui` and edits the live [`Theme`] in place — the main
6//! canvas reflects each change the same frame. Persistence to `font_sizes.json`
7//! is handled by the caller on exit.
8
9use egui::ViewportId;
10
11use crate::theme::Theme;
12
13/// Render the font-editor window for this frame, mutating `theme`'s font sizes in
14/// place as the user drags. Returns `true` once the window's close is requested,
15/// so the caller can stop showing it and persist the result.
16pub fn show(ctx: &egui::Context, theme: &mut Theme) -> bool {
17    let builder = egui::ViewportBuilder::default()
18        .with_title("Font Editor")
19        .with_inner_size([320.0, 280.0]);
20
21    ctx.show_viewport_immediate(
22        ViewportId::from_hash_of("font_editor"),
23        builder,
24        |ui, _class| {
25            table(ui, theme);
26            ui.input(|i| i.viewport().close_requested())
27        },
28    )
29}
30
31/// The label → size table. One row per canvas font size.
32fn table(ui: &mut egui::Ui, theme: &mut Theme) {
33    ui.heading("Font Sizes");
34    ui.label("Changes apply live; the sizes are saved to font_sizes.json on exit.");
35    ui.separator();
36
37    let mut fs = theme.font_sizes();
38    let before = fs;
39    egui::Grid::new("font_sizes_grid")
40        .num_columns(2)
41        .striped(true)
42        .show(ui, |ui| {
43            size_row(ui, "Title", &mut fs.title);
44            size_row(ui, "Block type", &mut fs.block_type);
45            size_row(ui, "Pin", &mut fs.pin);
46            size_row(ui, "Pin subtitle", &mut fs.pin_subtitle);
47            size_row(ui, "Tag", &mut fs.tag);
48            size_row(ui, "Route", &mut fs.route);
49        });
50
51    if fs != before {
52        theme.set_font_sizes(fs);
53        // The edited theme is injected into the root viewport on its next frame;
54        // nudge it to repaint so the canvas updates without a mouse move there.
55        ui.ctx().request_repaint_of(ViewportId::ROOT);
56    }
57}
58
59/// One labeled row with a `DragValue` bound to a font size (px).
60fn size_row(ui: &mut egui::Ui, label: &str, value: &mut f32) {
61    ui.label(label);
62    ui.add(
63        egui::DragValue::new(value)
64            .range(5.0..=30.0)
65            .speed(0.1)
66            .suffix(" px"),
67    );
68    ui.end_row();
69}