diff options
author | 2023-03-04 05:37:11 +0100 | |
---|---|---|
committer | 2023-03-04 05:37:11 +0100 | |
commit | 3a0d34c0240f4421737a6a08761f99d6f8140d02 (patch) | |
tree | c9a4a6b8e9c1db1b8fcd05bc98e3f131d5ef4bd5 /widget/src/pane_grid/axis.rs | |
parent | c54409d1711e1f615c7ea4b02c082954e340632a (diff) | |
download | iced-3a0d34c0240f4421737a6a08761f99d6f8140d02.tar.gz iced-3a0d34c0240f4421737a6a08761f99d6f8140d02.tar.bz2 iced-3a0d34c0240f4421737a6a08761f99d6f8140d02.zip |
Create `iced_widget` subcrate and re-organize the whole codebase
Diffstat (limited to 'widget/src/pane_grid/axis.rs')
-rw-r--r-- | widget/src/pane_grid/axis.rs | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/widget/src/pane_grid/axis.rs b/widget/src/pane_grid/axis.rs new file mode 100644 index 00000000..a3049230 --- /dev/null +++ b/widget/src/pane_grid/axis.rs @@ -0,0 +1,241 @@ +use crate::core::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 { + /// Splits the provided [`Rectangle`] on the current [`Axis`] with the + /// given `ratio` and `spacing`. + pub 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 + }, + ) + } + } + } + + /// Calculates the bounds of the split line in a [`Rectangle`] region. + pub fn split_line_bounds( + &self, + rectangle: Rectangle, + ratio: f32, + spacing: f32, + ) -> Rectangle { + match self { + Axis::Horizontal => Rectangle { + x: rectangle.x, + y: (rectangle.y + rectangle.height * ratio - spacing / 2.0) + .round(), + width: rectangle.width, + height: spacing, + }, + Axis::Vertical => Rectangle { + x: (rectangle.x + rectangle.width * ratio - spacing / 2.0) + .round(), + y: rectangle.y, + width: spacing, + height: rectangle.height, + }, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + enum Case { + Horizontal { + overall_height: f32, + spacing: f32, + top_height: f32, + bottom_y: f32, + bottom_height: f32, + }, + Vertical { + overall_width: f32, + spacing: f32, + left_width: f32, + right_x: f32, + right_width: f32, + }, + } + + #[test] + fn split() { + let cases = vec![ + // Even height, even spacing + Case::Horizontal { + overall_height: 10.0, + spacing: 2.0, + top_height: 4.0, + bottom_y: 6.0, + bottom_height: 4.0, + }, + // Odd height, even spacing + Case::Horizontal { + overall_height: 9.0, + spacing: 2.0, + top_height: 4.0, + bottom_y: 6.0, + bottom_height: 3.0, + }, + // Even height, odd spacing + Case::Horizontal { + overall_height: 10.0, + spacing: 1.0, + top_height: 5.0, + bottom_y: 6.0, + bottom_height: 4.0, + }, + // Odd height, odd spacing + Case::Horizontal { + overall_height: 9.0, + spacing: 1.0, + top_height: 4.0, + bottom_y: 5.0, + bottom_height: 4.0, + }, + // Even width, even spacing + Case::Vertical { + overall_width: 10.0, + spacing: 2.0, + left_width: 4.0, + right_x: 6.0, + right_width: 4.0, + }, + // Odd width, even spacing + Case::Vertical { + overall_width: 9.0, + spacing: 2.0, + left_width: 4.0, + right_x: 6.0, + right_width: 3.0, + }, + // Even width, odd spacing + Case::Vertical { + overall_width: 10.0, + spacing: 1.0, + left_width: 5.0, + right_x: 6.0, + right_width: 4.0, + }, + // Odd width, odd spacing + Case::Vertical { + overall_width: 9.0, + spacing: 1.0, + left_width: 4.0, + right_x: 5.0, + right_width: 4.0, + }, + ]; + for case in cases { + match case { + Case::Horizontal { + overall_height, + spacing, + top_height, + bottom_y, + bottom_height, + } => { + let a = Axis::Horizontal; + let r = Rectangle { + x: 0.0, + y: 0.0, + width: 10.0, + height: overall_height, + }; + let (top, bottom) = a.split(&r, 0.5, spacing); + assert_eq!( + top, + Rectangle { + height: top_height, + ..r + } + ); + assert_eq!( + bottom, + Rectangle { + y: bottom_y, + height: bottom_height, + ..r + } + ); + } + Case::Vertical { + overall_width, + spacing, + left_width, + right_x, + right_width, + } => { + let a = Axis::Vertical; + let r = Rectangle { + x: 0.0, + y: 0.0, + width: overall_width, + height: 10.0, + }; + let (left, right) = a.split(&r, 0.5, spacing); + assert_eq!( + left, + Rectangle { + width: left_width, + ..r + } + ); + assert_eq!( + right, + Rectangle { + x: right_x, + width: right_width, + ..r + } + ); + } + } + } + } +} |