use crate::Rectangle; /// A fixed reference line for the measurement of coordinates. #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum Axis { /// The horizontal axis: — Horizontal, /// The vertical axis: | Vertical, } impl Axis { pub(super) fn split( &self, rectangle: &Rectangle, ratio: f32, spacing: f32, ) -> (Rectangle, Rectangle) { match self { Axis::Horizontal => { let height_top = (rectangle.height * ratio - spacing / 2.0).round(); let height_bottom = rectangle.height - height_top - spacing; ( Rectangle { height: height_top, ..*rectangle }, Rectangle { y: rectangle.y + height_top + spacing, height: height_bottom, ..*rectangle }, ) } Axis::Vertical => { let width_left = (rectangle.width * ratio - spacing / 2.0).round(); let width_right = rectangle.width - width_left - spacing; ( Rectangle { width: width_left, ..*rectangle }, Rectangle { x: rectangle.x + width_left + spacing, width: width_right, ..*rectangle }, ) } } } } #[cfg(test)] mod tests { use super::*; #[test] fn split_horizontal() { let a = Axis::Horizontal; // rectangle height, spacing, top height, bottom y, bottom height let cases = vec![ // Even height, even spacing (10.0, 2.0, 4.0, 6.0, 4.0), // Odd height, even spacing (9.0, 2.0, 4.0, 6.0, 3.0), // Even height, odd spacing (10.0, 1.0, 5.0, 6.0, 4.0), // Odd height, odd spacing (9.0, 1.0, 4.0, 5.0, 4.0), ]; for case in cases { let (h0, spacing, h1_top, y_bottom, h1_bottom) = case; let r = Rectangle { x: 0.0, y: 0.0, width: 10.0, height: h0, }; let (top, bottom) = a.split(&r, 0.5, spacing); assert_eq!( top, Rectangle { height: h1_top, ..r } ); assert_eq!( bottom, Rectangle { y: y_bottom, height: h1_bottom, ..r } ); } } #[test] fn split_vertical() { let a = Axis::Vertical; // rectangle width, spacing, left width, right x, right width let cases = vec![ // Even width, even spacing (10.0, 2.0, 4.0, 6.0, 4.0), // Odd width, even spacing (9.0, 2.0, 4.0, 6.0, 3.0), // Even width, odd spacing (10.0, 1.0, 5.0, 6.0, 4.0), // Odd width, odd spacing (9.0, 1.0, 4.0, 5.0, 4.0), ]; for case in cases { let (w0, spacing, w1_left, x_right, w1_right) = case; let r = Rectangle { x: 0.0, y: 0.0, width: w0, height: 10.0, }; let (left, right) = a.split(&r, 0.5, spacing); assert_eq!( left, Rectangle { width: w1_left, ..r } ); assert_eq!( right, Rectangle { x: x_right, width: w1_right, ..r } ); } } }