Add explicit orthogonal span sizing
This commit is contained in:
1 parent
29c7881c8a
commit
f437495309
7 files changed
+108
-8
No files matched your search
@@ -1,10 +1,21 @@
|
||||
use crate::prelude::*;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum OrthoSize {
|
||||
/// Reports one full relative length across the span's orthogonal axis,
|
||||
/// whether or not its siblings also take space.
|
||||
Full,
|
||||
/// Reports its longest fixed child, or leftover space if any child scales.
|
||||
#[default]
|
||||
Children,
|
||||
}
|
||||
|
||||
pub struct Span {
|
||||
pub children: Vec<StrongWidget>,
|
||||
pub dir: Dir,
|
||||
pub gap: f32,
|
||||
pub ortho: OrthoSize,
|
||||
}
|
||||
|
||||
impl Widget for Span {
|
||||
@@ -82,12 +93,18 @@ impl Widget for Span {
|
||||
if self.dir.sign == Sign::Neg {
|
||||
region.flip(axis);
|
||||
}
|
||||
let used = painter.place(child, region).size().axis(!axis);
|
||||
// TODO: rel shouldn't do this, but no easy way before actually calculating pixels
|
||||
if used.rel > 0.0 || used.leftover > 0.0 {
|
||||
ortho = Len::LEFTOVER;
|
||||
} else if ortho.leftover == 0.0 {
|
||||
ortho.px = ortho.px.max(used.px);
|
||||
let placed = painter.place(child, region);
|
||||
if self.ortho == OrthoSize::Children {
|
||||
let used = placed.len(!axis);
|
||||
// Choosing between a fixed and a relative length from the
|
||||
// span's own eventual width admits multiple fixed points.
|
||||
// A scalable child therefore makes Children scalable too;
|
||||
// only fixed children are compared with one another.
|
||||
if used.rel != 0.0 || used.leftover != 0.0 {
|
||||
ortho = Len::LEFTOVER;
|
||||
} else if ortho.leftover == 0.0 {
|
||||
ortho.px = ortho.px.max(used.px);
|
||||
}
|
||||
}
|
||||
start.px += self.gap;
|
||||
}
|
||||
@@ -100,6 +117,10 @@ impl Widget for Span {
|
||||
// not give. Resolution happens at the nearest ancestor with a length,
|
||||
// and the root always has one.
|
||||
let along = total;
|
||||
let ortho = match self.ortho {
|
||||
OrthoSize::Full => Len::rel(1.0),
|
||||
OrthoSize::Children => ortho,
|
||||
};
|
||||
Size::from_axis(axis, along, ortho)
|
||||
}
|
||||
}
|
||||
@@ -110,6 +131,7 @@ impl Span {
|
||||
children: Vec::new(),
|
||||
dir,
|
||||
gap: 0.0,
|
||||
ortho: OrthoSize::Children,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +140,11 @@ impl Span {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn ortho(mut self, ortho: OrthoSize) -> Self {
|
||||
self.ortho = ortho;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn push(&mut self, w: StrongWidget) {
|
||||
self.children.push(w);
|
||||
}
|
||||
@@ -131,6 +158,7 @@ pub struct SpanBuilder<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Ta
|
||||
pub children: Wa,
|
||||
pub dir: Dir,
|
||||
pub gap: f32,
|
||||
pub ortho: OrthoSize,
|
||||
_pd: PhantomData<(State, Tag)>,
|
||||
}
|
||||
|
||||
@@ -145,6 +173,7 @@ impl<Rsc, const LEN: usize, Wa: WidgetArrLike<Rsc, LEN, Tag>, Tag> WidgetFnTrait
|
||||
children: self.children.add(rsc).arr.into_iter().collect(),
|
||||
dir: self.dir,
|
||||
gap: self.gap,
|
||||
ortho: self.ortho,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -157,6 +186,7 @@ impl<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag>
|
||||
children,
|
||||
dir,
|
||||
gap: 0.0,
|
||||
ortho: OrthoSize::Children,
|
||||
_pd: PhantomData,
|
||||
}
|
||||
}
|
||||
@@ -165,6 +195,11 @@ impl<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag>
|
||||
self.gap = gap.to_f32();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn ortho(mut self, ortho: OrthoSize) -> Self {
|
||||
self.ortho = ortho;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Span {
|
||||
|
||||
Reference in new issue
Block a user