use crate::Point;
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct Rect {
pub left: i32,
pub top: i32,
pub right: i32,
pub bottom: i32,
}
impl Rect {
#[inline]
pub const fn new(left: i32, top: i32, right: i32, bottom: i32) -> Self {
Self {
left,
top,
right,
bottom,
}
}
#[inline]
pub const fn from_origin_size(left: i32, top: i32, width: i32, height: i32) -> Self {
Self {
left,
top,
right: left + width,
bottom: top + height,
}
}
#[inline]
pub const fn width(&self) -> i32 {
self.right - self.left
}
#[inline]
pub const fn height(&self) -> i32 {
self.bottom - self.top
}
#[inline]
pub const fn contains(&self, point: Point) -> bool {
point.x >= self.left
&& point.x < self.right
&& point.y >= self.top
&& point.y < self.bottom
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct MonitorInfo {
pub id: String,
pub name: String,
pub bounds: Rect,
pub work_area: Rect,
pub is_primary: bool,
pub scale_factor: f32,
}
impl MonitorInfo {
pub fn resolution(&self) -> Point {
Point::new(self.bounds.width(), self.bounds.height())
}
pub fn dpi(&self) -> f32 {
self.scale_factor * 96.0
}
#[inline]
pub fn contains(&self, point: Point) -> bool {
self.bounds.contains(point)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rect_from_origin_size_matches_edges() {
let r = Rect::from_origin_size(-100, -50, 1920, 1080);
assert_eq!(r.left, -100);
assert_eq!(r.top, -50);
assert_eq!(r.right, 1820);
assert_eq!(r.bottom, 1030);
assert_eq!(r.width(), 1920);
assert_eq!(r.height(), 1080);
}
#[test]
fn rect_contains_half_open() {
let r = Rect::new(0, 0, 100, 100);
assert!(r.contains(Point::new(0, 0))); assert!(r.contains(Point::new(99, 99)));
assert!(!r.contains(Point::new(100, 50))); assert!(!r.contains(Point::new(50, 100))); assert!(!r.contains(Point::new(-1, 50)));
}
#[test]
fn monitor_contains_delegates_to_bounds() {
let m = MonitorInfo {
id: "\\.\\DISPLAY2".into(),
name: "\\.\\DISPLAY2".into(),
bounds: Rect::from_origin_size(-1920, 0, 1920, 1080),
work_area: Rect::from_origin_size(-1920, 0, 1920, 1040),
is_primary: false,
scale_factor: 1.0,
};
assert!(m.contains(Point::new(-100, 100)));
assert!(!m.contains(Point::new(100, 100)));
}
}