mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-31 07:39:08 +00:00
fix(ui): Add text finishes a paragraph drag that leaves the paragraph's box
With Add text the page's own paragraphs took input only while the pointer was over one (over_source), and their drags end in edit_text_ui::page_input. A paragraph dragged off its box was left hanging after the release (block_drag), to land wherever the pointer next met a paragraph; one flicked off in its first move never started, so nothing moved. main has the same test. Add text now also acts on the paragraph the page router says holds the press, until the button is up, so the drag ends where it is released, as with Edit text, and Add text's new-box path does not take the press over. New test add_text_finishes_a_paragraph_drag_that_leaves_its_box, seen failing before the fix (the drag still pending after the release); the flick was checked by hand the same way. From CodeRabbit's third review of #5300. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2 files changed
+39
-2
No files matched your search
@@ -1275,9 +1275,13 @@ fn page_tool_input(ui: &mut egui::Ui, view: &mut DocView, frame: &mut PageFrame<
|
||||
crate::redact_ui::page_input(cx, over_text, view)
|
||||
};
|
||||
let on_objects = tool == QuickTool::EditText && can_modify && crate::object_ui::page_input(cx, view);
|
||||
// Add text acts on the page's own paragraphs over them, and on the one its press was on until
|
||||
// the button is up: a drag that leaves the box still ends, and no new box takes it over.
|
||||
let over_source = tool == QuickTool::AddText
|
||||
&& pointer
|
||||
.is_some_and(|p| !crate::content_ui::hits_added(&xf, info, i, added, p) && crate::edit_text_ui::over_paragraph(&xf, info, i, &lines, p));
|
||||
&& (matches!(view.router.owner(i), Some(crate::page_router::Owner::Paragraph { .. }))
|
||||
|| pointer.is_some_and(|p| {
|
||||
!crate::content_ui::hits_added(&xf, info, i, added, p) && crate::edit_text_ui::over_paragraph(&xf, info, i, &lines, p)
|
||||
}));
|
||||
let source_blocked = over_source && view.content.hold_blocked();
|
||||
if over_source && resp.clicked() && !source_blocked {
|
||||
if let Some(edit) = view.content.finish_draft(added) {
|
||||
|
||||
@@ -3994,6 +3994,39 @@ fn add_text_opens_a_paragraph_from_just_inside_its_edge() {
|
||||
assert!(h.state().views[0].content.draft.is_none(), "and starts no text box");
|
||||
}
|
||||
|
||||
/// With Add text a paragraph dragged off its own box still moves to where the button comes up, as
|
||||
/// with Edit text. Add text acted on the page's paragraphs only while the pointer was over one, so
|
||||
/// the drag was left hanging, to land wherever the pointer next met a paragraph.
|
||||
#[test]
|
||||
fn add_text_finishes_a_paragraph_drag_that_leaves_its_box() {
|
||||
let mut h = harness(2, |_| {});
|
||||
h.state_mut().quick_tool = pdfcraft_ui_egui::QuickTool::AddText;
|
||||
h.run_steps(2);
|
||||
let id = h.state().views[0].id;
|
||||
let before = h.state().session.get(id).unwrap().text_blocks(0)[0].rect;
|
||||
let r = h.state().views[0].page_screen_rect(0).expect("on screen");
|
||||
let k = r.width() / 200.0;
|
||||
let from = egui::pos2(r.left() + ((before[0] + before[2]) / 2.0) as f32 * k, r.top() + (300.0 - ((before[1] + before[3]) / 2.0) as f32) * k);
|
||||
// The drag starts in the box (8 px down), then goes 60 pt down, onto the blank page under it.
|
||||
h.hover_at(from);
|
||||
h.run_steps(1);
|
||||
h.drag_at(from);
|
||||
h.run_steps(1);
|
||||
h.hover_at(from + egui::vec2(0.0, 8.0));
|
||||
h.run_steps(1);
|
||||
for i in 1..=4 {
|
||||
h.hover_at(from + egui::vec2(0.0, 15.0 * k * i as f32));
|
||||
h.run_steps(1);
|
||||
}
|
||||
h.drop_at(from + egui::vec2(0.0, 60.0 * k));
|
||||
for _ in 0..10 {
|
||||
h.run_steps(2);
|
||||
}
|
||||
assert!(h.state().views[0].block_drag.is_none(), "the drag is over");
|
||||
let after = h.state().session.get(id).unwrap().text_blocks(0)[0].rect;
|
||||
assert!(before[1] - after[1] > 50.0, "the paragraph moved down with it: {before:?} to {after:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dragging_the_rotate_knob_turns_a_page_image() {
|
||||
let mut png = Vec::new();
|
||||
|
||||
Reference in new issue
Block a user