sizing actually working correctly now

This commit is contained in:
2025-09-16 17:31:54 -04:00
parent b48acccb8d
commit f9097807a2
17 changed files with 333 additions and 194 deletions

View File

@@ -5,12 +5,12 @@ use crate::{
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, bytemuck::Pod, bytemuck::Zeroable, Default)]
pub struct UiPos {
pub anchor: Vec2,
pub offset: Vec2,
pub struct UiVec2 {
pub rel: Vec2,
pub abs: Vec2,
}
impl UiPos {
impl UiVec2 {
/// expands this position into a sized region centered at self
pub fn expand(&self, size: impl Into<Vec2>) -> UiRegion {
let size = size.into();
@@ -21,21 +21,29 @@ impl UiPos {
}
pub const fn anchor(anchor: Vec2) -> Self {
Self {
anchor,
offset: Vec2::ZERO,
}
Self::rel(anchor)
}
pub const fn offset(offset: Vec2) -> Self {
Self::abs(offset)
}
pub const fn abs(abs: Vec2) -> Self {
Self {
anchor: Vec2::ZERO,
offset,
rel: Vec2::ZERO,
abs,
}
}
pub const fn rel(rel: Vec2) -> Self {
Self {
rel,
abs: Vec2::ZERO,
}
}
pub const fn shift(&mut self, offset: impl const Into<Vec2>) {
self.offset += offset.into();
self.abs += offset.into();
}
pub const fn shifted(mut self, offset: Vec2) -> Self {
@@ -43,33 +51,44 @@ impl UiPos {
self
}
pub const fn within(&self, region: &UiRegion) -> UiPos {
let anchor = self
.anchor
.lerp(region.top_left.anchor, region.bot_right.anchor);
let offset = self.offset
+ self
.anchor
.lerp(region.top_left.offset, region.bot_right.offset);
UiPos { anchor, offset }
pub const fn within(&self, region: &UiRegion) -> UiVec2 {
let anchor = self.rel.lerp(region.top_left.rel, region.bot_right.rel);
let offset = self.abs + self.rel.lerp(region.top_left.abs, region.bot_right.abs);
UiVec2 {
rel: anchor,
abs: offset,
}
}
pub fn axis_mut(&mut self, axis: Axis) -> UIScalarView<'_> {
pub fn axis_mut(&mut self, axis: Axis) -> UiScalarView<'_> {
match axis {
Axis::X => UIScalarView {
anchor: &mut self.anchor.x,
offset: &mut self.offset.x,
Axis::X => UiScalarView {
anchor: &mut self.rel.x,
offset: &mut self.abs.x,
},
Axis::Y => UIScalarView {
anchor: &mut self.anchor.y,
offset: &mut self.offset.y,
Axis::Y => UiScalarView {
anchor: &mut self.rel.y,
offset: &mut self.abs.y,
},
}
}
pub fn axis(&self, axis: Axis) -> UiScalar {
match axis {
Axis::X => UiScalar {
rel: self.rel.x,
abs: self.abs.x,
},
Axis::Y => UiScalar {
rel: self.rel.y,
abs: self.abs.y,
},
}
}
pub fn flip(&mut self) {
self.anchor = 1.0 - self.anchor;
self.offset = -self.offset;
self.rel = 1.0 - self.rel;
self.abs = -self.abs;
}
pub fn flipped(mut self) -> Self {
@@ -78,64 +97,92 @@ impl UiPos {
}
pub fn to_size(&self, size: Vec2) -> Vec2 {
self.anchor * size + self.offset
self.rel * size + self.abs
}
pub const fn max_size() -> Self {
Self::rel(Vec2::ONE)
}
pub const fn from_axis(axis: Axis, aligned: UiScalar, ortho: UiScalar) -> Self {
Self {
rel: Vec2::from_axis(axis, aligned.rel, ortho.rel),
abs: Vec2::from_axis(axis, aligned.abs, ortho.abs),
}
}
}
impl const From<Align> for UiPos {
impl const From<Align> for UiVec2 {
fn from(align: Align) -> Self {
Self::anchor(align.anchor())
}
}
impl Align {
pub fn pos(self) -> UiPos {
UiPos::from(self)
pub fn pos(self) -> UiVec2 {
UiVec2::from(self)
}
}
#[derive(Clone, Copy, Debug)]
pub struct UIScalar {
pub anchor: f32,
pub offset: f32,
#[derive(Clone, Copy, Debug, Default)]
pub struct UiScalar {
pub rel: f32,
pub abs: f32,
}
impl_op!(UIScalar Add add; anchor offset);
impl_op!(UIScalar Sub sub; anchor offset);
impl_op!(UiScalar Add add; rel abs);
impl_op!(UiScalar Sub sub; rel abs);
impl UIScalar {
pub fn new(anchor: f32, offset: f32) -> Self {
Self { anchor, offset }
impl UiScalar {
pub fn new(rel: f32, abs: f32) -> Self {
Self { rel, abs }
}
pub fn min() -> Self {
pub fn rel_min() -> Self {
Self::new(0.0, 0.0)
}
pub fn max() -> Self {
pub fn rel_max() -> Self {
Self::new(1.0, 0.0)
}
pub fn max(&self, other: Self) -> Self {
Self {
rel: self.rel.max(other.rel),
abs: self.abs.max(other.abs),
}
}
pub fn min(&self, other: Self) -> Self {
Self {
rel: self.rel.min(other.rel),
abs: self.abs.min(other.abs),
}
}
pub fn from_anchor(anchor: f32) -> Self {
Self::new(anchor, 0.0)
}
pub fn offset(mut self, amt: f32) -> Self {
self.offset += amt;
self.abs += amt;
self
}
pub fn within(&self, start: UIScalar, end: UIScalar) -> Self {
let anchor = self.anchor.lerp(start.anchor, end.anchor);
let offset = self.offset + self.anchor.lerp(start.offset, end.offset);
Self { anchor, offset }
pub fn within(&self, start: UiScalar, end: UiScalar) -> Self {
let anchor = self.rel.lerp(start.rel, end.rel);
let offset = self.abs + self.rel.lerp(start.abs, end.abs);
Self {
rel: anchor,
abs: offset,
}
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
pub struct UiRegion {
pub top_left: UiPos,
pub bot_right: UiPos,
pub top_left: UiVec2,
pub bot_right: UiVec2,
}
impl UiRegion {
@@ -147,8 +194,8 @@ impl UiRegion {
}
pub fn anchor(anchor: Vec2) -> Self {
Self {
top_left: UiPos::anchor(anchor),
bot_right: UiPos::anchor(anchor),
top_left: UiVec2::anchor(anchor),
bot_right: UiVec2::anchor(anchor),
}
}
pub fn within(&self, parent: &Self) -> Self {
@@ -183,12 +230,12 @@ impl UiRegion {
pub fn to_screen(&self, size: Vec2) -> ScreenRegion {
ScreenRegion {
top_left: self.top_left.anchor * size + self.top_left.offset,
bot_right: self.bot_right.anchor * size + self.bot_right.offset,
top_left: self.top_left.rel * size + self.top_left.abs,
bot_right: self.bot_right.rel * size + self.bot_right.abs,
}
}
pub fn center(&self) -> UiPos {
pub fn center(&self) -> UiVec2 {
Align::Center.pos().within(self)
}
@@ -201,10 +248,23 @@ impl UiRegion {
}
pub fn from_size_align(size: Vec2, align: Align) -> Self {
let mut top_left = UiPos::from(align);
top_left.offset -= size * align.anchor();
let mut bot_right = UiPos::from(align);
bot_right.offset += size * (Vec2::ONE - align.anchor());
let mut top_left = UiVec2::from(align);
top_left.abs -= size * align.anchor();
let mut bot_right = UiVec2::from(align);
bot_right.abs += size * (Vec2::ONE - align.anchor());
Self {
top_left,
bot_right,
}
}
pub fn from_ui_size_align(size: UiVec2, align: Align) -> Self {
let mut top_left = UiVec2::from(align);
top_left.abs -= size.abs * align.anchor();
top_left.rel -= size.rel * align.anchor();
let mut bot_right = UiVec2::from(align);
bot_right.abs += size.abs * (Vec2::ONE - align.anchor());
bot_right.rel += size.rel * (Vec2::ONE - align.anchor());
Self {
top_left,
bot_right,
@@ -227,24 +287,24 @@ impl ScreenRegion {
}
pub struct UIRegionAxisView<'a> {
pub top_left: UIScalarView<'a>,
pub bot_right: UIScalarView<'a>,
pub top_left: UiScalarView<'a>,
pub bot_right: UiScalarView<'a>,
}
pub struct UIScalarView<'a> {
pub struct UiScalarView<'a> {
pub anchor: &'a mut f32,
pub offset: &'a mut f32,
}
impl UIScalarView<'_> {
pub fn set(&mut self, scalar: UIScalar) {
*self.anchor = scalar.anchor;
*self.offset = scalar.offset;
impl UiScalarView<'_> {
pub fn set(&mut self, scalar: UiScalar) {
*self.anchor = scalar.rel;
*self.offset = scalar.abs;
}
pub fn get(self) -> UIScalar {
UIScalar {
anchor: *self.anchor,
offset: *self.offset,
pub fn get(self) -> UiScalar {
UiScalar {
rel: *self.anchor,
abs: *self.offset,
}
}
}