From 1905b3ef9d04b7c1c1ce279e4663268a495c720a Mon Sep 17 00:00:00 2001 From: ashokram-si <347905169+ashokram-si@users.noreply.github.com> Date: Thu, 29 Oct 2026 23:26:49 +0530 Subject: [PATCH] Canvas: the spine takes the spread edge's colour The spine used the UI theme's dim text colour, which follows the app theme while the paper follows the document, so on white paper it was barely visible (about 1.25:1). The spine is the inner edge of the spread, so it now uses the same dark grey hairline as the spread's outline, through one shared PAGE_EDGE constant for both; it reads on white paper and doesn't change with the theme. Not the smart-guide green, which marks snapping and would make the spine look like one. --- crates/ui-egui/src/canvas.rs | 2 +- crates/ui-egui/src/canvas/page_decor.rs | 16 +++++++++++----- crates/ui-egui/src/canvas/tests.rs | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index de4331c7d..7a424fa85 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -272,7 +272,7 @@ pub fn show(app: &mut DesignApp, ui: &mut egui::Ui) { crate::separations::paint(app, ui.ctx(), &painter, &xf, &layout, screen); let hair = 1.0 / ui.ctx().pixels_per_point(); for slot in &layout.slots { - painter.rect_stroke(xf.rect(slot.bounds), 0.0, Stroke::new(hair, Color32::from_rgb(0x4a, 0x4a, 0x4a)), StrokeKind::Outside); + painter.rect_stroke(xf.rect(slot.bounds), 0.0, Stroke::new(hair, page_decor::PAGE_EDGE), StrokeKind::Outside); } if !preview { let drag = ui.data(|d| d.get_temp::(egui::Id::unique(GUIDE_DRAG))); diff --git a/crates/ui-egui/src/canvas/page_decor.rs b/crates/ui-egui/src/canvas/page_decor.rs index c7d76412e..cddb5fd56 100644 --- a/crates/ui-egui/src/canvas/page_decor.rs +++ b/crates/ui-egui/src/canvas/page_decor.rs @@ -10,6 +10,10 @@ pub(super) fn dashed(painter: &egui::Painter, a: Pos2, b: Pos2, stroke: Stroke, painter.extend(egui::Shape::dashed_line(&[a, b], stroke, dash, gap)); } +/// The hairline around each spread and at its spine, where its pages meet: one dark grey on any +/// paper colour and in either theme, so the binding edge reads like the spread's own edge. +pub(super) const PAGE_EDGE: Color32 = Color32::from_rgb(0x4a, 0x4a, 0x4a); + /// The most baseline grid lines drawn on a page: one per point of the tallest page (216 in). pub(super) const MAX_BASELINES: usize = 216 * 72; @@ -52,7 +56,7 @@ pub(super) fn draw_guides( let Some(sp) = doc.spread(slot.spread) else { continue }; if app.ui.guides { draw_bleed_and_slug(painter, xf, doc, slot, sp); - draw_spine(painter, xf, slot, sp, t); + draw_spine(painter, xf, slot, sp); } let pasteboard = slot.xf.inverse().transform_rect_bbox(layout.pasteboard); for (pi, p) in sp.pages.iter().enumerate() { @@ -66,6 +70,7 @@ pub(super) fn draw_guides( draw_page_guides(&cx, (pi, p, pr), moving, &selection); } } + let _ = t; } /// The bleed and slug outlines of a spread, in their own colours. @@ -81,9 +86,10 @@ fn draw_bleed_and_slug(painter: &egui::Painter, xf: &Xf, doc: &Document, slot: & } } -/// The spine: a hairline where the pages of a spread meet, the full height of the taller page. -/// Screen only, like the other guides; the paper is one rectangle and exports never show a seam. -fn draw_spine(painter: &egui::Painter, xf: &Xf, slot: &SpreadSlot, sp: &designcraft_doc::Spread, t: &Tokens) { +/// The spine: a hairline where the pages of a spread meet, the full height of the taller page, in +/// the spread edge's colour ([`PAGE_EDGE`]). Screen only, like the other guides; the paper is one +/// rectangle and exports never show a seam. +fn draw_spine(painter: &egui::Painter, xf: &Xf, slot: &SpreadSlot, sp: &designcraft_doc::Spread) { let pt = |p: Point| xf.to_screen(slot.xf * p); for pair in sp.pages.windows(2) { // Bound right to left, a spread lists its right page first: take the two edges that @@ -92,7 +98,7 @@ fn draw_spine(painter: &egui::Painter, xf: &Xf, slot: &SpreadSlot, sp: &designcr let (left, right) = if a.x0 <= b.x0 { (a, b) } else { (b, a) }; let x = (left.x1 + right.x0) / 2.0; let (y0, y1) = (a.y0.min(b.y0), a.y1.max(b.y1)); - painter.line_segment([pt(Point::new(x, y0)), pt(Point::new(x, y1))], Stroke::new(hair(painter), t.text_dim)); + painter.line_segment([pt(Point::new(x, y0)), pt(Point::new(x, y1))], Stroke::new(hair(painter), PAGE_EDGE)); } } diff --git a/crates/ui-egui/src/canvas/tests.rs b/crates/ui-egui/src/canvas/tests.rs index 8ca5d6e1c..ad4720cf9 100644 --- a/crates/ui-egui/src/canvas/tests.rs +++ b/crates/ui-egui/src/canvas/tests.rs @@ -36,7 +36,7 @@ fn canvas_shapes(app: &mut DesignApp) -> Vec { /// The spine-coloured vertical hairlines at screen x `x` that run the full height of `page` /// (the spine of one spread shares its x with the pages of the spreads above and below it). fn vertical_lines_at(shapes: &[egui::epaint::ClippedShape], x: f32, page: Rect) -> usize { - let spine = Tokens::get(&egui::Context::default()).text_dim; + let spine = page_decor::PAGE_EDGE; shapes .iter() .filter(|c| match &c.shape {