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