Reproduce wrapped geometry retained after foreign label preview refusal
This commit is contained in:
@@ -642,7 +642,23 @@ impl DiagramCanvas<'_> {
|
|||||||
scene
|
scene
|
||||||
}
|
}
|
||||||
fn begin_route(&self, state: &mut State, world: Point, handle: Handle, route: EdgeRoute) {
|
fn begin_route(&self, state: &mut State, world: Point, handle: Handle, route: EdgeRoute) {
|
||||||
let baseline = self.scene(state).routed.clone();
|
self.begin_route_with_profile(
|
||||||
|
state,
|
||||||
|
world,
|
||||||
|
handle,
|
||||||
|
route,
|
||||||
|
label_layout_experiment::profile(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
fn begin_route_with_profile(
|
||||||
|
&self,
|
||||||
|
state: &mut State,
|
||||||
|
world: Point,
|
||||||
|
handle: Handle,
|
||||||
|
route: EdgeRoute,
|
||||||
|
profile: label_layout_experiment::Profile,
|
||||||
|
) {
|
||||||
|
let baseline = self.scene_with_profile(state, profile).routed.clone();
|
||||||
state.route_drag = Some(Gesture {
|
state.route_drag = Some(Gesture {
|
||||||
context: self.context,
|
context: self.context,
|
||||||
start: world,
|
start: world,
|
||||||
|
|||||||
@@ -576,6 +576,8 @@ mod tests {
|
|||||||
};
|
};
|
||||||
p.diagrams.get_mut(&id).unwrap().routes = vec![EdgeRoute {
|
p.diagrams.get_mut(&id).unwrap().routes = vec![EdgeRoute {
|
||||||
edge: edge_id(),
|
edge: edge_id(),
|
||||||
|
source_attachment: None,
|
||||||
|
target_attachment: None,
|
||||||
waypoints: vec![],
|
waypoints: vec![],
|
||||||
label: Some(EdgeLabel {
|
label: Some(EdgeLabel {
|
||||||
fraction: initial.geometry.fraction,
|
fraction: initial.geometry.fraction,
|
||||||
@@ -633,6 +635,94 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
|
fn different_edge_preview_guard_rejection_restores_complete_core_geometry() {
|
||||||
|
// Exercise the actual gesture capture and core preview, with a pure
|
||||||
|
// explicit profile. Moving another label onto the wrapped target must
|
||||||
|
// reject wrapping, leaving the full original one-line target geometry.
|
||||||
|
// All twelve point arrays and every other frozen label remain exact.
|
||||||
|
let (p, id) = fixture();
|
||||||
|
let view = project_view(&p, id);
|
||||||
|
let core = route_diagram(&p, &p.diagrams[&id], &view);
|
||||||
|
let foreign = core
|
||||||
|
.edges
|
||||||
|
.values()
|
||||||
|
.find(|edge| edge.id != edge_id() && !edge.label.text.is_empty())
|
||||||
|
.unwrap();
|
||||||
|
let original_offset = Position {
|
||||||
|
x: foreign.label.center.x - foreign.label.anchor.x,
|
||||||
|
y: foreign.label.center.y - foreign.label.anchor.y,
|
||||||
|
};
|
||||||
|
let c = DiagramCanvas {
|
||||||
|
selected: foreign.id,
|
||||||
|
..canvas(&p, id)
|
||||||
|
};
|
||||||
|
for profile in [Profile::E, Profile::F] {
|
||||||
|
let mut state = State {
|
||||||
|
context: Some(c.context),
|
||||||
|
..State::default()
|
||||||
|
};
|
||||||
|
let initial = c.scene_with_profile(&state, profile);
|
||||||
|
let target = initial
|
||||||
|
.label_layout
|
||||||
|
.as_ref()
|
||||||
|
.expect("Initial witness must wrap");
|
||||||
|
c.begin_route_with_profile(
|
||||||
|
&mut state,
|
||||||
|
point(foreign.label.center),
|
||||||
|
Handle::Label {
|
||||||
|
original: original_offset,
|
||||||
|
},
|
||||||
|
EdgeRoute {
|
||||||
|
edge: foreign.id,
|
||||||
|
source_attachment: None,
|
||||||
|
target_attachment: None,
|
||||||
|
waypoints: vec![],
|
||||||
|
label: Some(EdgeLabel {
|
||||||
|
fraction: foreign.label.fraction,
|
||||||
|
offset: original_offset,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
profile,
|
||||||
|
);
|
||||||
|
state
|
||||||
|
.route_drag
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.move_to(point(target.geometry.center), 1.);
|
||||||
|
let diagram = c.preview_diagram(&state);
|
||||||
|
let expected = routing::route_edge_preview(&p, &diagram, &view, &core, foreign.id);
|
||||||
|
let mut guard_probe = expected.clone();
|
||||||
|
assert!(
|
||||||
|
apply(&p, &diagram, &view, &mut guard_probe, profile).is_none(),
|
||||||
|
"Foreign label now overlaps target: wrapping must be refused"
|
||||||
|
);
|
||||||
|
assert_eq!(guard_probe, expected);
|
||||||
|
let actual = c.scene_with_profile(&state, profile);
|
||||||
|
assert!(actual.label_layout.is_none());
|
||||||
|
for (edge, before) in &core.edges {
|
||||||
|
assert_eq!(
|
||||||
|
actual.routed.edges[edge].points, before.points,
|
||||||
|
"Label drag must not reroute"
|
||||||
|
);
|
||||||
|
if *edge != foreign.id && *edge != edge_id() {
|
||||||
|
assert_eq!(
|
||||||
|
actual.routed.edges[edge].label, before.label,
|
||||||
|
"Other labels remain frozen"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert_eq!(
|
||||||
|
actual.routed.edges[&edge_id()].label,
|
||||||
|
core.edges[&edge_id()].label,
|
||||||
|
"No Layout means original complete one-line target geometry, never stale wrapped hit bounds"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
*actual.routed, expected,
|
||||||
|
"Fallback is the complete core preview result"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
fn scene_and_measurement_cache_reuse_and_geometry_invalidation() {
|
fn scene_and_measurement_cache_reuse_and_geometry_invalidation() {
|
||||||
let (p, id) = fixture();
|
let (p, id) = fixture();
|
||||||
let c = canvas(&p, id);
|
let c = canvas(&p, id);
|
||||||
|
|||||||
Reference in New Issue
Block a user