Info panel: show guide coordinates while dragging outside the canvas (#5728) (#5768)

* Fix Info panel guide coordinates during ruler drags (storytold/photocraft#5728).

Show the dragged guide position on one axis while the pointer is outside the canvas, matching Photoshop.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Merge main; fill GuideDrag's new press field in the test; cargo fmt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
nrq6993-a11y
2026-10-14 23:50:14 -04:00
committed by GitHub
co-authored by Cursor Claude Opus 5.5 Brandon Thomas
parent be32a7c651
commit 96c683b25d
2 changed files with 27 additions and 2 deletions
+9 -2
View File
@@ -1797,6 +1797,13 @@ fn info_panel(app: &mut PhotocraftApp, ui: &mut egui::Ui) {
.hover_doc
.map(|p| (p[0].floor() as i32, p[1].floor() as i32))
.filter(|(x, y)| *x >= 0 && *y >= 0 && *x < size.width as i32 && *y < size.height as i32);
// While a guide is dragged (#5728), the Info panel shows its position in one axis only, even
// when the pointer is outside the canvas (ruler drags do not update `hover_doc` there).
let (guide_x, guide_y) = match app.guide_drag {
Some(d) if d.vertical => (Some(d.pos), None),
Some(d) => (None, Some(d.pos)),
None => (None, None),
};
// The readout averages the Eyedropper's Sample Size, as in Photoshop (#1649).
let sample_size = app.ui.tool_options.eyedropper_size;
let rgba = pos.and_then(|(x, y)| {
@@ -1835,8 +1842,8 @@ fn info_panel(app: &mut PhotocraftApp, ui: &mut egui::Ui) {
ui.columns(2, |cols| {
let dash = || "—".to_string();
// Measured from the rulers' zero point (#2955).
row(&mut cols[0], "X:", pos.map_or_else(dash, |p| fx(p.0 as f64 - origin[0])));
row(&mut cols[0], "Y:", pos.map_or_else(dash, |p| fy(p.1 as f64 - origin[1])));
row(&mut cols[0], "X:", guide_x.map(|p| fx(p - origin[0])).or_else(|| pos.map(|p| fx(p.0 as f64 - origin[0]))).unwrap_or_else(dash));
row(&mut cols[0], "Y:", guide_y.map(|p| fy(p - origin[1])).or_else(|| pos.map(|p| fy(p.1 as f64 - origin[1]))).unwrap_or_else(dash));
row(&mut cols[1], "W:", sel.map_or_else(dash, |r| fx(r.width() as f64)));
row(&mut cols[1], "H:", sel.map_or_else(dash, |r| fy(r.height() as f64)));
});
+18
View File
@@ -668,6 +668,24 @@ mod tests {
assert!(h.query_by_label("50").is_none(), "not the raw image x");
}
/// #5728: dragging a guide shows its coordinate in the Info panel on one axis only.
#[test]
fn info_panel_shows_guide_drag_position_outside_canvas() {
use egui_kittest::kittest::Queryable;
let mut app = PhotocraftApp::new(photocraft_engine::Session::new(), crate::Services::default());
app.run("file.new", json!({"width": 200, "height": 100})).unwrap();
app.hover_doc = None;
app.guide_drag = Some(GuideDrag { vertical: true, index: None, pos: 42.0, press: 42.0 });
let mut h = egui_kittest::Harness::builder()
.with_size(vec2(260.0, 240.0))
.build_ui_state(|ui, app| crate::panels::dock_body(app, ui, crate::dock::Group::Navigator, 2), app);
h.run_steps(2);
assert!(h.query_by_label("42").is_some(), "vertical guide: X readout");
h.state_mut().guide_drag = Some(GuideDrag { vertical: false, index: None, pos: 17.0, press: 17.0 });
h.run_steps(2);
assert!(h.query_by_label("17").is_some(), "horizontal guide: Y readout");
}
#[test]
fn percentage_grid_spacing_uses_both_canvas_dimensions() {
let mut g = GuidesGridAndSlices { grid_unit: Unit::Percent, gridline_every: 20.0, subdivisions: 2, ..Default::default() };