Repair animation integration paths
This commit is contained in:
parent
31c289f628
commit
0fefe814c3
9 changed files with 229 additions and 35 deletions
|
|
@ -152,6 +152,7 @@ pub enum PlanStrategy {
|
|||
SingleAction,
|
||||
MixedSinglePhase,
|
||||
HierarchyOrderedScales,
|
||||
OrientationChange { from_axis: PhaseAxis },
|
||||
SwapLanes { axis: PhaseAxis },
|
||||
SpaceThenOrthogonalGrowth { axis: PhaseAxis },
|
||||
ReversedForwardPlan { original: Box<PlanStrategy> },
|
||||
|
|
@ -501,6 +502,22 @@ fn plan_forward(
|
|||
}
|
||||
}
|
||||
}
|
||||
for axis in [PhaseAxis::Horizontal, PhaseAxis::Vertical] {
|
||||
match plan_orientation_change(request, axis) {
|
||||
Ok(plan) => return Ok(plan),
|
||||
Err(error) => {
|
||||
record_rejection(
|
||||
&mut attempted,
|
||||
direction,
|
||||
PlanStrategy::OrientationChange { from_axis: axis },
|
||||
error,
|
||||
);
|
||||
if error != MultiphasePlanFailure::NoPattern {
|
||||
rejection.get_or_insert(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for axis in [PhaseAxis::Horizontal, PhaseAxis::Vertical] {
|
||||
match plan_axis_crossing_lanes(request, axis) {
|
||||
Ok(plan) => return Ok(plan),
|
||||
|
|
@ -920,6 +937,94 @@ fn plan_space_then_orthogonal_growth(
|
|||
)
|
||||
}
|
||||
|
||||
fn plan_orientation_change(
|
||||
request: &MultiphaseRequest,
|
||||
from_axis: PhaseAxis,
|
||||
) -> Result<MultiphasePlanned, MultiphasePlanFailure> {
|
||||
if request.windows.len() < 2 {
|
||||
return Err(MultiphasePlanFailure::NoPattern);
|
||||
}
|
||||
let to_axis = from_axis.other();
|
||||
let min_lane_size = sane_min_size(main_size(request.bounds, to_axis));
|
||||
let target_start = request
|
||||
.windows
|
||||
.first()
|
||||
.map(|window| main_start(window.to, from_axis))
|
||||
.ok_or(MultiphasePlanFailure::NoPattern)?;
|
||||
let target_end = request
|
||||
.windows
|
||||
.first()
|
||||
.map(|window| main_end(window.to, from_axis))
|
||||
.ok_or(MultiphasePlanFailure::NoPattern)?;
|
||||
let source_start = request
|
||||
.windows
|
||||
.first()
|
||||
.map(|window| main_start(window.from, to_axis))
|
||||
.ok_or(MultiphasePlanFailure::NoPattern)?;
|
||||
let source_end = request
|
||||
.windows
|
||||
.first()
|
||||
.map(|window| main_end(window.from, to_axis))
|
||||
.ok_or(MultiphasePlanFailure::NoPattern)?;
|
||||
if request.windows.iter().any(|window| {
|
||||
main_start(window.from, to_axis) != source_start
|
||||
|| main_end(window.from, to_axis) != source_end
|
||||
|| main_start(window.to, from_axis) != target_start
|
||||
|| main_end(window.to, from_axis) != target_end
|
||||
|| main_size(window.to, to_axis) < min_lane_size
|
||||
}) {
|
||||
return Err(MultiphasePlanFailure::NoPattern);
|
||||
}
|
||||
|
||||
let mut phase1 = vec![];
|
||||
let mut phase2 = vec![];
|
||||
let mut phase3 = vec![];
|
||||
for window in &request.windows {
|
||||
let lane = with_main_interval(
|
||||
window.from,
|
||||
to_axis,
|
||||
main_start(window.to, to_axis),
|
||||
main_end(window.to, to_axis),
|
||||
);
|
||||
let moved = with_main_interval(
|
||||
lane,
|
||||
from_axis,
|
||||
main_start(window.to, from_axis),
|
||||
main_start(window.to, from_axis) + main_size(lane, from_axis),
|
||||
);
|
||||
push_step(&mut phase1, window.node_id, window.from, lane);
|
||||
push_step(&mut phase2, window.node_id, lane, moved);
|
||||
push_step(&mut phase3, window.node_id, moved, window.to);
|
||||
}
|
||||
if phase1.is_empty() || phase3.is_empty() {
|
||||
return Err(MultiphasePlanFailure::NoPattern);
|
||||
}
|
||||
build_validated_plan(
|
||||
request,
|
||||
PlanStrategy::OrientationChange { from_axis },
|
||||
[
|
||||
phase_draft(
|
||||
PhaseKind::Scale,
|
||||
to_axis,
|
||||
phase1,
|
||||
PhaseReason::ShrinkIntoLanes { lane_axis: to_axis },
|
||||
),
|
||||
phase_draft(
|
||||
PhaseKind::Move,
|
||||
from_axis,
|
||||
phase2,
|
||||
PhaseReason::MoveThroughFreedSpace,
|
||||
),
|
||||
phase_draft(
|
||||
PhaseKind::Scale,
|
||||
from_axis,
|
||||
phase3,
|
||||
PhaseReason::GrowOutOfLanes,
|
||||
),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
struct MultiphasePhaseDraft {
|
||||
action: MultiphasePhaseActionDraft,
|
||||
steps: Vec<MultiphaseStep>,
|
||||
|
|
@ -1665,6 +1770,20 @@ mod tests {
|
|||
strategy: PlanStrategy::HierarchyOrderedScales,
|
||||
reason: MultiphasePlanFailure::NoPattern,
|
||||
},
|
||||
RejectedStrategy {
|
||||
direction,
|
||||
strategy: PlanStrategy::OrientationChange {
|
||||
from_axis: PhaseAxis::Horizontal,
|
||||
},
|
||||
reason: MultiphasePlanFailure::NoPattern,
|
||||
},
|
||||
RejectedStrategy {
|
||||
direction,
|
||||
strategy: PlanStrategy::OrientationChange {
|
||||
from_axis: PhaseAxis::Vertical,
|
||||
},
|
||||
reason: MultiphasePlanFailure::NoPattern,
|
||||
},
|
||||
RejectedStrategy {
|
||||
direction,
|
||||
strategy: PlanStrategy::SwapLanes {
|
||||
|
|
@ -2024,6 +2143,46 @@ mod tests {
|
|||
assert!(validate_plan_continuous(&req, plan));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn orientation_change_shrinks_moves_then_grows() {
|
||||
let req = request(vec![
|
||||
window(1, rect(0, 0, 200, 400), rect(0, 0, 400, 200)),
|
||||
window(2, rect(200, 0, 400, 400), rect(0, 200, 400, 400)),
|
||||
]);
|
||||
let planned = plan_no_overlap_explained(&req).unwrap();
|
||||
let plan = &planned.plan;
|
||||
|
||||
assert_eq!(
|
||||
planned.explanation.strategy,
|
||||
PlanStrategy::OrientationChange {
|
||||
from_axis: PhaseAxis::Horizontal,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
actions(plan),
|
||||
vec![
|
||||
PhaseAction {
|
||||
kind: PhaseKind::Scale,
|
||||
axis: PhaseAxis::Vertical,
|
||||
},
|
||||
PhaseAction {
|
||||
kind: PhaseKind::Move,
|
||||
axis: PhaseAxis::Horizontal,
|
||||
},
|
||||
PhaseAction {
|
||||
kind: PhaseKind::Scale,
|
||||
axis: PhaseAxis::Horizontal,
|
||||
},
|
||||
]
|
||||
);
|
||||
assert_eq!(step_to(plan, 0, id(1)), rect(0, 0, 200, 200));
|
||||
assert_eq!(step_to(plan, 0, id(2)), rect(200, 200, 400, 400));
|
||||
assert_eq!(step_to(plan, 1, id(2)), rect(0, 200, 200, 400));
|
||||
assert_eq!(step_to(plan, 2, id(1)), rect(0, 0, 400, 200));
|
||||
assert_eq!(step_to(plan, 2, id(2)), rect(0, 200, 400, 400));
|
||||
assert!(validate_plan_continuous(&req, plan));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn two_axis_redistribution_without_hierarchy_still_falls_back() {
|
||||
let req = request(vec![
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue