fix(blocks): show directional Flip grip arrows

Use the existing triangular grip marker in Test Block and saved drawing references. Point it across the reflection line, transform it with the INSERT, and reverse the arrow when the native Flip state changes.

Validate arrow shape and both directions through the existing mouse-click, undo/redo and reopen regression in both contexts.
This commit is contained in:
Karim Jerbi committed 2026-10-17 09:54:30 +01:00
1 parent 1ee432ac64
commit 94940ad77c
3 files changed
+43 -12

No files matched your search

+12 -12
View File
@@ -242,12 +242,12 @@ impl OpenCADStudio {
id: TEST_GRIP_START + index,
world,
is_midpoint: false,
shape: if p.flip {
crate::scene::model::object::GripShape::Square
} else {
crate::scene::model::object::GripShape::Triangle
},
dir: None,
shape: crate::scene::model::object::GripShape::Triangle,
dir: actions::grip_direction(&p, value).and_then(|direction| {
(actions::v(transform.apply(actions::native(direction)))
- actions::v(transform.apply(codec::types::Vector3::ZERO)))
.try_normalize()
}),
axis: None,
});
}
@@ -336,12 +336,12 @@ impl OpenCADStudio {
id: TEST_GRIP_START + index,
world,
is_midpoint: false,
shape: if p.flip {
crate::scene::model::object::GripShape::Square
} else {
crate::scene::model::object::GripShape::Triangle
},
dir: None,
shape: crate::scene::model::object::GripShape::Triangle,
dir: actions::grip_direction(&p, value).and_then(|direction| {
(actions::v(transform.apply(actions::native(direction)))
- actions::v(transform.apply(codec::types::Vector3::ZERO)))
.try_normalize()
}),
axis: None,
});
}
+22
View File
@@ -270,12 +270,34 @@ fn block_actions_rotate_flip_mouse_grips_authoring_history_and_reopen() {
app.tabs[i].scene.selected.insert(insert);
app.refresh_properties();
let depth = app.tabs[i].history.undo_stack.len();
let flip_grip = app.tabs[i]
.selected_grips
.iter()
.find(|g| {
super::block_actions::is_test_grip(g.id) && g.world.distance(flip.reference) < 1e-5
})
.unwrap();
assert_eq!(
flip_grip.shape,
crate::scene::model::object::GripShape::Triangle
);
assert!(flip_grip.dir.unwrap().distance(glam::DVec3::Y) < 1e-5);
click(&mut app, flip.reference);
assert!(
app.tabs[i].active_cmd.is_none(),
"Flip toggles immediately without point input"
);
check(&app, insert, -Vector3::UNIT_Y);
app.tabs[i].scene.selected.insert(insert);
app.refresh_properties();
let flip_grip = app.tabs[i]
.selected_grips
.iter()
.find(|g| {
super::block_actions::is_test_grip(g.id) && g.world.distance(flip.reference) < 1e-5
})
.unwrap();
assert!(flip_grip.dir.unwrap().distance(-glam::DVec3::Y) < 1e-5);
assert_eq!(app.tabs[i].history.undo_stack.len(), depth + 1);
app.undo_steps(1);
check(&app, insert, Vector3::UNIT_Y);
+9
View File
@@ -172,6 +172,15 @@ pub(crate) fn grip_position(p: &Parameter, value: Value) -> DVec3 {
}
}
/// A Flip arrow points across its reflection line and reverses with its state.
pub(crate) fn grip_direction(p: &Parameter, value: Value) -> Option<DVec3> {
let Value::Flip(flipped) = value else {
return None;
};
let across = DVec3::Z.cross(p.end - p.base).try_normalize()?;
Some(if flipped { -across } else { across })
}
pub(crate) fn parameters(doc: &CadDocument, definition: Handle, kind: Kind) -> Vec<Parameter> {
let Ok(Some(graph)) = authoring::graph(doc, definition) else {
return vec![];