mirror of
https://github.com/storytold/designcraft.git
synced 2026-10-14 19:27:07 -04:00
V: Power Zoom by press-and-hold with the Hand tool
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
8ac240889f
commit
031d099b3a
4 files changed
+67
-4
No files matched your search
+1
-1
@@ -87,7 +87,7 @@ DesignCraft aims at full Adobe InDesign parity — and to be better: faster, ope
|
||||
- Move table rows and columns (`table.moveRow`, `table.moveColumn`, Table panel buttons; dragging on the canvas isn't there yet).
|
||||
- Object States (`states.create/show/rename/release/list`, Object States panel): multi-state objects show one state on screen and in PDF.
|
||||
- Buttons (`button.set/clear/list`, Buttons and Forms panel): go to page / next / previous / first / last / URL as PDF link annotations. Form fields need AcroForm support the PDF writer lacks.
|
||||
- Power Zoom (Hand tool, Alt-press): zoom out to the spread, aim the red view rectangle, release to zoom back in there. InDesign triggers it by press-and-hold instead.
|
||||
- Power Zoom (Hand tool: press and hold still for half a second, or Alt-press): zoom out to the spread, aim the red view rectangle, release to zoom back in there.
|
||||
- Graphic cells (`table.placeGraphic`, `table.textCell`, Table › Convert Cell Type, Table panel): images in table cells, fitted or filled, clipped to the cell on screen and in PDF.
|
||||
- Live Distribute (Space while dragging a selection handle; `transform.resize {distribute}`): objects keep their size and spread with the bounds.
|
||||
- Liquid Layout (`liquid.pageRule/object`, `guide.liquid`, `layout.createAlternate`, Liquid Layout panel): scale / re-center / guide-based / object-based page rules applied on page resize and Document Setup; dashed liquid guides; alternate layouts as resized page copies in a named section. Alternate layouts aren't linked to their source.
|
||||
|
||||
@@ -1362,6 +1362,26 @@ fn handle_input(app: &mut DesignApp, ui: &mut egui::Ui, resp: &egui::Response, r
|
||||
{
|
||||
events.push(PointerEvent { kind: PointerKind::Drag, pos: pos(p), mods: m });
|
||||
}
|
||||
// Power Zoom: holding the Hand tool still for half a second turns the press into one.
|
||||
let hold_id = egui::Id::new(("canvas_hold", app.pane));
|
||||
if down && !released && app.session.tool_id() == "hand" && !m.alt {
|
||||
let (now, origin_pos) = ui.input(|i| (i.time, i.pointer.press_origin()));
|
||||
let (start, fired): (f64, bool) = ui.data(|d| d.get_temp(hold_id)).unwrap_or((now, false));
|
||||
let still = origin_pos.zip(latest).is_some_and(|(o, l)| (o - l).length() < 3.0);
|
||||
if !fired && still && now - start >= 0.5 {
|
||||
let p = pos(latest.unwrap_or(rect.center()));
|
||||
events.push(PointerEvent { kind: PointerKind::Up, pos: p, mods: m });
|
||||
events.push(PointerEvent { kind: PointerKind::Down, pos: p, mods: Mods { alt: true, ..m } });
|
||||
ui.data_mut(|d| d.insert_temp(hold_id, (start, true)));
|
||||
} else {
|
||||
ui.data_mut(|d| d.insert_temp(hold_id, (start, fired)));
|
||||
if !fired {
|
||||
ui.ctx().request_repaint_after(std::time::Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ui.data_mut(|d| d.remove::<(f64, bool)>(hold_id));
|
||||
}
|
||||
if down && released {
|
||||
let p = latest.unwrap_or(rect.center());
|
||||
events.push(PointerEvent { kind: PointerKind::Up, pos: pos(p), mods: m });
|
||||
|
||||
@@ -2032,6 +2032,49 @@ mod tests {
|
||||
assert_eq!(run_ui(&mut app, "view.rotateSpread", &json!({"angle": 0})).unwrap().unwrap(), json!(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hand_tool_hold_starts_power_zoom() {
|
||||
let mut app = crate::DesignApp::new(designcraft_engine::Session::new(), crate::Services::default());
|
||||
app.session.execute("file.new", &json!({})).unwrap();
|
||||
let ctx = egui::Context::default();
|
||||
let frame = |app: &mut crate::DesignApp, t: f64, events: Vec<egui::Event>| {
|
||||
let input = egui::RawInput {
|
||||
screen_rect: Some(egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(1400.0, 900.0))),
|
||||
time: Some(t),
|
||||
events,
|
||||
..Default::default()
|
||||
};
|
||||
let mut out = ctx.run_ui(input, |ui| {
|
||||
app.logic(&ui.ctx().clone());
|
||||
app.ui(ui);
|
||||
});
|
||||
out.textures_delta.clear();
|
||||
};
|
||||
frame(&mut app, 0.0, vec![]);
|
||||
frame(&mut app, 0.05, vec![]);
|
||||
app.select_tool("hand");
|
||||
let r = app.canvas_rect.unwrap();
|
||||
let p = r.center();
|
||||
let z0 = app.view().unwrap().zoom;
|
||||
frame(&mut app, 0.1, vec![egui::Event::PointerMoved(p)]);
|
||||
frame(
|
||||
&mut app,
|
||||
0.2,
|
||||
vec![egui::Event::PointerButton { pos: p, button: egui::PointerButton::Primary, pressed: true, modifiers: Default::default() }],
|
||||
);
|
||||
frame(&mut app, 0.4, vec![]);
|
||||
assert!(app.power_zoom.is_none(), "not yet");
|
||||
frame(&mut app, 0.8, vec![]);
|
||||
assert!(app.power_zoom.is_some(), "holding still starts Power Zoom");
|
||||
frame(
|
||||
&mut app,
|
||||
0.9,
|
||||
vec![egui::Event::PointerButton { pos: p, button: egui::PointerButton::Primary, pressed: false, modifiers: Default::default() }],
|
||||
);
|
||||
assert!(app.power_zoom.is_none());
|
||||
assert!((app.view().unwrap().zoom - z0).abs() < 1e-9, "back at the zoom it started from");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn panels_float_and_dock() {
|
||||
let mut app = crate::DesignApp::new(designcraft_engine::Session::new(), crate::Services::default());
|
||||
|
||||
+3
-3
@@ -11,7 +11,7 @@ Each row of the InDesign feature catalogue is scored **D** (done), **P** (partia
|
||||
|---|---|---|---|---|---|
|
||||
| P0 | 102 | 100 | 2 | 0 | 99% |
|
||||
| P1 | 97 | 94 | 3 | 0 | 98% |
|
||||
| P2 | 76 | 50 | 26 | 0 | 83% |
|
||||
| P2 | 76 | 51 | 25 | 0 | 84% |
|
||||
|
||||
| Area | Parity |
|
||||
|---|---|
|
||||
@@ -31,7 +31,7 @@ Each row of the InDesign feature catalogue is scored **D** (done), **P** (partia
|
||||
| Interactivity & digital | 90% |
|
||||
| Output & production | 82% |
|
||||
| XML & automation | 83% |
|
||||
| View & navigation | 95% |
|
||||
| View & navigation | 96% |
|
||||
| Undo, history, saving | 100% |
|
||||
| Accessibility | 90% |
|
||||
|
||||
@@ -297,7 +297,7 @@ Open P0 items: Vector/page formats (PDF/AI/SVG/EPS place), Export to PDF (print)
|
||||
| XML & automation | Snippets | P1 | D |
|
||||
| XML & automation | Object Library | P2 | D |
|
||||
| View & navigation | Zoom commands | P0 | D |
|
||||
| View & navigation | Power Zoom | P2 | P |
|
||||
| View & navigation | Power Zoom | P2 | D |
|
||||
| View & navigation | Animated/scrubby zoom | P1 | D |
|
||||
| View & navigation | Screen modes | P0 | D |
|
||||
| View & navigation | Overprint preview | P1 | D |
|
||||
|
||||
Reference in new issue
Block a user