diff --git a/src/display.rs b/src/display.rs index 503c549..827d45b 100644 --- a/src/display.rs +++ b/src/display.rs @@ -75,3 +75,54 @@ impl From for Display { } } } + +impl Display { + pub fn is_overlap(&self, target: Display) -> bool { + let self_right = self.x + self.width; + let self_bottom = self.y + self.height; + let target_right = target.x + target.width; + let target_bottom = target.y + target.height; + + self.x < target_right + && self_right > target.x + && self.y < target_bottom + && self_bottom > target.y + } + + pub fn is_touch(&self, target: Display) -> Option<(i32, i32, ZoneDirection)> { + let self_right = self.x + self.width; + let self_bottom = self.y + self.height; + let target_right = target.x + target.width; + let target_bottom = target.y + target.height; + + let horizontal_touch = (self_right == target.x || self.x == target_right) + && (self.y < target_bottom && self_bottom > target.y); + + let vertical_touch = (self_bottom == target.y || self.y == target_bottom) + && (self.x < target_right && self_right > target.x); + + if horizontal_touch { + return Some(( + i32::max(self.y, target.y), + i32::min(self_bottom, target_bottom), + if self_right == target.x { + ZoneDirection::HorizontalRight + } else { + ZoneDirection::HorizontalLeft + }, + )); + } else if vertical_touch { + return Some(( + i32::max(self.x, target.x), + i32::min(self_right, target_right), + if self_bottom == target.y { + ZoneDirection::VerticalDown + } else { + ZoneDirection::VerticalUp + }, + )); + } else { + None + } + } +} diff --git a/src/server.rs b/src/server.rs index be2127a..6bd62bc 100644 --- a/src/server.rs +++ b/src/server.rs @@ -35,12 +35,13 @@ impl Server { return Err(Error::new(NotFound, "[ERR] system display not found")); } + // TODO: set warpzones: WIP + create_warpzones(disp.clone(), disp.clone(), true); + let system = disp.iter().map(|x| x.id).collect(); let current = disp.iter().find(|x| x.is_primary).unwrap_or(&disp[0]).id; let displays = Arc::new(RwLock::new(disp.into_iter().map(|x| (x.id, x)).collect())); - // TODO: set warpzones - Ok(Server { clients: Arc::new(RwLock::new(HashMap::new())), displays, diff --git a/src/utils.rs b/src/utils.rs index c3c8fce..f678c9a 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,10 @@ +use std::io::{Error, ErrorKind::*}; + use display_info::DisplayInfo; use serde::{Deserialize, Serialize}; +use crate::display::*; + #[derive(Serialize, Deserialize, Debug)] pub enum HandshakeStatus { HandshakeOk, @@ -16,6 +20,31 @@ pub fn print_displays() { } } +pub fn create_warpzones(a: Vec, b: Vec, is_list_same: bool) -> Result, Error> { + for (i, disp) in a.iter().enumerate() { + for (j, target) in b.iter().enumerate() { + if is_list_same && i >= j { + continue; + } + + if disp.is_overlap(target.clone()) { + return Err(Error::new(InvalidInput, "[ERR] two displays are overlapping")); + } + + if let Some((start, end, direction)) = disp.is_touch(target.clone()) { + disp.warpzones.push(WarpZone { + start, + end, + direction, + to: 0 + }) + } + } + } + + Ok(Vec::new()) +} + #[macro_export] macro_rules! config_dir { () => {{