leftwm-core 0.4.1

A window manager for Adventurers
Documentation
use crate::models::Xyhw;
use crate::models::XyhwBuilder;

use super::Screen;

#[derive(Copy, Clone, Debug, Default)]
pub struct DockArea {
    pub top: i32,
    pub top_start_x: i32,
    pub top_end_x: i32,

    pub bottom: i32,
    pub bottom_start_x: i32,
    pub bottom_end_x: i32,

    pub right: i32,
    pub right_start_y: i32,
    pub right_end_y: i32,

    pub left: i32,
    pub left_start_y: i32,
    pub left_end_y: i32,
}

impl From<&[i64]> for DockArea {
    fn from(slice: &[i64]) -> Self {
        Self {
            left: slice[0] as i32,
            right: slice[1] as i32,
            top: slice[2] as i32,
            bottom: slice[3] as i32,
            left_start_y: slice[4] as i32,
            left_end_y: slice[5] as i32,
            right_start_y: slice[6] as i32,
            right_end_y: slice[7] as i32,
            top_start_x: slice[8] as i32,
            top_end_x: slice[9] as i32,
            bottom_start_x: slice[10] as i32,
            bottom_end_x: slice[11] as i32,
        }
    }
}

impl From<&[i32]> for DockArea {
    fn from(slice: &[i32]) -> Self {
        Self {
            left: slice[0],
            right: slice[1],
            top: slice[2],
            bottom: slice[3],
            left_start_y: slice[4],
            left_end_y: slice[5],
            right_start_y: slice[6],
            right_end_y: slice[7],
            top_start_x: slice[8],
            top_end_x: slice[9],
            bottom_start_x: slice[10],
            bottom_end_x: slice[11],
        }
    }
}

impl DockArea {
    #[must_use]
    pub fn as_xyhw(
        &self,
        screens_height: i32,
        screens_width: i32,
        screen: &Screen,
    ) -> Option<Xyhw> {
        if self.top > 0 {
            return Some(self.xyhw_from_top(screen.bbox.y));
        }
        if self.bottom > 0 {
            return Some(self.xyhw_from_bottom(screens_height, screen.bbox.y + screen.bbox.height));
        }
        if self.left > 0 {
            return Some(self.xyhw_from_left(screen.bbox.x));
        }
        if self.right > 0 {
            return Some(self.xyhw_from_right(screens_width, screen.bbox.x + screen.bbox.width));
        }
        None
    }

    fn xyhw_from_top(&self, screen_y: i32) -> Xyhw {
        XyhwBuilder {
            x: self.top_start_x,
            y: screen_y,
            h: self.top - screen_y,
            w: self.top_end_x - self.top_start_x,
            ..XyhwBuilder::default()
        }
        .into()
    }

    fn xyhw_from_bottom(&self, screens_height: i32, screen_bottom: i32) -> Xyhw {
        XyhwBuilder {
            x: self.bottom_start_x,
            y: screens_height - self.bottom,
            h: self.bottom - (screens_height - screen_bottom),
            w: self.bottom_end_x - self.bottom_start_x,
            ..XyhwBuilder::default()
        }
        .into()
    }

    fn xyhw_from_left(&self, screen_x: i32) -> Xyhw {
        XyhwBuilder {
            x: screen_x,
            y: self.left_start_y,
            h: self.left_end_y - self.left_start_y,
            w: self.left - screen_x,
            ..XyhwBuilder::default()
        }
        .into()
    }

    fn xyhw_from_right(&self, screens_width: i32, screen_right: i32) -> Xyhw {
        XyhwBuilder {
            x: screens_width - self.right,
            y: self.right_start_y,
            h: self.right_end_y - self.right_start_y,
            w: self.right - (screens_width - screen_right),
            ..XyhwBuilder::default()
        }
        .into()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn should_be_able_to_build_from_top() {
        let area = DockArea {
            top: 2,
            top_start_x: 10,
            top_end_x: 200,
            ..DockArea::default()
        };
        let expected: Xyhw = XyhwBuilder {
            h: 2,
            w: 190,
            x: 10,
            y: 0,
            ..XyhwBuilder::default()
        }
        .into();
        assert_eq!(area.xyhw_from_top(0), expected);
    }

    #[test]
    fn should_be_able_to_build_from_bottom() {
        let area = DockArea {
            bottom: 2,
            bottom_start_x: 10,
            bottom_end_x: 200,
            ..DockArea::default()
        };
        let expected: Xyhw = XyhwBuilder {
            h: 2,
            w: 190,
            x: 10,
            y: 998,
            ..XyhwBuilder::default()
        }
        .into();
        assert_eq!(area.xyhw_from_bottom(1000, 1000), expected);
    }

    #[test]
    fn should_be_able_to_build_from_left() {
        let area = DockArea {
            left: 2,
            left_start_y: 10,
            left_end_y: 200,
            ..DockArea::default()
        };
        let expected: Xyhw = XyhwBuilder {
            h: 190,
            w: 2,
            x: 0,
            y: 10,
            ..XyhwBuilder::default()
        }
        .into();
        assert_eq!(area.xyhw_from_left(0), expected);
    }

    #[test]
    fn should_be_able_to_build_from_right() {
        let area = DockArea {
            right: 2,
            right_start_y: 10,
            right_end_y: 200,
            ..DockArea::default()
        };
        let expected: Xyhw = XyhwBuilder {
            h: 190,
            w: 2,
            x: 1998,
            y: 10,
            ..XyhwBuilder::default()
        }
        .into();
        assert_eq!(area.xyhw_from_right(2000, 2000), expected);
    }
}