Files
pdfcraft/crates/ui-egui/tests/it/pageboxes.rs
T
eliets2 64d8c20584 Leave the page grid when the Crop tool is chosen
Crop is only listed in the Organize pages panel, which is shown together with the thumbnail grid; activating it there must bring the document view back, otherwise the tool is selected but no page is on screen to drag a crop rectangle on.

In the "page.crop" command arm, close the organize grid of the active view before arming the Crop tool, the way opening a page from the grid does. The left panel then falls back to the workspace panel on the next frame, as it already does when the grid closes by other means.

Test: the_crop_tool_leaves_the_page_grid_so_a_page_can_be_cropped failed before the change and passes after.
2026-10-23 12:05:49 +03:00

122 lines
4.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Crop tool, Set Page Boxes and Duplicate pages in the real shell (egui_kittest).
use egui_kittest::Harness;
use egui_kittest::kittest::Queryable;
use pdfcraft_ui_egui::{Dialog, PdfCraftApp, QuickTool};
const FIXTURE: &[u8] = b"%PDF-1.7
1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj
2 0 obj << /Type /Pages /Kids [3 0 R 4 0 R] /Count 2 /MediaBox [0 0 300 400] >> endobj
3 0 obj << /Type /Page /Parent 2 0 R >> endobj
4 0 obj << /Type /Page /Parent 2 0 R >> endobj
trailer << /Root 1 0 R >>
%%EOF";
fn harness() -> Harness<'static, PdfCraftApp> {
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_cc| {
let mut app = PdfCraftApp::new();
app.set_option("language", "en").unwrap();
app.open_bytes("doc.pdf", None, FIXTURE.to_vec()).unwrap();
app.set_option("left", "closed").unwrap();
app.set_option("zoom", "150").unwrap();
app
});
h.run_steps(6);
h
}
fn size(h: &Harness<'static, PdfCraftApp>, page: usize) -> (f32, f32) {
let s = h.state();
let p = &s.session.get(s.views[0].id).unwrap().info.pages[page];
(p.width, p.height)
}
#[test]
fn the_crop_tool_crops_to_the_dragged_rectangle_then_returns_to_select() {
let mut h = harness();
assert!(h.state_mut().execute("page.crop"));
assert_eq!(h.state().quick_tool, QuickTool::Crop);
h.run_steps(2);
let r = h.state().views[0].page_screen_rect(0).unwrap();
// The middle half of the page in both directions.
let (a, b) = (r.min + r.size() * 0.25, r.min + r.size() * 0.75);
h.hover_at(a);
h.run_steps(1);
h.drag_at(a);
h.run_steps(1);
for k in 1..=4 {
h.hover_at(a + (b - a) * (k as f32 / 4.0));
h.run_steps(1);
}
h.drop_at(b);
h.run_steps(4);
let (w, hh) = size(&h, 0);
assert!((w - 150.0).abs() < 2.0 && (hh - 200.0).abs() < 2.0, "{w}×{hh}");
assert_eq!(size(&h, 1), (300.0, 400.0));
assert_eq!(h.state().quick_tool, QuickTool::Select);
assert_eq!(h.state().session.get(h.state().views[0].id).unwrap().can_undo(), Some("Crop page"));
}
#[test]
fn set_page_boxes_dialog_applies_margins_to_the_chosen_pages() {
let mut h = harness();
assert!(h.state_mut().execute("page.boxes"));
h.run_steps(3);
assert_eq!(h.state().dialog, Some(Dialog::PageBoxes));
h.get_by_label("Set Page Boxes");
// One inch off every side (the units default to inches; margins are stored in points).
h.state_mut().boxes_draft.margins = [72.0; 4];
h.run_steps(2);
h.get_by_label("OK").click();
h.run_steps(4);
assert_eq!(h.state().dialog, None);
assert_eq!(size(&h, 0), (156.0, 256.0));
assert_eq!(size(&h, 1), (156.0, 256.0), "All pages by default");
// Set to zero resets the box.
h.state_mut().execute("page.boxes");
h.run_steps(3);
h.get_by_label("Set to zero").click();
h.run_steps(1);
h.get_by_label("OK").click();
h.run_steps(4);
assert_eq!(size(&h, 0), (300.0, 400.0));
}
#[test]
fn duplicate_pages_copies_the_current_page() {
let mut h = harness();
assert!(h.state_mut().execute("page.duplicate"));
h.run_steps(3);
let s = h.state();
assert_eq!(s.session.get(s.views[0].id).unwrap().info.pages.len(), 3);
}
#[test]
fn the_crop_tool_leaves_the_page_grid_so_a_page_can_be_cropped() {
let mut h = harness();
// The Organize panel's thumbnail grid is on screen for this view: choosing
// "Crop pages" from it must leave the grid so the canvas handles a drag on
// a page instead of returning early to organize_grid.
h.state_mut().views[0].organize = true;
assert!(h.state_mut().execute("page.crop"));
assert_eq!(h.state().quick_tool, QuickTool::Crop);
assert!(!h.state().views[0].organize, "\"page.crop\" must clear view.organize");
h.run_steps(2);
let r = h.state().views[0].page_screen_rect(0).unwrap();
// The middle half of the page in both directions.
let (a, b) = (r.min + r.size() * 0.25, r.min + r.size() * 0.75);
h.hover_at(a);
h.run_steps(1);
h.drag_at(a);
h.run_steps(1);
for k in 1..=4 {
h.hover_at(a + (b - a) * (k as f32 / 4.0));
h.run_steps(1);
}
h.drop_at(b);
h.run_steps(4);
let (w, hh) = size(&h, 0);
assert!((w - 150.0).abs() < 2.0 && (hh - 200.0).abs() < 2.0, "{w}×{hh}");
assert_eq!(size(&h, 1), (300.0, 400.0));
}