the great orientation refactor (move to x & y UiScalars/Spans) + don't call full size in align

This commit is contained in:
2025-11-20 15:44:39 -05:00
parent 96ef0c529b
commit 6251c23d37
20 changed files with 832 additions and 578 deletions

View File

@@ -7,8 +7,32 @@ pub struct Aligned {
impl Widget for Aligned {
fn draw(&mut self, painter: &mut Painter) {
let region =
UiRegion::from_ui_size_align(painter.size(&self.inner).to_uivec2(), self.align);
let region = match self.align {
Align {
x: Some(x),
y: Some(y),
} => {
painter
.size(&self.inner)
.to_uivec2()
.align(RegionAlign { x, y })
}
Align {
x: Some(x),
y: None,
} => {
let x = painter.size_ctx().width(&self.inner).apply_rest().align(x);
UiRegion::new(x, UiSpan::FULL)
}
Align {
x: None,
y: Some(y),
} => {
let y = painter.size_ctx().height(&self.inner).apply_rest().align(y);
UiRegion::new(UiSpan::FULL, y)
}
Align { x: None, y: None } => UiRegion::FULL,
};
painter.widget_within(&self.inner, region);
}

View File

@@ -7,7 +7,7 @@ pub struct Offset {
impl Widget for Offset {
fn draw(&mut self, painter: &mut Painter) {
let region = UiRegion::full().offset(self.amt);
let region = UiRegion::FULL.offset(self.amt);
painter.widget_within(&self.inner, region);
}

View File

@@ -13,8 +13,8 @@ impl Widget for Pad {
fn desired_width(&mut self, ctx: &mut SizeCtx) -> Len {
let width = self.padding.left + self.padding.right;
let height = self.padding.top + self.padding.bottom;
ctx.outer.abs.x -= width;
ctx.outer.abs.y -= height;
ctx.outer.x.abs -= width;
ctx.outer.y.abs -= height;
let mut size = ctx.width(&self.inner);
size.abs += width;
size
@@ -23,8 +23,8 @@ impl Widget for Pad {
fn desired_height(&mut self, ctx: &mut SizeCtx) -> Len {
let width = self.padding.left + self.padding.right;
let height = self.padding.top + self.padding.bottom;
ctx.outer.abs.x -= width;
ctx.outer.abs.y -= height;
ctx.outer.x.abs -= width;
ctx.outer.y.abs -= height;
let mut size = ctx.height(&self.inner);
size.abs += height;
size
@@ -49,11 +49,11 @@ impl Padding {
}
}
pub fn region(&self) -> UiRegion {
let mut region = UiRegion::full();
region.top_left.abs.x += self.left;
region.top_left.abs.y += self.top;
region.bot_right.abs.x -= self.right;
region.bot_right.abs.y -= self.bottom;
let mut region = UiRegion::FULL;
region.x.start.abs += self.left;
region.y.start.abs += self.top;
region.x.end.abs -= self.right;
region.y.end.abs -= self.bottom;
region
}
pub fn x(amt: impl UiNum) -> Self {

View File

@@ -9,16 +9,10 @@ pub struct Sized {
impl Sized {
fn apply_to_outer(&self, ctx: &mut SizeCtx) {
if let Some(x) = self.x {
let outer = ctx.outer.axis(Axis::X);
ctx.outer
.axis_mut(Axis::X)
.set(x.apply_rest().within_len(outer));
ctx.outer.x.select_len(x.apply_rest());
}
if let Some(y) = self.y {
let outer = ctx.outer.axis(Axis::Y);
ctx.outer
.axis_mut(Axis::Y)
.set(y.apply_rest().within_len(outer));
ctx.outer.y.select_len(y.apply_rest());
}
}
}

View File

@@ -1,6 +1,5 @@
use std::marker::PhantomData;
use crate::prelude::*;
use std::marker::PhantomData;
pub struct Span {
pub children: Vec<WidgetId>,
@@ -13,18 +12,19 @@ impl Widget for Span {
let total = self.len_sum(&mut painter.size_ctx());
let mut start = UiScalar::rel_min();
for child in &self.children {
let mut child_region = UiRegion::full();
let mut axis = child_region.axis_mut(self.dir.axis);
axis.top_left.set(start);
let mut span = UiSpan::FULL;
span.start = start;
let len = painter.len_axis(child, self.dir.axis);
if len.rest > 0.0 {
let offset = UiScalar::new(total.rel, total.abs);
let rel_end = UiScalar::from_anchor(len.rest / total.rest);
start = rel_end.within(start, (UiScalar::rel_max() + start) - offset);
let rel_end = UiScalar::rel(len.rest / total.rest);
let end = (UiScalar::rel_max() + start) - offset;
start = rel_end.within(&start.to(end));
}
start.abs += len.abs;
start.rel += len.rel;
axis.bot_right.set(start);
span.end = start;
let mut child_region = UiRegion::from_axis(self.dir.axis, span, UiSpan::FULL);
if self.dir.sign == Sign::Neg {
child_region.flip(self.dir.axis);
}
@@ -89,33 +89,29 @@ impl Span {
fn desired_ortho(&mut self, ctx: &mut SizeCtx) -> Len {
// this is an awful hack to get text wrapping to work properly when in a downward span
let outer = ctx.outer.axis(self.dir.axis);
if self.dir.axis == Axis::X {
// so....... this literally copies draw so that the lengths are correctly set in the
// context, which makes this slow and not cool
let total = self.len_sum(ctx);
let mut start = UiScalar::rel_min();
let outer = ctx.outer.axis(self.dir.axis);
let mut ortho_len = Len::ZERO;
for child in &self.children {
let mut child_region = UiRegion::full();
let mut axis = child_region.axis_mut(self.dir.axis);
axis.top_left.set(start);
let mut span = UiSpan::FULL;
span.start = start;
let len = ctx.len_axis(child, self.dir.axis);
if len.rest > 0.0 {
let offset = UiScalar::new(total.rel, total.abs);
let rel_end = UiScalar::from_anchor(len.rest / total.rest);
start = rel_end.within(start, (UiScalar::rel_max() + start) - offset);
let rel_end = UiScalar::rel(len.rest / total.rest);
let end = (UiScalar::rel_max() + start) - offset;
start = rel_end.within(&start.to(end));
}
start.abs += len.abs;
start.rel += len.rel;
axis.bot_right.set(start);
// if self.dir.sign == Sign::Neg {
// child_region.flip(self.dir.axis);
// }
let scalar = child_region.size().axis(self.dir.axis);
ctx.outer
.axis_mut(self.dir.axis)
.set(scalar.within_len(outer));
span.end = start;
let scalar = span.len();
*ctx.outer.axis_mut(self.dir.axis) = outer.select_len(scalar);
let ortho = ctx.len_axis(child, !self.dir.axis);
// TODO: rel shouldn't do this, but no easy way before actually calculating pixels
if ortho.rel > 0.0 || ortho.rest > 0.0 {