Give a length with no share in it its own type again
`UiScalar` was `Len` without the `leftover` weight, which is the separation canonical `main` already had as `Len` beside `LayoutLen` and this branch collapsed. It is needed back for the queued clamp: a cap may not contain a share, because a cap has to read the report a rule otherwise makes moot, and a share puts the container's division into the same equation -- two self-consistent assignments, which is the multiple-fixed-point failure generated seed 13 punished for orthogonal sizing. `min(report, cap)` is not a `LayoutLen` either: it is a sum of parts, and the smaller of two of them is not one. So `UiScalar` is `Len`, what was `Len` is `LayoutLen`, and the two say in their docs which is which: a `Len` is pixels plus a fraction of a box -- a position being the length from the box's start, which is why a span is two of them -- and a `LayoutLen` is a `Len` plus a claim only a container dividing its room can answer. `From<Len> for LayoutLen` is the one-way step between them. Names only; the shader's `UiScalar` is renamed with them. Checked: fmt, clippy, 105 tests, and `tabs`, `minimal`, `view`, `text` and `random` byte-identical at 1920x1200. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4f5e27cba9
commit
a8898aaa54
27 files changed
+218
-202
No files matched your search
+42
-38
@@ -6,41 +6,41 @@ use crate::{Px, PxVec2, Rel, UiNum, util::impl_op};
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, bytemuck::Pod, bytemuck::Zeroable, Default)]
|
||||
pub struct UiVec2 {
|
||||
pub x: UiScalar,
|
||||
pub y: UiScalar,
|
||||
pub x: Len,
|
||||
pub y: Len,
|
||||
}
|
||||
|
||||
impl UiVec2 {
|
||||
pub const ZERO: Self = Self {
|
||||
x: UiScalar::ZERO,
|
||||
y: UiScalar::ZERO,
|
||||
x: Len::ZERO,
|
||||
y: Len::ZERO,
|
||||
};
|
||||
|
||||
pub const fn new(x: UiScalar, y: UiScalar) -> Self {
|
||||
pub const fn new(x: Len, y: Len) -> Self {
|
||||
Self { x, y }
|
||||
}
|
||||
|
||||
pub const fn px(px: impl const Into<Vec2>) -> Self {
|
||||
let px = px.into();
|
||||
Self {
|
||||
x: UiScalar::px(px.x),
|
||||
y: UiScalar::px(px.y),
|
||||
x: Len::px(px.x),
|
||||
y: Len::px(px.y),
|
||||
}
|
||||
}
|
||||
|
||||
/// From lengths already on the grid, with no fraction of a box.
|
||||
pub const fn from_px(px: PxVec2) -> Self {
|
||||
Self {
|
||||
x: UiScalar::from_parts(Rel::ZERO, px.x),
|
||||
y: UiScalar::from_parts(Rel::ZERO, px.y),
|
||||
x: Len::from_parts(Rel::ZERO, px.x),
|
||||
y: Len::from_parts(Rel::ZERO, px.y),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn rel(rel: impl const Into<Vec2>) -> Self {
|
||||
let rel = rel.into();
|
||||
Self {
|
||||
x: UiScalar::rel(rel.x),
|
||||
y: UiScalar::rel(rel.y),
|
||||
x: Len::rel(rel.x),
|
||||
y: Len::rel(rel.y),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,14 +61,14 @@ impl UiVec2 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn axis_mut(&mut self, axis: Axis) -> &mut UiScalar {
|
||||
pub fn axis_mut(&mut self, axis: Axis) -> &mut Len {
|
||||
match axis {
|
||||
Axis::X => &mut self.x,
|
||||
Axis::Y => &mut self.y,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn axis(&self, axis: Axis) -> UiScalar {
|
||||
pub fn axis(&self, axis: Axis) -> Len {
|
||||
match axis {
|
||||
Axis::X => self.x,
|
||||
Axis::Y => self.y,
|
||||
@@ -83,7 +83,7 @@ impl UiVec2 {
|
||||
|
||||
pub const FULL_SIZE: Self = Self::rel(Vec2::ONE);
|
||||
|
||||
pub const fn from_axis(axis: Axis, aligned: UiScalar, ortho: UiScalar) -> Self {
|
||||
pub const fn from_axis(axis: Axis, aligned: Len, ortho: Len) -> Self {
|
||||
match axis {
|
||||
Axis::X => Self {
|
||||
x: aligned,
|
||||
@@ -129,21 +129,27 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// A position along one axis, as a fraction of the box it sits in plus an
|
||||
/// offset: `rel * len + px`. Both parts are fixed point, so composing one
|
||||
/// through a chain of boxes rounds only where it multiplies and lands on the
|
||||
/// same number as any other route to the same place.
|
||||
/// A length along one axis: a fraction of the box it is measured in plus an
|
||||
/// offset, `rel * box + px`. A position is the same number -- the length from
|
||||
/// the start of the box to the point -- which is why a [`UiSpan`] is two of
|
||||
/// these. Both parts are fixed point, so composing one through a chain of
|
||||
/// boxes rounds only where it multiplies, and lands on the same number as any
|
||||
/// other route to the same place.
|
||||
///
|
||||
/// It carries no claim on what a container has left over. That is
|
||||
/// [`crate::LayoutLen`], which is this plus a weight, and which means nothing
|
||||
/// to anyone but whoever divides the room.
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, bytemuck::Pod, Default, bytemuck::Zeroable)]
|
||||
pub struct UiScalar {
|
||||
pub struct Len {
|
||||
pub rel: Rel,
|
||||
pub px: Px,
|
||||
}
|
||||
|
||||
impl_op!(same UiScalar Add add; rel px);
|
||||
impl_op!(same UiScalar Sub sub; rel px);
|
||||
impl_op!(same Len Add add; rel px);
|
||||
impl_op!(same Len Sub sub; rel px);
|
||||
|
||||
impl UiScalar {
|
||||
impl Len {
|
||||
pub const ZERO: Self = Self {
|
||||
rel: Rel::ZERO,
|
||||
px: Px::ZERO,
|
||||
@@ -192,10 +198,8 @@ impl UiScalar {
|
||||
}
|
||||
}
|
||||
|
||||
/// Both channels by the same factor, which is what a fraction of a
|
||||
/// length means when the length is part pixels and part a share.
|
||||
/// Both channels by the same fraction, which is what a part of a length
|
||||
/// means when the length is part pixels and part a share.
|
||||
/// Both parts by the same fraction, which is what a part of a length
|
||||
/// means when the length is part pixels and part a fraction of a box.
|
||||
pub const fn scale(&self, by: Rel) -> Self {
|
||||
Self {
|
||||
rel: self.rel.mul(by),
|
||||
@@ -215,14 +219,14 @@ impl UiScalar {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn within_len(&self, len: UiScalar) -> Self {
|
||||
pub fn within_len(&self, len: Len) -> Self {
|
||||
self.within(&UiSpan {
|
||||
start: UiScalar::ZERO,
|
||||
start: Len::ZERO,
|
||||
end: len,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn select_len(&self, len: UiScalar) -> Self {
|
||||
pub fn select_len(&self, len: Len) -> Self {
|
||||
len.within_len(*self)
|
||||
}
|
||||
|
||||
@@ -245,24 +249,24 @@ impl UiScalar {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
pub struct UiSpan {
|
||||
pub start: UiScalar,
|
||||
pub end: UiScalar,
|
||||
pub start: Len,
|
||||
pub end: Len,
|
||||
}
|
||||
|
||||
impl UiSpan {
|
||||
pub const FULL: Self = Self {
|
||||
start: UiScalar::ZERO,
|
||||
end: UiScalar::FULL,
|
||||
start: Len::ZERO,
|
||||
end: Len::FULL,
|
||||
};
|
||||
|
||||
pub const fn rel(rel: f32) -> Self {
|
||||
Self {
|
||||
start: UiScalar::rel(rel),
|
||||
end: UiScalar::rel(rel),
|
||||
start: Len::rel(rel),
|
||||
end: Len::rel(rel),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn new(start: UiScalar, end: UiScalar) -> Self {
|
||||
pub const fn new(start: Len, end: Len) -> Self {
|
||||
Self { start, end }
|
||||
}
|
||||
|
||||
@@ -273,7 +277,7 @@ impl UiSpan {
|
||||
std::mem::swap(&mut self.start.px, &mut self.end.px);
|
||||
}
|
||||
|
||||
pub const fn shift(&mut self, offset: UiScalar) {
|
||||
pub const fn shift(&mut self, offset: Len) {
|
||||
self.start += offset;
|
||||
self.end += offset;
|
||||
}
|
||||
@@ -285,7 +289,7 @@ impl UiSpan {
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn len(&self) -> UiScalar {
|
||||
pub const fn len(&self) -> Len {
|
||||
self.end - self.start
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user