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
}
}
|