use diaphragm_core::{ types::{Float, ShapeContext}, ComplexShape, DrawResult, DynDrawable, SolverContext, }; #[derive(Clone)] pub struct Spacer { pub margin_left: Float, pub margin_right: Float, pub margin_top: Float, pub margin_bottom: Float, pub content: DynDrawable, } impl Spacer { pub fn builder>(drawable: T) -> SpacerBuilder { SpacerBuilder::new(drawable) } } impl ComplexShape for Spacer { fn draw(&self, context: &ShapeContext, solver: &mut dyn SolverContext) -> DrawResult { let mut result = DrawResult::new(); let bounds_left = context.bounds().left(solver); let bounds_right = context.bounds().right(solver); let bounds_top = context.bounds().top(solver); let bounds_bottom = context.bounds().bottom(solver); let wanted_content_left = solver.float_add(&[bounds_left, self.margin_left]); let content_left = self.content.bounds().left(solver); let content_left_constraint = solver.float_eq(content_left, wanted_content_left); solver.constrain(content_left_constraint); let wanted_content_right = solver.float_sub(&[bounds_right, self.margin_right]); let content_right = self.content.bounds().right(solver); let content_right_constraint = solver.float_eq(content_right, wanted_content_right); solver.constrain(content_right_constraint); let wanted_content_top = solver.float_add(&[bounds_top, self.margin_top]); let content_top = self.content.bounds().top(solver); let content_top_constraint = solver.float_eq(content_top, wanted_content_top); solver.constrain(content_top_constraint); let wanted_content_bottom = solver.float_sub(&[bounds_bottom, self.margin_bottom]); let content_bottom = self.content.bounds().bottom(solver); let content_bottom_constraint = solver.float_eq(content_bottom, wanted_content_bottom); solver.constrain(content_bottom_constraint); result.push_dyn(self.content.clone()); result } } #[derive(Clone)] pub struct SpacerBuilder { pub margin_left: Option, pub margin_right: Option, pub margin_top: Option, pub margin_bottom: Option, pub content: DynDrawable, } impl SpacerBuilder { pub fn new>(drawable: T) -> Self { SpacerBuilder { margin_left: None, margin_right: None, margin_top: None, margin_bottom: None, content: drawable.into(), } } pub fn margin_left(&mut self, margin_left: Float) -> &mut Self { self.margin_left = Some(margin_left); self } pub fn margin_right(&mut self, margin_right: Float) -> &mut Self { self.margin_right = Some(margin_right); self } pub fn margin_top(&mut self, margin_top: Float) -> &mut Self { self.margin_top = Some(margin_top); self } pub fn margin_bottom(&mut self, margin_bottom: Float) -> &mut Self { self.margin_bottom = Some(margin_bottom); self } pub fn vertical_align_center(&mut self, solver: &mut dyn SolverContext) -> &mut Self { let vertical_margin = solver.new_free_float(); self.margin_top = Some(vertical_margin); self.margin_bottom = Some(vertical_margin); self } pub fn vertical_align_center_with(&mut self, margin: Float) -> &mut Self { self.margin_top = Some(margin); self.margin_bottom = Some(margin); self } pub fn horizontal_align_center(&mut self, solver: &mut dyn SolverContext) -> &mut Self { let horizontal_margin = solver.new_free_float(); self.margin_left = Some(horizontal_margin); self.margin_right = Some(horizontal_margin); self } pub fn horizontal_align_center_with(&mut self, margin: Float) -> &mut Self { self.margin_left = Some(margin); self.margin_right = Some(margin); self } pub fn build(&self, solver: &mut dyn SolverContext) -> Spacer { Spacer { margin_left: self.margin_left.unwrap_or_else(|| solver.new_free_float()), margin_right: self.margin_right.unwrap_or_else(|| solver.new_free_float()), margin_top: self.margin_top.unwrap_or_else(|| solver.new_free_float()), margin_bottom: self .margin_bottom .unwrap_or_else(|| solver.new_free_float()), content: self.content.clone(), } } }