asdf_overlay/
layout.rs

1//! Minimal overlay surface layout implementation for smooth window resizing.
2//! If you need more advanced layout system, create a fullscreen overlay surface and bring your own layout system.
3
4use asdf_overlay_common::size::PercentLength;
5
6#[derive(Clone)]
7/// A simple overlay layout implementation.
8pub struct OverlayLayout {
9    /// X, Y Position of the overlay surface, relative to window's client size.
10    pub position: (PercentLength, PercentLength),
11    /// X, Y Positioning anchor of the overlay surface, relative to overlay's surface size.
12    pub anchor: (PercentLength, PercentLength),
13    /// Top, right, bottom, left margins of the overlay surface, relative to window's client size.
14    pub margin: (PercentLength, PercentLength, PercentLength, PercentLength),
15}
16
17impl OverlayLayout {
18    /// Create a new default [`OverlayLayout`].
19    pub const fn new() -> Self {
20        Self {
21            position: (PercentLength::ZERO, PercentLength::ZERO),
22            anchor: (PercentLength::ZERO, PercentLength::ZERO),
23            margin: (
24                PercentLength::ZERO,
25                PercentLength::ZERO,
26                PercentLength::ZERO,
27                PercentLength::ZERO,
28            ),
29        }
30    }
31
32    /// Calculate absolute position of the window relative to `screen`,
33    /// pretends overlay surface to have `size` size.
34    pub fn calc(&self, size: (u32, u32), screen: (u32, u32)) -> (i32, i32) {
35        let size = (size.0 as f32, size.1 as f32);
36        let screen = (screen.0 as f32, screen.1 as f32);
37        let (x, y) = self.position;
38        let (anchor_x, anchor_y) = self.anchor;
39        let (margin_top, margin_right, margin_bottom, margin_left) = self.margin;
40
41        let margin_left = margin_left.resolve(screen.0);
42        let margin_top = margin_top.resolve(screen.1);
43
44        let outer_width = margin_left + size.0 + margin_right.resolve(screen.0);
45        let outer_height = margin_top + size.1 + margin_bottom.resolve(screen.1);
46
47        let x = x.resolve(screen.0) - anchor_x.resolve(outer_width) + margin_left;
48        let y = y.resolve(screen.1) - anchor_y.resolve(outer_height) + margin_top;
49
50        (x.round() as i32, y.round() as i32)
51    }
52}
53
54impl Default for OverlayLayout {
55    fn default() -> Self {
56        Self::new()
57    }
58}