mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-24 10:08:00 -06:00
Merge r2-fix-ui: tests the combined batch broke
This commit is contained in:
@@ -569,7 +569,8 @@ pub(crate) fn delete_selected(view: &mut DocView) -> Option<Edit> {
|
||||
/// as the object nudge does (`object_ui::nudge_keys`) and as dragging it does (#2608). The keys
|
||||
/// are consumed before the view turns the page with them; one press is one undo step.
|
||||
pub(crate) fn nudge_keys(ctx: &egui::Context, view: &mut DocView, doc: &Document) {
|
||||
if ctx.egui_wants_keyboard_input() || view.prepare.grab.is_some() {
|
||||
// `consume_key` lets an extra Alt through, and Alt+↑/↓ belongs to Calculation order's move.
|
||||
if ctx.egui_wants_keyboard_input() || view.prepare.grab.is_some() || ctx.input(|i| i.modifiers.alt) {
|
||||
return;
|
||||
}
|
||||
let Some((name, wi)) = view.prepare.selected.clone() else { return };
|
||||
|
||||
@@ -713,7 +713,7 @@ fn mode_tab(h: &Harness<'static, PdfCraftApp>, label: &str) -> egui::Rect {
|
||||
}
|
||||
|
||||
/// Scroll the page until `what` (on screen) lies across the mode bar, then the cursor over each
|
||||
/// tab it lies under: with the All tools panel closed, Read, Edit, Convert and E-Sign.
|
||||
/// tab it lies under: with the All tools panel closed, every tab: All tools, Edit, Convert and E-Sign.
|
||||
fn mode_tab_cursors(
|
||||
h: &mut Harness<'static, PdfCraftApp>,
|
||||
what: impl Fn(&Harness<'static, PdfCraftApp>) -> egui::Rect,
|
||||
@@ -727,7 +727,7 @@ fn mode_tab_cursors(
|
||||
h.state_mut().views[0].goto = Some((0, (top - (tabs - y)) / page(h).height()));
|
||||
h.run_steps(4);
|
||||
let under = what(h);
|
||||
["Read", "Edit", "Convert", "E-Sign"].map(|label| {
|
||||
["All tools", "Edit", "Convert", "E-Sign"].map(|label| {
|
||||
let at = mode_tab(h, label).center();
|
||||
assert!(under.contains(at), "{under:?} lies under {label} at {at:?}");
|
||||
h.hover_at(at);
|
||||
@@ -737,7 +737,7 @@ fn mode_tab_cursors(
|
||||
}
|
||||
|
||||
const HAND_ON_EVERY_TAB: [(&str, egui::CursorIcon); 4] = [
|
||||
("Read", egui::CursorIcon::PointingHand),
|
||||
("All tools", egui::CursorIcon::PointingHand),
|
||||
("Edit", egui::CursorIcon::PointingHand),
|
||||
("Convert", egui::CursorIcon::PointingHand),
|
||||
("E-Sign", egui::CursorIcon::PointingHand),
|
||||
|
||||
@@ -5879,12 +5879,13 @@ fn mode_tab(h: &Harness<'static, PdfCraftApp>, label: &str) -> egui::Rect {
|
||||
}
|
||||
|
||||
/// The cursor over each mode bar tab that page 1's text lies under, once that text is scrolled
|
||||
/// up under the bar. With the All tools panel closed it lies under Read, Edit, Convert and E-Sign.
|
||||
fn mode_tab_cursors(h: &mut Harness<'static, PdfCraftApp>, text: egui::Rect) -> [(&'static str, egui::CursorIcon); 4] {
|
||||
/// up under the bar. With the All tools panel closed it lies under Edit, Convert and E-Sign; it
|
||||
/// starts right of All tools.
|
||||
fn mode_tab_cursors(h: &mut Harness<'static, PdfCraftApp>, text: egui::Rect) -> [(&'static str, egui::CursorIcon); 3] {
|
||||
h.state_mut().views[0].goto = Some((0, 0.5));
|
||||
h.run_steps(4);
|
||||
let offset = h.state().views[0].page_screen_rect(0).expect("on screen").top();
|
||||
["Read", "Edit", "Convert", "E-Sign"].map(|label| {
|
||||
["Edit", "Convert", "E-Sign"].map(|label| {
|
||||
let at = mode_tab(h, label).center();
|
||||
assert!(text.translate(egui::vec2(0.0, offset)).contains(at), "the text lies under {label}");
|
||||
h.hover_at(at);
|
||||
@@ -5893,12 +5894,8 @@ fn mode_tab_cursors(h: &mut Harness<'static, PdfCraftApp>, text: egui::Rect) ->
|
||||
})
|
||||
}
|
||||
|
||||
const HAND_ON_EVERY_TAB: [(&str, egui::CursorIcon); 4] = [
|
||||
("Read", egui::CursorIcon::PointingHand),
|
||||
("Edit", egui::CursorIcon::PointingHand),
|
||||
("Convert", egui::CursorIcon::PointingHand),
|
||||
("E-Sign", egui::CursorIcon::PointingHand),
|
||||
];
|
||||
const HAND_ON_EVERY_TAB: [(&str, egui::CursorIcon); 3] =
|
||||
[("Edit", egui::CursorIcon::PointingHand), ("Convert", egui::CursorIcon::PointingHand), ("E-Sign", egui::CursorIcon::PointingHand)];
|
||||
|
||||
/// Page 1's text block on screen, relative to the page's top edge, in the window as it is now.
|
||||
fn page_text(h: &Harness<'static, PdfCraftApp>) -> egui::Rect {
|
||||
|
||||
@@ -1331,6 +1331,13 @@ fn lines_grow_and_shrink_with_their_handles_before_release() {
|
||||
let _gpu = gpu();
|
||||
for (document_rotation, view_rotation) in [(0, 0), (90, 0), (0, 90), (90, 270)] {
|
||||
let rot = (document_rotation, view_rotation);
|
||||
// A line runs across the page as /Rotate displays it (#3781): along user y on a quarter turn.
|
||||
// `d` is the distance along the line from the click at (100, 250).
|
||||
let along =
|
||||
|h: &Harness<'static, PdfCraftApp>, d: f32| if document_rotation == 90 { at(h, 100.0, 250.0 + d) } else { at(h, 100.0 + d, 250.0) };
|
||||
let line = |from: f32, to: f32| {
|
||||
if document_rotation == 90 { [98.0, 250.0 + from, 102.0, 250.0 + to] } else { [100.0 + from, 248.0, 100.0 + to, 252.0] }
|
||||
};
|
||||
let mut h = harness();
|
||||
if document_rotation != 0 {
|
||||
h.state_mut().apply_edit(pdfcraft_engine::Edit::RotatePages { pages: vec![0], degrees: document_rotation });
|
||||
@@ -1341,36 +1348,36 @@ fn lines_grow_and_shrink_with_their_handles_before_release() {
|
||||
h.run_steps(3);
|
||||
assert!(h.state_mut().execute("sign.fill.line"));
|
||||
click(&mut h, 100.0, 250.0);
|
||||
assert_rect(rects(&h)[0], [82.0, 248.0, 118.0, 252.0]);
|
||||
assert_rect(rects(&h)[0], line(-18.0, 18.0));
|
||||
// In line mode a click on the line picks it up, with its handles.
|
||||
click(&mut h, 100.0, 250.0);
|
||||
assert_eq!(h.state().views[0].comments.selected, Some((0, 0)), "{rot:?}");
|
||||
let generation = h.state().session.get(h.state().views[0].id).unwrap().edit_generation();
|
||||
|
||||
// The handle at the line's end, dragged out to 160.
|
||||
h.drag_at(at(&h, 118.0, 250.0));
|
||||
// The handle at the line's end, dragged out to 60 from the middle.
|
||||
h.drag_at(along(&h, 18.0));
|
||||
h.run_steps(1);
|
||||
h.hover_at(at(&h, 160.0, 250.0));
|
||||
h.hover_at(along(&h, 60.0));
|
||||
// Wait only for the one-time layers. Later pointer frames are immediate.
|
||||
let mut grown = h.render().unwrap();
|
||||
for _ in 0..50 {
|
||||
if ink_near(&grown, at(&h, 150.0, 250.0)) {
|
||||
if ink_near(&grown, along(&h, 50.0)) {
|
||||
break;
|
||||
}
|
||||
h.run_steps(2);
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
grown = h.render().unwrap();
|
||||
}
|
||||
assert!(ink_near(&grown, at(&h, 150.0, 250.0)), "{rot:?}: the line grows with the handle before release");
|
||||
assert!(ink_near(&grown, at(&h, 90.0, 250.0)), "{rot:?}: from where it starts");
|
||||
assert!(ink_near(&grown, along(&h, 50.0)), "{rot:?}: the line grows with the handle before release");
|
||||
assert!(ink_near(&grown, along(&h, -10.0)), "{rot:?}: from where it starts");
|
||||
|
||||
// Back in, shorter than it was, still without letting go.
|
||||
h.hover_at(at(&h, 100.0, 250.0));
|
||||
h.hover_at(along(&h, 0.0));
|
||||
h.run_steps(2);
|
||||
let shrunk = h.render().unwrap();
|
||||
assert!(ink_near(&shrunk, at(&h, 90.0, 250.0)), "{rot:?}: the line still starts where it did");
|
||||
for x in [110.0, 150.0] {
|
||||
assert!(!ink_near(&shrunk, at(&h, x, 250.0)), "{rot:?}: the line shrinks with the handle before release (ink at {x})");
|
||||
assert!(ink_near(&shrunk, along(&h, -10.0)), "{rot:?}: the line still starts where it did");
|
||||
for d in [10.0, 50.0] {
|
||||
assert!(!ink_near(&shrunk, along(&h, d)), "{rot:?}: the line shrinks with the handle before release (ink at {d})");
|
||||
}
|
||||
let doc = h.state().session.get(h.state().views[0].id).unwrap();
|
||||
assert_eq!((doc.edit_generation(), doc.can_undo()), (generation, Some("Add line")), "{rot:?}: pointer frames never edit the document");
|
||||
@@ -1378,12 +1385,12 @@ fn lines_grow_and_shrink_with_their_handles_before_release() {
|
||||
grown.save(format!("{dir}/line-live-grow-{document_rotation}-{view_rotation}.png")).unwrap();
|
||||
shrunk.save(format!("{dir}/line-live-shrink-{document_rotation}-{view_rotation}.png")).unwrap();
|
||||
}
|
||||
h.drop_at(at(&h, 100.0, 250.0));
|
||||
h.drop_at(along(&h, 0.0));
|
||||
h.run_steps(3);
|
||||
let doc = h.state().session.get(h.state().views[0].id).unwrap();
|
||||
assert_eq!(doc.can_undo(), Some("Resize comment"), "{rot:?}");
|
||||
let [now] = rects(&h)[..] else { panic!("{rot:?}: still one line: {:?}", rects(&h)) };
|
||||
assert!(now.iter().zip([82.0, 248.0, 100.0, 252.0]).all(|(a, b)| (a - b).abs() < 0.01), "{rot:?}: {now:?}");
|
||||
assert!(now.iter().zip(line(-18.0, 0.0)).all(|(a, b)| (a - b).abs() < 0.01), "{rot:?}: {now:?}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1667,7 +1674,7 @@ fn mode_tab(h: &Harness<'static, PdfCraftApp>, label: &str) -> egui::Rect {
|
||||
}
|
||||
|
||||
/// Scroll the page until `what` (on screen) lies across the mode bar, then the cursor over each
|
||||
/// tab it lies under: with the All tools panel closed, Read, Edit, Convert and E-Sign.
|
||||
/// tab it lies under: with the All tools panel closed, every tab: All tools, Edit, Convert and E-Sign.
|
||||
fn mode_tab_cursors(
|
||||
h: &mut Harness<'static, PdfCraftApp>,
|
||||
what: impl Fn(&Harness<'static, PdfCraftApp>) -> egui::Rect,
|
||||
@@ -1681,7 +1688,7 @@ fn mode_tab_cursors(
|
||||
h.state_mut().views[0].goto = Some((0, (top - (tabs - y)) / page(h).height()));
|
||||
h.run_steps(4);
|
||||
let under = what(h);
|
||||
["Read", "Edit", "Convert", "E-Sign"].map(|label| {
|
||||
["All tools", "Edit", "Convert", "E-Sign"].map(|label| {
|
||||
let at = mode_tab(h, label).center();
|
||||
assert!(under.contains(at), "{under:?} lies under {label} at {at:?}");
|
||||
h.hover_at(at);
|
||||
@@ -1691,7 +1698,7 @@ fn mode_tab_cursors(
|
||||
}
|
||||
|
||||
const HAND_ON_EVERY_TAB: [(&str, egui::CursorIcon); 4] = [
|
||||
("Read", egui::CursorIcon::PointingHand),
|
||||
("All tools", egui::CursorIcon::PointingHand),
|
||||
("Edit", egui::CursorIcon::PointingHand),
|
||||
("Convert", egui::CursorIcon::PointingHand),
|
||||
("E-Sign", egui::CursorIcon::PointingHand),
|
||||
|
||||
@@ -1282,11 +1282,12 @@ fn mode_tab(h: &Harness<'static, PdfCraftApp>, label: &str) -> egui::Rect {
|
||||
}
|
||||
|
||||
/// Scroll the page until `what` (on screen) lies across the mode bar, then the cursor over each
|
||||
/// tab it lies under: with the All tools panel closed, Read, Edit, Convert and E-Sign.
|
||||
/// tab it lies under: with the All tools panel closed, Edit, Convert and E-Sign (the name field
|
||||
/// starts right of All tools).
|
||||
fn mode_tab_cursors(
|
||||
h: &mut Harness<'static, PdfCraftApp>,
|
||||
what: impl Fn(&Harness<'static, PdfCraftApp>) -> egui::Rect,
|
||||
) -> [(&'static str, egui::CursorIcon); 4] {
|
||||
) -> [(&'static str, egui::CursorIcon); 3] {
|
||||
let page = |h: &Harness<'static, PdfCraftApp>| h.state().views[0].page_screen_rect(0).expect("on screen");
|
||||
let y = what(h).center().y - page(h).top();
|
||||
let tabs = mode_tab(h, "Convert").center().y;
|
||||
@@ -1296,7 +1297,7 @@ fn mode_tab_cursors(
|
||||
h.state_mut().views[0].goto = Some((0, (top - (tabs - y)) / page(h).height()));
|
||||
h.run_steps(4);
|
||||
let under = what(h);
|
||||
["Read", "Edit", "Convert", "E-Sign"].map(|label| {
|
||||
["Edit", "Convert", "E-Sign"].map(|label| {
|
||||
let at = mode_tab(h, label).center();
|
||||
assert!(under.contains(at), "{under:?} lies under {label} at {at:?}");
|
||||
h.hover_at(at);
|
||||
@@ -1305,12 +1306,8 @@ fn mode_tab_cursors(
|
||||
})
|
||||
}
|
||||
|
||||
const HAND_ON_EVERY_TAB: [(&str, egui::CursorIcon); 4] = [
|
||||
("Read", egui::CursorIcon::PointingHand),
|
||||
("Edit", egui::CursorIcon::PointingHand),
|
||||
("Convert", egui::CursorIcon::PointingHand),
|
||||
("E-Sign", egui::CursorIcon::PointingHand),
|
||||
];
|
||||
const HAND_ON_EVERY_TAB: [(&str, egui::CursorIcon); 3] =
|
||||
[("Edit", egui::CursorIcon::PointingHand), ("Convert", egui::CursorIcon::PointingHand), ("E-Sign", egui::CursorIcon::PointingHand)];
|
||||
|
||||
/// A text field scrolled up under the mode bar leaves its tabs the hand (#2755). The field gave
|
||||
/// them its I-beam, and its open editor floated over them and took their clicks.
|
||||
|
||||
@@ -5,6 +5,9 @@ Label = "2 Replaced"
|
||||
Label = "0 Inserted"
|
||||
Label = "0 Deleted"
|
||||
Label = "1 Visual"
|
||||
Label = "Show:"
|
||||
CheckBox "Text" [on]
|
||||
CheckBox "Visual" [on]
|
||||
Button "Side by side"
|
||||
Button "New file only"
|
||||
Button "Mark as comments"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
Label = "Layers"
|
||||
Label = "1"
|
||||
Button "Close" [off]
|
||||
Button "Layer options" [off]
|
||||
CheckBox "Draft notes" [on]
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
Label = "Pages"
|
||||
Label = "2"
|
||||
Button "Close" [off]
|
||||
Label = "Thumbnail size"
|
||||
Label = "100%"
|
||||
Button "Smaller thumbnails" [off]
|
||||
Slider "Thumbnail size"
|
||||
Button "Larger thumbnails" [off]
|
||||
Button "Page 1" [off]
|
||||
Label = "1"
|
||||
Button "Page 2" [off]
|
||||
|
||||
Reference in New Issue
Block a user