use crate::primitive::{Point, point::point}; #[repr(C)] #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable, Default)] pub struct UIPos { pub anchor: Point, pub offset: Point, } impl UIPos { pub const fn anchor_offset(anchor_x: f32, anchor_y: f32, offset_x: f32, offset_y: f32) -> Self { Self { anchor: point(anchor_x, anchor_y), offset: point(offset_x, offset_y), } } pub const fn top_left() -> Self { Self::anchor_offset(-1.0, -1.0, 0.0, 0.0) } pub const fn bottom_right() -> Self { Self::anchor_offset(1.0, 1.0, 0.0, 0.0) } pub const fn within(&self, region: &UIRegion) -> UIPos { let lerp = self.anchor_01(); let anchor = region.top_left.anchor.lerp(region.bot_right.anchor, lerp); let offset = self.offset + region.top_left.offset.lerp(region.bot_right.offset, lerp); UIPos { anchor, offset } } pub const fn anchor_01(&self) -> Point { (self.anchor + 1.0) / 2.0 } pub fn axis_mut(&mut self, axis: Axis) -> UIPosAxisView<'_> { match axis { Axis::X => UIPosAxisView { anchor: &mut self.anchor.x, offset: &mut self.offset.x, }, Axis::Y => UIPosAxisView { anchor: &mut self.anchor.y, offset: &mut self.offset.y, }, } } } pub struct UIPosAxisView<'a> { pub anchor: &'a mut f32, pub offset: &'a mut f32, } #[repr(C)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] pub struct UIRegion { pub top_left: UIPos, pub bot_right: UIPos, } impl UIRegion { pub const fn full() -> Self { Self { top_left: UIPos::top_left(), bot_right: UIPos::bottom_right(), } } pub fn within(&self, parent: &Self) -> Self { Self { top_left: self.top_left.within(parent), bot_right: self.bot_right.within(parent), } } pub fn select(&mut self, inner: &Self) { *self = inner.within(self); } pub fn axis_mut(&mut self, axis: Axis) -> UIRegionAxisView<'_> { UIRegionAxisView { top_left: self.top_left.axis_mut(axis), bot_right: self.bot_right.axis_mut(axis), } } } pub struct UIRegionAxisView<'a> { pub top_left: UIPosAxisView<'a>, pub bot_right: UIPosAxisView<'a>, } #[derive(Copy, Clone)] pub enum Axis { X, Y, }