From 6365e2ed476aa9ddd1b7bb137f32af6e6575f142 Mon Sep 17 00:00:00 2001 From: RiceDee <345114586+RiceDee@users.noreply.github.com> Date: Sun, 1 Nov 2026 16:42:02 +1100 Subject: [PATCH] fix(ui): centre the quick-tools bar in the margin beside the page (#5635) The bar stood a fixed 14 pt from the side panel, so its gap to the page changed with zoom and window size. It now centres in the margin between the panel and the page when the margin holds it, within the first 100 pt; otherwise it keeps 14 pt in. Co-Authored-By: Claude Sonnet 5.5 --- crates/ui-egui/src/canvas.rs | 4 +++- crates/ui-egui/src/canvas/bars.rs | 39 ++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index 5625587a69..62fc39ccae 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -3486,7 +3486,9 @@ fn apply_frame_requests(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui, // Read mode hides the tools (#2646), and full screen is the page and nothing else (#1459); // the quick tools come back with the window. if app.mode != crate::Mode::Read && !app.full_screen { - quick_bar(app, avail, ui); + // The page nearest the left edge, whose margin the bar sits in. + let page_left = app.views[index].screen_rects.iter().map(|(_, r)| r.left()).reduce(f32::min); + quick_bar(app, avail, page_left, ui); } if let Some((source, file, destination)) = remote_open { app.open_remote_link(source, file, destination); diff --git a/crates/ui-egui/src/canvas/bars.rs b/crates/ui-egui/src/canvas/bars.rs index 2472366672..c5b4586946 100644 --- a/crates/ui-egui/src/canvas/bars.rs +++ b/crates/ui-egui/src/canvas/bars.rs @@ -276,10 +276,23 @@ fn notice_bar(ui: &mut egui::Ui, t: &Tokens, icon: &str, icon_color: Color32, te }); } -/// The floating quick-action bar at the left edge of the document area. -pub(super) fn quick_bar(app: &mut PdfCraftApp, area: Rect, ui: &mut egui::Ui) { +const QUICK_BAR_WIDTH: f32 = 46.0; +const QUICK_BAR_EDGE: f32 = 14.0; + +/// How far from the side panel the quick-action bar stands, given the width of the margin between +/// the panel and the page: centred in it when it holds the bar, else 14 pt in (a page filling the +/// width). +fn quick_bar_offset(margin: f32) -> f32 { + // shortcut: centred in at most 100 pt of margin, so a wide margin keeps the bar by the panel. + let margin = margin.min(100.0); + if margin >= QUICK_BAR_WIDTH + 2.0 * 8.0 { (margin - QUICK_BAR_WIDTH) / 2.0 } else { QUICK_BAR_EDGE } +} + +/// The floating quick-action bar in the margin between the side panel and the page. +pub(super) fn quick_bar(app: &mut PdfCraftApp, area: Rect, page_left: Option, ui: &mut egui::Ui) { let t = Tokens::get(ui.ctx()); - let pos = area.left_top() + vec2(14.0, 14.0); + let x = quick_bar_offset(page_left.map_or(0.0, |left| left - area.left())); + let pos = area.left_top() + vec2(x, QUICK_BAR_EDGE); egui::Area::new(egui::Id::unique("quick-bar")).order(egui::Order::Middle).fixed_pos(pos).show(ui.ctx(), |ui| { egui::Frame::NONE .fill(t.card) @@ -496,3 +509,23 @@ pub(super) fn quick_bar(app: &mut PdfCraftApp, area: Rect, ui: &mut egui::Ui) { }); }); } + +#[cfg(test)] +mod tests { + use super::quick_bar_offset; + + #[test] + fn the_quick_bar_centres_in_the_margin_that_holds_it() { + assert_eq!(quick_bar_offset(72.0), 13.0); + assert_eq!(quick_bar_offset(62.0), 8.0); + // A wide margin centres in its first 100 pt, not all of it. + assert_eq!(quick_bar_offset(400.0), 27.0); + } + + #[test] + fn the_quick_bar_keeps_14_pt_in_when_the_margin_cannot_hold_it() { + for margin in [61.9, 30.0, 0.0, -50.0, f32::NEG_INFINITY] { + assert_eq!(quick_bar_offset(margin), 14.0, "{margin}"); + } + } +}