Skip to main content

impulse_ui_kit/utils/
position.rs

1//! Calculate position utility.
2
3/// Overlay side to show at.
4#[derive(Clone, Copy, PartialEq)]
5#[allow(missing_docs)]
6pub enum OverlaySide {
7  Top,
8  Right,
9  Bottom,
10  Left,
11}
12
13/// Overlay align to show with.
14#[derive(Clone, Copy, PartialEq)]
15#[allow(missing_docs)]
16pub enum OverlayAlign {
17  Start,
18  Center,
19  End,
20}
21
22/// Calculates overlay position based on given positions, side and align.
23#[allow(clippy::too_many_arguments)]
24pub fn calculate_position(
25  trigger_top: f64,
26  trigger_left: f64,
27  trigger_width: f64,
28  trigger_height: f64,
29  content_width: f64,
30  content_height: f64,
31  side: OverlaySide,
32  align: OverlayAlign,
33  side_offset: i32,
34) -> (f64, f64) {
35  let offset = side_offset as f64;
36
37  let (mut top, mut left) = match side {
38    OverlaySide::Top => (trigger_top - content_height - offset, trigger_left),
39    OverlaySide::Bottom => (trigger_top + trigger_height + offset, trigger_left),
40    OverlaySide::Left => (trigger_top, trigger_left - content_width - offset),
41    OverlaySide::Right => (trigger_top, trigger_left + trigger_width + offset),
42  };
43
44  match side {
45    OverlaySide::Top | OverlaySide::Bottom => {
46      left += match align {
47        OverlayAlign::Start => 0.0,
48        OverlayAlign::Center => (trigger_width - content_width) / 2.0,
49        OverlayAlign::End => trigger_width - content_width,
50      };
51    }
52    OverlaySide::Left | OverlaySide::Right => {
53      top += match align {
54        OverlayAlign::Start => 0.0,
55        OverlayAlign::Center => (trigger_height - content_height) / 2.0,
56        OverlayAlign::End => trigger_height - content_height,
57      };
58    }
59  }
60
61  (top, left)
62}