mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-09 12:32:52 +00:00
fix(ui): with Edit text, what has no menu gives way to a picture under it
Found in review. With Edit text, a right-click on added text or on an open paragraph's frame went to that, which has no menu: the picture under it was unselected and the page's menu opened. `main` opens the picture's. Those give way to a picture under them, as paragraphs do, and to nothing else: a comment under added text stays unselected, as before. A comment in `draw_pages` said a selected Prepare field keeps its menu off the pages. Since the page menu follows the right-click, it stays selected and the menu is the page's. Tests, each seen failing with the fix reverted: `a_right_click_on_added_text_over_a_picture_selects_the_picture`, `a_right_click_on_an_open_paragraphs_frame_over_a_picture_selects_the_picture`. `a_right_click_with_edit_text_on_added_text_over_a_comment_selects_no_comment` is a pin, seen failing with added text dropped from the hits outright. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4 files changed
+71
-4
No files matched your search
@@ -1676,7 +1676,7 @@ fn draw_pages(
|
||||
// Set again below by the page right-clicked: a right-click off the pages (between them,
|
||||
// beside one) anchors no page's menu, which then acts on the current page. It deselects the
|
||||
// comment, and Edit text's picture, too (below), as one on a page's empty part does. A
|
||||
// selected Prepare field keeps its menu, off the pages as on them.
|
||||
// selected Prepare field stays selected, and the menu is the page's there too.
|
||||
view.comments.context_at = None;
|
||||
view.menu_for = None;
|
||||
}
|
||||
|
||||
@@ -462,6 +462,9 @@ impl PageHits<'_> {
|
||||
/// whatever the field tool. Links count for the tools that reach them (Select; the Link tool,
|
||||
/// below). Edit text's paragraphs have no menu, and give way to the picture under them (the
|
||||
/// user's ruling): with Edit text, a picture under a link or a paragraph takes the right-click.
|
||||
/// Nor have added content or an open paragraph's frame: those give way to a picture under them,
|
||||
/// and to nothing else. (Where objects are selected together, the page view unselects the picture
|
||||
/// a right-click selects, and the menu is the page's.)
|
||||
/// A highlight over a link is the highlight's ([`comments::context_hit`]).
|
||||
/// The Link tool edits links and reaches no comment: on a document it can change, its
|
||||
/// right-click is what its press there would take (`under`, the hits at `p`), when that is
|
||||
@@ -473,11 +476,18 @@ impl PageHits<'_> {
|
||||
{
|
||||
return Some(press.owner);
|
||||
}
|
||||
let reached = self
|
||||
let reached: Vec<_> = self
|
||||
.hits(view, p, true, None)
|
||||
.into_iter()
|
||||
.filter(|h| (h.layer != Layer::Link || h.layer.reached_by(self.tool)) && !matches!(h.owner, Owner::Paragraph { .. }));
|
||||
top(reached, QuickTool::Select).map(|h| h.owner)
|
||||
.filter(|h| (h.layer != Layer::Link || h.layer.reached_by(self.tool)) && !matches!(h.owner, Owner::Paragraph { .. }))
|
||||
.collect();
|
||||
let on_top = top(reached.iter().cloned(), QuickTool::Select)?.owner;
|
||||
if self.tool == QuickTool::EditText && matches!(on_top, Owner::Added { .. } | Owner::Objects { part: crate::page_router::ObjectsPart::Frame })
|
||||
{
|
||||
let pictures = reached.into_iter().filter(|h| matches!(h.owner, Owner::Picture { .. }));
|
||||
return Some(top(pictures, QuickTool::Select).map_or(on_top, |h| h.owner));
|
||||
}
|
||||
Some(on_top)
|
||||
}
|
||||
|
||||
/// The hits at `p`, bottom up: links, comments; Edit text's pictures under its paragraphs (text
|
||||
|
||||
@@ -7336,6 +7336,47 @@ fn a_right_click_on_text_over_a_picture_selects_the_picture() {
|
||||
assert_eq!(selected, Some((0, 0)), "the picture under the text is selected for its menu");
|
||||
}
|
||||
|
||||
/// With Edit text, a right-click on added text over a picture is the picture's, which is selected
|
||||
/// for its menu: added text has no menu of its own. It unselected the picture and opened the page's.
|
||||
#[test]
|
||||
fn a_right_click_on_added_text_over_a_picture_selects_the_picture() {
|
||||
let mut h = picture_pages(false);
|
||||
h.state_mut().views[0].image_selection = None;
|
||||
assert!(h.state_mut().apply_edit(pdfcraft_engine::Edit::AddText {
|
||||
page: 0,
|
||||
text: pdfcraft_engine::AddedText { rect: [60.0, 190.0, 150.0, 205.0], text: "Added".into(), ..Default::default() },
|
||||
}));
|
||||
h.run_steps(3);
|
||||
let on_it = page_at(&h, 0, 100.0, 198.0);
|
||||
right_click_at(&mut h, on_it);
|
||||
let selected = h.state().views[0].image_selection.as_ref().map(|s| (s.page, s.index));
|
||||
assert_eq!(selected, Some((0, 0)), "the picture under the added text is selected for its menu");
|
||||
assert!(h.query_by_label("Flip horizontal").is_some(), "its menu opens");
|
||||
}
|
||||
|
||||
/// With Edit text, a right-click on the frame of a paragraph open for typing over a picture is the
|
||||
/// picture's too. It unselected the picture and opened the page's menu.
|
||||
#[test]
|
||||
fn a_right_click_on_an_open_paragraphs_frame_over_a_picture_selects_the_picture() {
|
||||
let mut h = picture_pages(false);
|
||||
h.state_mut().views[0].image_selection = None;
|
||||
h.run_steps(2);
|
||||
// "Overlay" lies on the picture, at x 40, y 220.
|
||||
let overlay = page_at(&h, 0, 50.0, 224.0);
|
||||
slipping_click(&mut h, overlay, overlay);
|
||||
assert!(h.state().views[0].line_editor.is_some(), "the paragraph is open for typing");
|
||||
let id = h.state().views[0].id;
|
||||
let blocks = h.state().session.get(id).unwrap().text_blocks(0);
|
||||
let block =
|
||||
blocks.iter().find(|b| b.rect[0] < 50.0 && 50.0 < b.rect[2] && b.rect[1] < 224.0 && 224.0 < b.rect[3]).expect("the paragraph opened").clone();
|
||||
// Its frame runs just outside its box.
|
||||
let frame = page_at(&h, 0, block.rect[0] as f32, ((block.rect[1] + block.rect[3]) / 2.0) as f32) - egui::vec2(3.0, 0.0);
|
||||
right_click_at(&mut h, frame);
|
||||
let selected = h.state().views[0].image_selection.as_ref().map(|s| (s.page, s.index));
|
||||
assert_eq!(selected, Some((0, 0)), "the picture under the frame is selected for its menu");
|
||||
assert!(h.query_by_label("Flip horizontal").is_some(), "its menu opens");
|
||||
}
|
||||
|
||||
/// In crop mode, a right-click on another picture selects it for its menu, as without crop mode. It
|
||||
/// went to crop mode's whole-page hit, which unselected every picture.
|
||||
#[test]
|
||||
|
||||
@@ -1579,6 +1579,22 @@ fn a_right_click_with_edit_text_on_a_paragraph_under_a_comment_selects_the_comme
|
||||
assert_eq!(h.state().views[0].comments.selected, None, "the paragraph beside the comment leaves it unselected");
|
||||
}
|
||||
|
||||
/// With Edit text, a right-click on added text over a comment selects no comment: what has no menu
|
||||
/// gives way to a picture under it and to nothing else, as before.
|
||||
#[test]
|
||||
fn a_right_click_with_edit_text_on_added_text_over_a_comment_selects_no_comment() {
|
||||
let mut h = open(comment_on_text_pdf(), "150", false);
|
||||
assert!(h.state_mut().execute("edit.edit_text"));
|
||||
assert!(h.state_mut().apply_edit(pdfcraft_engine::Edit::AddText {
|
||||
page: 0,
|
||||
text: pdfcraft_engine::AddedText { rect: [110.0, 296.0, 190.0, 311.0], text: "Added".into(), ..Default::default() },
|
||||
}));
|
||||
h.run_steps(4);
|
||||
let on_added = at(&h, 150.0, 303.0);
|
||||
right_click(&mut h, on_added);
|
||||
assert_eq!(h.state().views[0].comments.selected, None, "the comment under the added text is not selected");
|
||||
}
|
||||
|
||||
/// With a Prepare field tool a right-click is the tool's, as before: a comment under it is not
|
||||
/// selected.
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user