112 lines
2.8 KiB
Rust
112 lines
2.8 KiB
Rust
use crate::primitive::{Vec2, vec2::point};
|
|
|
|
#[repr(C)]
|
|
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable, Default)]
|
|
pub struct UIPos {
|
|
pub anchor: Vec2,
|
|
pub offset: Vec2,
|
|
}
|
|
|
|
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 center() -> Self {
|
|
Self::anchor_offset(0.0, 0.0, 0.0, 0.0)
|
|
}
|
|
|
|
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 offset(mut self, offset: Vec2) -> Self {
|
|
self.offset = offset;
|
|
self
|
|
}
|
|
|
|
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) -> Vec2 {
|
|
(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 center(size: Vec2) -> Self {
|
|
Self {
|
|
top_left: UIPos::center().offset(-size / 2.0),
|
|
bot_right: UIPos::center().offset(size / 2.0),
|
|
}
|
|
}
|
|
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,
|
|
}
|