atagen

monolith

public
Star0
Watch0
28e12a7e36cd0fa0d8a578bc1b88205d8d1e3300
1
ssh://brewery@pls.lobotomise.me:33/atagen/monolith.git
crates/planner/src/blocks.rsRust58 lines1.8 KB
1
use crate::geom::Rect;
2
use crate::plan::{Config, Group, Plan, plan};
3
4
/// Plans with each block moving rigidly, for moves whose unit is a whole
5
/// container such as reordering viewed tags. Blocks must partition the
6
/// windows, and every window must keep its place inside its block.
7
pub fn plan_blocks(from: &[Rect], to: &[Rect], blocks: &[Vec<usize>], cfg: &Config) -> Plan {
8
    let bounds = |l: &[Rect]| -> Vec<Rect> {
9
        blocks
10
            .iter()
11
            .map(|b| Rect::bounding(b.iter().map(|&i| &l[i])))
12
            .collect()
13
    };
14
    let (bf, bt) = (bounds(from), bounds(to));
15
    let bp = plan(&bf, &bt, cfg);
16
    let last = bp.keyframes.len() - 1;
17
    let keyframes = bp
18
        .keyframes
19
        .iter()
20
        .enumerate()
21
        .map(|(k, key)| match k {
22
            0 => from.to_vec(),
23
            k if k == last => to.to_vec(),
24
            _ => {
25
                let mut frame = from.to_vec();
26
                for (b, members) in blocks.iter().enumerate() {
27
                    for &i in members {
28
                        frame[i] = reframe(&from[i], &bf[b], &key[b]);
29
                    }
30
                }
31
                frame
32
            }
33
        })
34
        .collect();
35
    let groups = bp
36
        .groups
37
        .into_iter()
38
        .map(|g| Group {
39
            members: g
40
                .members
41
                .iter()
42
                .flat_map(|&b| blocks[b].iter().copied())
43
                .collect(),
44
            ..g
45
        })
46
        .collect();
47
    Plan { keyframes, groups }
48
}
49
50
fn reframe(r: &Rect, from: &Rect, to: &Rect) -> Rect {
51
    let scale = |v: f64, len: f64| if len > 0.0 { v / len } else { 0.0 };
52
    Rect::new(
53
        to.x + scale(r.x - from.x, from.w) * to.w,
54
        to.y + scale(r.y - from.y, from.h) * to.h,
55
        scale(r.w, from.w) * to.w,
56
        scale(r.h, from.h) * to.h,
57
    )
58
}