summaryrefslogtreecommitdiffstats
path: root/examples/lib-dfscq-log/src/blocks.rs
blob: 0576b7d880b297dd0b75895814b2b285a8a7624f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use diaphragm_core::{
    core_shapes::Rectangle,
    types::{Float, ShapeContext},
    ComplexShape, DrawResult, Drawable, SolverContext,
};

#[derive(Debug, Clone)]
pub struct Block {
    pub grow: u8,
}

impl ComplexShape for Block {
    fn draw(&self, context: &ShapeContext, _solver: &mut dyn SolverContext) -> DrawResult {
        let mut result = DrawResult::new();

        // Grow is handled at the upper level
        let block = Drawable::new(Rectangle {}, context.clone());

        result.push(block);

        result
    }
}

#[derive(Debug, Clone)]
pub struct Blocks {
    pub blocks: Vec<Drawable<Block>>,
    pub unit_width: Float,
}

impl ComplexShape for Blocks {
    fn draw(&self, context: &ShapeContext, solver: &mut dyn SolverContext) -> DrawResult {
        let mut result = DrawResult::new();

        let sum: u8 = self.blocks.iter().map(|block| block.shape().grow).sum();

        let mut rect_left = context.bounds().left(solver);
        let rect_top = context.bounds().top(solver);
        let rect_height = context.bounds().height(solver);

        for block in &self.blocks {
            let block_top = block.bounds().top(solver);
            let rect_top_constraint = solver.float_eq(block_top, rect_top);
            solver.constrain(rect_top_constraint);

            let block_left = block.bounds().left(solver);
            let rect_left_constraint = solver.float_eq(block_left, rect_left);
            solver.constrain(rect_left_constraint);

            let grow = Float::Fixed(block.shape().grow as f64);
            let block_width = block.bounds().width(solver);
            let rect_width = solver.float_mul(&[self.unit_width, grow]);
            let rect_width_constraint = solver.float_eq(block_width, rect_width);
            solver.constrain(rect_width_constraint);

            let block_height = block.bounds().height(solver);
            let rect_height_constraint = solver.float_eq(block_height, rect_height);
            solver.constrain(rect_height_constraint);

            result.push(block.clone());

            rect_left = solver.float_add(&[rect_left, rect_width]);
        }

        let this_width = solver.float_mul(&[self.unit_width, Float::Fixed(sum as f64)]);
        let bounds_width = context.bounds().width(solver);
        let bounds_width_constraint = solver.float_eq(bounds_width, this_width);
        solver.constrain(bounds_width_constraint);

        result
    }
}