mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-14 04:10:55 +00:00
M8: an icon double-click keeps its selection when a modifier is held
egui reports a click on a double-click's release too, so the row's queued click ran after the zoom: with Ctrl held, a double-click on an unselected layer's icon toggled it back out of the selection, and Shift could restore a range. The icon branch now drops the queued click. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Model-Effort: Opus 5.5 drove; Fable 5.2 queued; Sonnet 5.5 measured and wrote at medium
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
9a29a3cbb7
commit
cf80dc1afa
@@ -842,6 +842,24 @@ fn search_fields_keep_their_text_in_the_middle() {
|
||||
assert!(off < 1.0, "Search assets is {off} points off the middle");
|
||||
}
|
||||
|
||||
/// The centre of `id`'s icon, a top-level row: the row's left edge is the first point from the
|
||||
/// left at which the pointer is over it, and the icon's centre is 8 (margin) + 4 + 22 points
|
||||
/// further right.
|
||||
fn icon_of(u: &mut Ui, id: NodeId) -> Pos2 {
|
||||
let y = u.row_at(id).y;
|
||||
let mut left = None;
|
||||
for x in 0..150 {
|
||||
let p = Pos2::new(x as f32, y);
|
||||
u.app.session.ds_mut().unwrap().hover = None;
|
||||
u.frame(vec![Event::PointerMoved(p)]);
|
||||
if u.app.session.ds().unwrap().hover == Some(id) {
|
||||
left = Some(x as f32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Pos2::new(left.expect("the row has a left edge") + 34.0, y)
|
||||
}
|
||||
|
||||
/// Measured in Figma's web app, 2026-11-12: a double-click on a layer's icon zooms the canvas to
|
||||
/// the layer and starts no rename (a double-click on the name renames, as before).
|
||||
#[test]
|
||||
@@ -852,20 +870,7 @@ fn a_double_click_on_a_layers_icon_zooms_to_it_instead_of_renaming() {
|
||||
s.execute("select.none", &json!({})).unwrap();
|
||||
let mut u = Ui::new(s);
|
||||
u.frame(vec![]);
|
||||
let y = u.row_at(far).y;
|
||||
// The row's left edge: the first point from the left at which the pointer is over it. At depth
|
||||
// 0 the icon's centre is 8 (margin) + 4 + 22 points further right.
|
||||
let mut left = None;
|
||||
for x in 0..150 {
|
||||
let p = Pos2::new(x as f32, y);
|
||||
u.app.session.ds_mut().unwrap().hover = None;
|
||||
u.frame(vec![Event::PointerMoved(p)]);
|
||||
if u.app.session.ds().unwrap().hover == Some(far) {
|
||||
left = Some(x as f32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let icon = Pos2::new(left.expect("the row has a left edge") + 34.0, y);
|
||||
let icon = icon_of(&mut u, far);
|
||||
let view = |u: &Ui| {
|
||||
let v = &u.app.session.ds().unwrap().view;
|
||||
(v.cx, v.cy, v.zoom)
|
||||
@@ -884,3 +889,28 @@ fn a_double_click_on_a_layers_icon_zooms_to_it_instead_of_renaming() {
|
||||
u.app.session.execute("view.zoomSelection", &json!({})).unwrap();
|
||||
assert_eq!(after, view(&u), "the view frames the layer, as view.zoomSelection does");
|
||||
}
|
||||
|
||||
/// A double-click's release is also a click on the row; with Ctrl held it must not toggle the layer
|
||||
/// back out of the selection the zoom just made, nor can Shift restore a range.
|
||||
#[test]
|
||||
fn an_icon_double_click_keeps_its_selection_when_a_modifier_is_held() {
|
||||
let mut s = Session::new();
|
||||
rect(&mut s, "near", 0.0, None);
|
||||
let far = rect(&mut s, "far", 3000.0, None);
|
||||
s.execute("select.none", &json!({})).unwrap();
|
||||
let mut u = Ui::new(s);
|
||||
u.frame(vec![]);
|
||||
let icon = icon_of(&mut u, far);
|
||||
let before = (u.app.session.ds().unwrap().view.cx, u.app.session.ds().unwrap().view.zoom);
|
||||
for _ in 0..2 {
|
||||
for pressed in [true, false] {
|
||||
let e = Event::PointerButton { pos: icon, button: egui::PointerButton::Primary, pressed, modifiers: CMD };
|
||||
u.frame_with(vec![Event::PointerMoved(icon), e], CMD);
|
||||
}
|
||||
}
|
||||
u.frame(vec![]);
|
||||
assert_eq!(u.app.session.selection(), vec![far], "the layer stays selected");
|
||||
assert_eq!(u.app.ui.rename, None);
|
||||
let v = &u.app.session.ds().unwrap().view;
|
||||
assert_ne!((v.cx, v.zoom), before, "the view frames the layer");
|
||||
}
|
||||
|
||||
@@ -1269,6 +1269,8 @@ fn layers(app: &mut FigApp, ui: &mut Ui) {
|
||||
app.run("select.set", json!({"ids": [row.id]}));
|
||||
}
|
||||
app.run("view.zoomSelection", json!({}));
|
||||
// The release is also a click: it must not toggle or extend the selection.
|
||||
clicked = None;
|
||||
} else if !crate::menus::dev_mode_refuses(app, "object.rename") {
|
||||
app.ui.rename = Some(Rename { id: row.id, start: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user