Fallback layout animations by motion group
This commit is contained in:
parent
a516b2e721
commit
4ee2c324e1
3 changed files with 115 additions and 27 deletions
|
|
@ -81,6 +81,33 @@ pub fn plan_no_overlap(request: &MultiphaseRequest) -> Result<MultiphasePlan, Mu
|
|||
Err(MultiphaseError::NoPlan)
|
||||
}
|
||||
|
||||
pub(crate) fn partition_motion_groups(windows: &[MultiphaseWindow]) -> Vec<Vec<usize>> {
|
||||
let mut groups = vec![];
|
||||
let mut seen = vec![false; windows.len()];
|
||||
for start in 0..windows.len() {
|
||||
if seen[start] {
|
||||
continue;
|
||||
}
|
||||
seen[start] = true;
|
||||
let mut group = vec![];
|
||||
let mut pending = vec![start];
|
||||
while let Some(idx) = pending.pop() {
|
||||
group.push(idx);
|
||||
let bounds = motion_bounds(windows[idx]);
|
||||
for other in 0..windows.len() {
|
||||
if seen[other] || !bounds.intersects(&motion_bounds(windows[other])) {
|
||||
continue;
|
||||
}
|
||||
seen[other] = true;
|
||||
pending.push(other);
|
||||
}
|
||||
}
|
||||
group.sort_unstable();
|
||||
groups.push(group);
|
||||
}
|
||||
groups
|
||||
}
|
||||
|
||||
fn validate_request(request: &MultiphaseRequest) -> Result<(), MultiphaseError> {
|
||||
if request.bounds.is_empty() {
|
||||
return Err(MultiphaseError::EmptyBounds);
|
||||
|
|
@ -380,6 +407,10 @@ fn overlaps(rects: impl IntoIterator<Item = Rect>) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
fn motion_bounds(window: MultiphaseWindow) -> Rect {
|
||||
window.from.union(window.to)
|
||||
}
|
||||
|
||||
fn push_step(steps: &mut Vec<MultiphaseStep>, node_id: NodeId, from: Rect, to: Rect) {
|
||||
if from != to {
|
||||
steps.push(MultiphaseStep { node_id, from, to });
|
||||
|
|
@ -697,4 +728,48 @@ mod tests {
|
|||
}]);
|
||||
assert_eq!(plan_no_overlap(&req), Err(MultiphaseError::NoPlan));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn motion_groups_split_disjoint_layout_changes() {
|
||||
let windows = vec![
|
||||
MultiphaseWindow {
|
||||
node_id: id(1),
|
||||
from: rect(0, 0, 100, 100),
|
||||
to: rect(100, 0, 200, 100),
|
||||
},
|
||||
MultiphaseWindow {
|
||||
node_id: id(2),
|
||||
from: rect(100, 0, 200, 100),
|
||||
to: rect(0, 0, 100, 100),
|
||||
},
|
||||
MultiphaseWindow {
|
||||
node_id: id(3),
|
||||
from: rect(300, 0, 400, 100),
|
||||
to: rect(400, 0, 500, 100),
|
||||
},
|
||||
];
|
||||
assert_eq!(partition_motion_groups(&windows), vec![vec![0, 1], vec![2]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn motion_groups_are_transitive() {
|
||||
let windows = vec![
|
||||
MultiphaseWindow {
|
||||
node_id: id(1),
|
||||
from: rect(0, 0, 100, 100),
|
||||
to: rect(80, 0, 180, 100),
|
||||
},
|
||||
MultiphaseWindow {
|
||||
node_id: id(2),
|
||||
from: rect(170, 0, 270, 100),
|
||||
to: rect(250, 0, 350, 100),
|
||||
},
|
||||
MultiphaseWindow {
|
||||
node_id: id(3),
|
||||
from: rect(90, 0, 180, 100),
|
||||
to: rect(180, 0, 260, 100),
|
||||
},
|
||||
];
|
||||
assert_eq!(partition_motion_groups(&windows), vec![vec![0, 1, 2]]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue