mirror of
https://github.com/storytold/wordcraft.git
synced 2026-10-29 04:47:10 -06:00
The canvas ignored egui's zoom delta, so Ctrl/Cmd+wheel and trackpad pinch did nothing over the document. Apply it through view.zoom, starting from the shown scale so fit modes (Page Width etc.) zoom from where they are. Co-authored-by: Simon Geljic <simon.geljic2@det.nsw.edu.au> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Simon Geljic
Claude Opus 5.5
parent
bd123c3808
commit
97aad95d4d
@@ -168,6 +168,13 @@ pub fn show(app: &mut WordApp, ui: &mut Ui) {
|
||||
(None, None, full)
|
||||
};
|
||||
app.canvas.canvas_rect = Some(area);
|
||||
// Ctrl/⌘ + wheel (and trackpad pinch) zooms the document, like Word. egui reports both as a
|
||||
// zoom factor and doesn't scroll for them. Start from the shown scale so fit modes zoom too.
|
||||
let zoom_delta = ui.input(|i| i.zoom_delta());
|
||||
if (zoom_delta - 1.0).abs() > 1e-3 && ui.rect_contains_pointer(area) {
|
||||
let pct = (app.canvas.scale / PX_PER_PT * zoom_delta * 100.0).clamp(10.0, 500.0);
|
||||
let _ = app.run("view.zoom", json!({"value": pct}));
|
||||
}
|
||||
let geo = geometry(app, &layout, area.size() - vec2(14.0, 0.0));
|
||||
app.canvas.scale = geo.scale;
|
||||
let caret = layout.caret_on(&app.session.sel.focus, app.session.page_hint);
|
||||
|
||||
@@ -612,6 +612,48 @@ mod tests {
|
||||
WordApp::new(Session::new(wordcraft_doc::Document::new()), Services::default())
|
||||
}
|
||||
|
||||
/// Issue #139: Ctrl+wheel over the page didn't zoom.
|
||||
#[test]
|
||||
fn ctrl_wheel_over_canvas_zooms() {
|
||||
let ctx = egui::Context::default();
|
||||
let mut a = app();
|
||||
let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1280.0, 800.0));
|
||||
let mut t = 0.0;
|
||||
let mut frame = |a: &mut WordApp, events: Vec<egui::Event>| {
|
||||
t += 1.0 / 60.0;
|
||||
let input = egui::RawInput { events, time: Some(t), screen_rect: Some(screen), ..Default::default() };
|
||||
ctx.run_ui(input, |ui| {
|
||||
a.logic(ui.ctx());
|
||||
a.ui(ui);
|
||||
})
|
||||
.drop_without_applying_deltas();
|
||||
};
|
||||
// The first frames install fonts; the canvas appears after them.
|
||||
for _ in 0..3 {
|
||||
frame(&mut a, Vec::new());
|
||||
}
|
||||
let over_page = a.canvas.canvas_rect.unwrap().center();
|
||||
frame(&mut a, vec![egui::Event::PointerMoved(over_page)]);
|
||||
let before = a.canvas.scale;
|
||||
let wheel = |y: f32| egui::Event::MouseWheel {
|
||||
unit: egui::MouseWheelUnit::Line,
|
||||
delta: egui::vec2(0.0, y),
|
||||
phase: egui::TouchPhase::Move,
|
||||
modifiers: egui::Modifiers::COMMAND,
|
||||
};
|
||||
frame(&mut a, vec![wheel(1.0)]);
|
||||
for _ in 0..30 {
|
||||
frame(&mut a, Vec::new());
|
||||
}
|
||||
assert!(a.canvas.scale > before * 1.05, "Ctrl+wheel up zooms in: {before} -> {}", a.canvas.scale);
|
||||
let zoomed = a.canvas.scale;
|
||||
frame(&mut a, vec![wheel(-1.0)]);
|
||||
for _ in 0..30 {
|
||||
frame(&mut a, Vec::new());
|
||||
}
|
||||
assert!(a.canvas.scale < zoomed, "Ctrl+wheel down zooms out");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn user_name_survives_restart() {
|
||||
let mut first = app();
|
||||
|
||||
Reference in New Issue
Block a user