mistakes were fixed and sins were committed

This commit is contained in:
2025-11-20 00:18:30 -05:00
parent db248de8f4
commit a952b34a72
18 changed files with 418 additions and 142 deletions

View File

@@ -16,7 +16,7 @@ impl Widget for Span {
let mut child_region = UiRegion::full();
let mut axis = child_region.axis_mut(self.dir.axis);
axis.top_left.set(start);
let len = painter.size(child).axis(self.dir.axis);
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);
@@ -33,25 +33,18 @@ impl Widget for Span {
}
}
fn desired_size(&mut self, ctx: &mut SizeCtx) -> Size {
let sums = self.len_sum(ctx);
let dir_len = if sums.rest == 0.0 && sums.rel == 0.0 {
sums
} else {
Len::default()
};
let mut max_ortho = Len::ZERO;
for child in &self.children {
let len = ctx.size(child).axis(!self.dir.axis);
// TODO: rel shouldn't do this, but no easy way before actually calculating pixels
if len.rel > 0.0 || len.rest > 0.0 {
max_ortho.rest = 1.0;
max_ortho.abs = 0.0;
break;
}
max_ortho.abs = max_ortho.abs.max(len.abs);
fn desired_width(&mut self, ctx: &mut SizeCtx) -> Len {
match self.dir.axis {
Axis::X => self.desired_len(ctx),
Axis::Y => self.desired_ortho(ctx),
}
}
fn desired_height(&mut self, ctx: &mut SizeCtx) -> Len {
match self.dir.axis {
Axis::X => self.desired_ortho(ctx),
Axis::Y => self.desired_len(ctx),
}
Size::from_axis(self.dir.axis, dir_len, max_ortho)
}
}
@@ -71,11 +64,85 @@ impl Span {
fn len_sum(&mut self, ctx: &mut SizeCtx) -> Len {
let gap = self.gap * self.children.len().saturating_sub(1) as f32;
self.children.iter_mut().fold(Len::abs(gap), |mut s, id| {
s += ctx.size(id).axis(self.dir.axis);
self.children.iter().fold(Len::abs(gap), |mut s, id| {
// it's tempting to subtract the abs & rel from the ctx outer,
// but that would create inconsistent sizing if you put
// a rest first vs last & only speed up in one direction.
// I think this is only solvable by restricting how you can
// compute size, bc currently you need child to define parent's
// sectioning and you need parent's sectioning to define child.
// Fortunately, that doesn't matter in most cases
let len = ctx.len_axis(id, self.dir.axis);
s += len;
s
})
}
fn desired_len(&mut self, ctx: &mut SizeCtx) -> Len {
let len = self.len_sum(ctx);
if len.rest == 0.0 && len.rel == 0.0 {
len
} else {
Len::default()
}
}
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
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 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);
}
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));
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 {
ortho_len.rest = 1.0;
ortho_len.abs = 0.0;
break;
}
ortho_len.abs = ortho_len.abs.max(ortho.abs);
start.abs += self.gap;
}
ortho_len
} else {
let mut ortho_len = Len::ZERO;
let ortho = !self.dir.axis;
for child in &self.children {
let len = ctx.len_axis(child, ortho);
// TODO: rel shouldn't do this, but no easy way before actually calculating pixels
if len.rel > 0.0 || len.rest > 0.0 {
ortho_len.rest = 1.0;
ortho_len.abs = 0.0;
break;
}
ortho_len.abs = ortho_len.abs.max(len.abs);
}
ortho_len
}
}
}
pub struct SpanBuilder<const LEN: usize, Wa: WidgetArrLike<LEN, Tag>, Tag> {