use libc::{c_double, c_float, c_int};
use wlroots_sys::{wl_output_transform, wlr_box, wlr_box_closest_point, wlr_box_contains_point,
wlr_box_empty, wlr_box_intersection, wlr_box_rotated_bounds, wlr_box_transform};
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum IntersectionResult {
Intersection(Area),
NoIntersection
}
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
pub struct Origin {
pub x: c_int,
pub y: c_int
}
impl Origin {
pub fn new(x: c_int, y: c_int) -> Self {
Origin { x, y }
}
}
impl Into<Area> for Origin {
fn into(self) -> Area {
Area::new(self, Size::default())
}
}
#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
pub struct Size {
pub width: c_int,
pub height: c_int
}
impl Size {
pub fn new(width: c_int, height: c_int) -> Self {
Size { width, height }
}
}
impl Into<Area> for Size {
fn into(self) -> Area {
Area::new(Origin::default(), self)
}
}
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
pub struct Area {
pub origin: Origin,
pub size: Size
}
impl Into<wlr_box> for Area {
fn into(self) -> wlr_box {
wlr_box { x: self.origin.x,
y: self.origin.y,
width: self.size.width,
height: self.size.height }
}
}
impl Area {
pub fn new(origin: Origin, size: Size) -> Self {
Area { origin, size }
}
pub fn from_box(wlr_box: wlr_box) -> Self {
Area { origin: Origin { x: wlr_box.x,
y: wlr_box.y },
size: Size { width: wlr_box.width,
height: wlr_box.height } }
}
pub fn with_size(self, size: Size) -> Self {
Area { size, ..self }
}
pub fn with_origin(self, origin: Origin) -> Self {
Area { origin, ..self }
}
pub fn closest_point(self, x: c_double, y: c_double) -> (c_double, c_double) {
unsafe {
let (mut dest_x, mut dest_y) = (0.0, 0.0);
wlr_box_closest_point(&mut self.into(), x, y, &mut dest_x, &mut dest_y);
(dest_x, dest_y)
}
}
pub fn intersection(self, other_box: Area) -> IntersectionResult {
unsafe {
let res = Area::default();
let is_empty = wlr_box_intersection(&mut res.into(), &self.into(), &other_box.into());
if is_empty {
IntersectionResult::NoIntersection
} else {
IntersectionResult::Intersection(res)
}
}
}
pub fn contains_point(self, x: c_double, y: c_double) -> bool {
unsafe { wlr_box_contains_point(&mut self.into(), x, y) }
}
pub fn is_empty(self) -> bool {
unsafe { wlr_box_empty(&mut self.into()) }
}
pub fn transform(self, transform: wl_output_transform, width: c_int, height: c_int) -> Area {
unsafe {
let res = Area::default();
wlr_box_transform(&mut res.into(), &mut self.into(), transform, width, height);
res
}
}
pub fn rotated_bounds(self, rotation: c_float) -> Area {
unsafe {
let dest = Area::default();
wlr_box_rotated_bounds(&mut dest.into(), &self.into(), rotation);
dest
}
}
}