use super::blocks::Blocks; use super::bracket::*; use diaphragm_core::{ core_shapes::Text, text::FontDescription, types::{Bounds, Float, ShapeContext}, ComplexShape, DrawResult, Drawable, SolverContext, }; #[derive(Clone)] pub struct BlockList { pub block_list: Vec>, pub block_unit_width: Float, pub bracket_width: Float, pub blocks_vert_padding: Float, } impl ComplexShape for BlockList { fn draw(&self, context: &ShapeContext, solver: &mut dyn SolverContext) -> DrawResult { let mut result = DrawResult::new(); let bounds = context.bounds(); // Left bracket let opening_bracket_left = { let bracket = Drawable::builder(Bracket { r#type: BracketType::Opening, }) .bounds( Bounds::builder() .top(bounds.top(solver)) .left(bounds.left(solver)) .width(self.bracket_width) .height(bounds.height(solver)) .build(solver), ) .stroke(context.stroke().clone()) .build(solver); let bracket_left = bracket.bounds().left(solver); result.push(bracket); bracket_left }; let bounds_left = bounds.left(solver); let mut x_acc = solver.float_add(&[bounds_left, self.bracket_width]); // Block list let bounds_top = bounds.top(solver); let bounds_height = bounds.height(solver); let wanted_blocks_top = solver.float_add(&[bounds_top, self.blocks_vert_padding]); let wanted_blocks_height = solver.float_sub(&[ bounds_height, self.blocks_vert_padding, self.blocks_vert_padding, ]); let mut block_list_iter = self.block_list.iter(); // First blocks if let Some(first_blocks) = block_list_iter.next() { // TODO: waaay too verbose let blocks_top = first_blocks.bounds().top(solver); let blocks_top_constraint = solver.float_eq(blocks_top, wanted_blocks_top); solver.constrain(blocks_top_constraint); let blocks_left = first_blocks.bounds().left(solver); let blocks_left_constraint = solver.float_eq(blocks_left, x_acc); solver.constrain(blocks_left_constraint); let blocks_height = first_blocks.bounds().height(solver); let blocks_height_constraint = solver.float_eq(blocks_height, wanted_blocks_height); solver.constrain(blocks_height_constraint); let block_unit_width_constraint = solver.float_eq(first_blocks.shape().unit_width, self.block_unit_width); solver.constrain(block_unit_width_constraint); result.push(first_blocks.clone()); let blocks_width = first_blocks.bounds().width(solver); x_acc = solver.float_add(&[x_acc, blocks_width]); } // Rest of the blocks for blocks in block_list_iter { // Comma let comma = Drawable::builder(Text { content: String::from(", "), font: FontDescription { family: String::from("mono"), style: Default::default(), weight: Default::default(), size: wanted_blocks_height, }, }) .bounds( Bounds::builder() .top(wanted_blocks_top) .left(x_acc) .build(solver), ) .stroke(context.stroke().clone()) .build(solver); let comma_width = comma.bounds().width(solver); x_acc = solver.float_add(&[x_acc, comma_width]); result.push(comma); // Blocks /* let blocks_context = ShapeContext { bounds: Bounds { top: blocks_top, left: x_acc, height: blocks_height, width: blocks_width, }, fill: FillStyle::default(), stroke: StrokeStyle::default(), }; */ let blocks_top = blocks.bounds().top(solver); let blocks_top_constraint = solver.float_eq(blocks_top, wanted_blocks_top); solver.constrain(blocks_top_constraint); let blocks_left = blocks.bounds().left(solver); let blocks_left_constraint = solver.float_eq(blocks_left, x_acc); solver.constrain(blocks_left_constraint); let blocks_height = blocks.bounds().height(solver); let blocks_height_constraint = solver.float_eq(blocks_height, wanted_blocks_height); solver.constrain(blocks_height_constraint); let block_unit_width_constraint = solver.float_eq(blocks.shape().unit_width, self.block_unit_width); solver.constrain(block_unit_width_constraint); result.push(blocks.clone()); let blocks_width = blocks.bounds().width(solver); x_acc = solver.float_add(&[x_acc, blocks_width]); } // Right bracket let closing_bracket_right = { let bracket = Drawable::builder(Bracket { r#type: BracketType::Closing, }) .bounds( Bounds::builder() .top(bounds.top(solver)) .left(x_acc) .width(self.bracket_width) .height(bounds.height(solver)) .build(solver), ) .stroke(context.stroke().clone()) .build(solver); let bracket_right = bracket.bounds().right(solver); result.push(bracket); bracket_right }; let this_width = solver.float_sub(&[closing_bracket_right, opening_bracket_left]); let bounds_width = bounds.width(solver); let bounds_width_constraint = solver.float_eq(bounds_width, this_width); solver.constrain(bounds_width_constraint); result } }