iris: separate layout allocation from lengths
This commit is contained in:
1 parent
2b9d8c49a0
commit
1f15125992
17 files changed
+395
-168
No files matched your search
@@ -140,7 +140,7 @@ fn bench_input_grows(n: usize, lines: usize) {
|
|||||||
let input_area = rsc.ui.widgets.add_strong(Sized {
|
let input_area = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: input_rect.any(),
|
inner: input_rect.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(abs(line_height)),
|
y: Some(abs(line_height).into()),
|
||||||
});
|
});
|
||||||
|
|
||||||
let input_area_weak = input_area.weak();
|
let input_area_weak = input_area.weak();
|
||||||
@@ -162,7 +162,7 @@ fn bench_input_grows(n: usize, lines: usize) {
|
|||||||
let mut total_moves = 0u64;
|
let mut total_moves = 0u64;
|
||||||
for line in 1..=lines {
|
for line in 1..=lines {
|
||||||
rsc.ui.widgets.get_mut(&input_area_weak).unwrap().y =
|
rsc.ui.widgets.get_mut(&input_area_weak).unwrap().y =
|
||||||
Some(abs(line_height * (line + 1) as f32));
|
Some(abs(line_height * (line + 1) as f32).into());
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
render.update(&root, &mut rsc);
|
render.update(&root, &mut rsc);
|
||||||
total += start.elapsed();
|
total += start.elapsed();
|
||||||
@@ -253,7 +253,7 @@ fn bench_expand_holds_edge(n: usize, growths: usize) {
|
|||||||
let sized = rsc.ui.widgets.add_strong(Sized {
|
let sized = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: rect.any(),
|
inner: rect.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(abs(40.0)),
|
y: Some(abs(40.0).into()),
|
||||||
});
|
});
|
||||||
growable = Some(sized.weak());
|
growable = Some(sized.weak());
|
||||||
list.push_back(LazyItem::new(i as u64, sized.any()));
|
list.push_back(LazyItem::new(i as u64, sized.any()));
|
||||||
@@ -287,7 +287,7 @@ fn bench_expand_holds_edge(n: usize, growths: usize) {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.note_tap(top + 1.0);
|
.note_tap(top + 1.0);
|
||||||
}
|
}
|
||||||
rsc.ui.widgets.get_mut(&growable).unwrap().y = Some(abs(height));
|
rsc.ui.widgets.get_mut(&growable).unwrap().y = Some(abs(height).into());
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
render.update(&root, &mut rsc);
|
render.update(&root, &mut rsc);
|
||||||
total += start.elapsed();
|
total += start.elapsed();
|
||||||
|
|||||||
+189
-45
@@ -3,10 +3,13 @@ use crate::{UiNum, util::impl_op};
|
|||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
||||||
pub struct Size {
|
pub struct Size {
|
||||||
pub x: Len,
|
pub x: LayoutLen,
|
||||||
pub y: Len,
|
pub y: LayoutLen,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A length resolved from physical pixels, density-independent pixels, and a
|
||||||
|
/// fraction of a reference length. Unlike [`LayoutLen`], it carries no claim
|
||||||
|
/// on space left over by a layout container.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub struct Len {
|
pub struct Len {
|
||||||
/// Physical pixels -- a raw device pixel, unaffected by the display's
|
/// Physical pixels -- a raw device pixel, unaffected by the display's
|
||||||
@@ -17,6 +20,15 @@ pub struct Len {
|
|||||||
pub abs: f32,
|
pub abs: f32,
|
||||||
pub dp: f32,
|
pub dp: f32,
|
||||||
pub rel: f32,
|
pub rel: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A widget length plus its proportional claim on the space left after fixed
|
||||||
|
/// and relative lengths have been allocated.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
pub struct LayoutLen {
|
||||||
|
pub abs: f32,
|
||||||
|
pub dp: f32,
|
||||||
|
pub rel: f32,
|
||||||
pub rest: f32,
|
pub rest: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,8 +38,25 @@ impl<N: UiNum> From<N> for Len {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Nx: UiNum, Ny: UiNum> From<(Nx, Ny)> for Size {
|
impl<N: UiNum> From<N> for LayoutLen {
|
||||||
fn from((x, y): (Nx, Ny)) -> Self {
|
fn from(value: N) -> Self {
|
||||||
|
Self::abs(value.to_f32())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Len> for LayoutLen {
|
||||||
|
fn from(value: Len) -> Self {
|
||||||
|
Self {
|
||||||
|
abs: value.abs,
|
||||||
|
dp: value.dp,
|
||||||
|
rel: value.rel,
|
||||||
|
rest: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<X: Into<LayoutLen>, Y: Into<LayoutLen>> From<(X, Y)> for Size {
|
||||||
|
fn from((x, y): (X, Y)) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: x.into(),
|
x: x.into(),
|
||||||
y: y.into(),
|
y: y.into(),
|
||||||
@@ -35,41 +64,47 @@ impl<Nx: UiNum, Ny: UiNum> From<(Nx, Ny)> for Size {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<LayoutLen> for Size {
|
||||||
|
fn from(value: LayoutLen) -> Self {
|
||||||
|
Self { x: value, y: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Len> for Size {
|
impl From<Len> for Size {
|
||||||
fn from(value: Len) -> Self {
|
fn from(value: Len) -> Self {
|
||||||
Self { x: value, y: value }
|
Self::from(LayoutLen::from(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Size {
|
impl Size {
|
||||||
pub const ZERO: Self = Self {
|
pub const ZERO: Self = Self {
|
||||||
x: Len::ZERO,
|
x: LayoutLen::ZERO,
|
||||||
y: Len::ZERO,
|
y: LayoutLen::ZERO,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const REST: Self = Self {
|
pub const REST: Self = Self {
|
||||||
x: Len::REST,
|
x: LayoutLen::REST,
|
||||||
y: Len::REST,
|
y: LayoutLen::REST,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn abs(v: Vec2) -> Self {
|
pub fn abs(v: Vec2) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: Len::abs(v.x),
|
x: LayoutLen::abs(v.x),
|
||||||
y: Len::abs(v.y),
|
y: LayoutLen::abs(v.y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rel(v: Vec2) -> Self {
|
pub fn rel(v: Vec2) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: Len::rel(v.x),
|
x: LayoutLen::rel(v.x),
|
||||||
y: Len::rel(v.y),
|
y: LayoutLen::rel(v.y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rest(v: Vec2) -> Self {
|
pub fn rest(v: Vec2) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: Len::rest(v.x),
|
x: LayoutLen::rest(v.x),
|
||||||
y: Len::rest(v.y),
|
y: LayoutLen::rest(v.y),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +115,7 @@ impl Size {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_axis(axis: Axis, aligned: Len, ortho: Len) -> Self {
|
pub fn from_axis(axis: Axis, aligned: LayoutLen, ortho: LayoutLen) -> Self {
|
||||||
match axis {
|
match axis {
|
||||||
Axis::X => Self {
|
Axis::X => Self {
|
||||||
x: aligned,
|
x: aligned,
|
||||||
@@ -93,7 +128,7 @@ impl Size {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn axis(&self, axis: Axis) -> Len {
|
pub fn axis(&self, axis: Axis) -> LayoutLen {
|
||||||
match axis {
|
match axis {
|
||||||
Axis::X => self.x,
|
Axis::X => self.x,
|
||||||
Axis::Y => self.y,
|
Axis::Y => self.y,
|
||||||
@@ -101,7 +136,7 @@ impl Size {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Len {
|
impl LayoutLen {
|
||||||
pub const ZERO: Self = Self {
|
pub const ZERO: Self = Self {
|
||||||
abs: 0.0,
|
abs: 0.0,
|
||||||
dp: 0.0,
|
dp: 0.0,
|
||||||
@@ -119,7 +154,7 @@ impl Len {
|
|||||||
/// Resolves to a `UiScalar`, folding `dp` into `abs` pixels against
|
/// Resolves to a `UiScalar`, folding `dp` into `abs` pixels against
|
||||||
/// `density` (physical pixels per dp -- 1.0 on a desktop or an
|
/// `density` (physical pixels per dp -- 1.0 on a desktop or an
|
||||||
/// unscaled display, `content_scale` on Android; see `dp`'s field
|
/// unscaled display, `content_scale` on Android; see `dp`'s field
|
||||||
/// doc). Every other component of `Len` is already resolution-
|
/// doc). Every other component of `LayoutLen` is already resolution-
|
||||||
/// independent (`rel` is a fraction of the parent; `rest` becomes a
|
/// independent (`rel` is a fraction of the parent; `rest` becomes a
|
||||||
/// fraction too, below), so `density` only ever touches this one term.
|
/// fraction too, below), so `density` only ever touches this one term.
|
||||||
pub fn apply_rest(&self, density: f32) -> UiScalar {
|
pub fn apply_rest(&self, density: f32) -> UiScalar {
|
||||||
@@ -129,11 +164,11 @@ impl Len {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The same fold as [`Self::apply_rest`] but staying a `Len`, so
|
/// The same fold as [`Self::apply_rest`] but staying a `LayoutLen`, so
|
||||||
/// `rest` survives: `dp` becomes physical pixels and every other
|
/// `rest` survives: `dp` becomes physical pixels and every other
|
||||||
/// component is left alone.
|
/// component is left alone.
|
||||||
///
|
///
|
||||||
/// **A `Len` a widget *reports* must have been through this.** `dp` is
|
/// **A `LayoutLen` a widget *reports* must have been through this.** `dp` is
|
||||||
/// an input unit -- a number the widget author wrote -- and the
|
/// an input unit -- a number the widget author wrote -- and the
|
||||||
/// containers that consume a reported length read `abs`/`rel`/`rest`
|
/// containers that consume a reported length read `abs`/`rel`/`rest`
|
||||||
/// directly (`Span::draw`'s placement arithmetic, `Pad`'s addition),
|
/// directly (`Span::draw`'s placement arithmetic, `Pad`'s addition),
|
||||||
@@ -186,35 +221,68 @@ impl Len {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Len {
|
||||||
|
pub const ZERO: Self = Self {
|
||||||
|
abs: 0.0,
|
||||||
|
dp: 0.0,
|
||||||
|
rel: 0.0,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn abs(abs: impl UiNum) -> Self {
|
||||||
|
Self {
|
||||||
|
abs: abs.to_f32(),
|
||||||
|
dp: 0.0,
|
||||||
|
rel: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dp(dp: impl UiNum) -> Self {
|
||||||
|
Self {
|
||||||
|
abs: 0.0,
|
||||||
|
dp: dp.to_f32(),
|
||||||
|
rel: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rel(rel: impl UiNum) -> Self {
|
||||||
|
Self {
|
||||||
|
abs: 0.0,
|
||||||
|
dp: 0.0,
|
||||||
|
rel: rel.to_f32(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn fold_dp(self, density: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
abs: self.abs + self.dp * density,
|
||||||
|
dp: 0.0,
|
||||||
|
rel: self.rel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn resolve(self, density: f32) -> UiScalar {
|
||||||
|
let folded = self.fold_dp(density);
|
||||||
|
UiScalar {
|
||||||
|
rel: folded.rel,
|
||||||
|
abs: folded.abs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub mod len_fns {
|
pub mod len_fns {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub fn abs(abs: impl UiNum) -> Len {
|
pub fn abs(abs: impl UiNum) -> Len {
|
||||||
Len {
|
Len::abs(abs)
|
||||||
abs: abs.to_f32(),
|
|
||||||
dp: 0.0,
|
|
||||||
rel: 0.0,
|
|
||||||
rest: 0.0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pub fn dp(dp: impl UiNum) -> Len {
|
pub fn dp(dp: impl UiNum) -> Len {
|
||||||
Len {
|
Len::dp(dp)
|
||||||
abs: 0.0,
|
|
||||||
dp: dp.to_f32(),
|
|
||||||
rel: 0.0,
|
|
||||||
rest: 0.0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pub fn rel(rel: impl UiNum) -> Len {
|
pub fn rel(rel: impl UiNum) -> Len {
|
||||||
Len {
|
Len::rel(rel)
|
||||||
abs: 0.0,
|
|
||||||
dp: 0.0,
|
|
||||||
rel: rel.to_f32(),
|
|
||||||
rest: 0.0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pub fn rest(ratio: impl UiNum) -> Len {
|
pub fn rest(ratio: impl UiNum) -> LayoutLen {
|
||||||
Len {
|
LayoutLen {
|
||||||
abs: 0.0,
|
abs: 0.0,
|
||||||
dp: 0.0,
|
dp: 0.0,
|
||||||
rel: 0.0,
|
rel: 0.0,
|
||||||
@@ -223,25 +291,49 @@ pub mod len_fns {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_op!(Len Add add; abs dp rel rest);
|
impl_op!(LayoutLen Add add; abs dp rel rest);
|
||||||
impl_op!(Len Sub sub; abs dp rel rest);
|
impl_op!(LayoutLen Sub sub; abs dp rel rest);
|
||||||
|
impl_op!(Len Add add; abs dp rel);
|
||||||
|
impl_op!(Len Sub sub; abs dp rel);
|
||||||
|
|
||||||
|
impl std::ops::Add<Len> for LayoutLen {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, rhs: Len) -> Self::Output {
|
||||||
|
self + Self::from(rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Sub<Len> for LayoutLen {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn sub(self, rhs: Len) -> Self::Output {
|
||||||
|
self - Self::from(rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_op!(Size Add add; x y);
|
impl_op!(Size Add add; x y);
|
||||||
impl_op!(Size Sub sub; x y);
|
impl_op!(Size Sub sub; x y);
|
||||||
|
|
||||||
impl Default for Len {
|
impl Default for LayoutLen {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::rest(1.0)
|
Self::rest(1.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Len {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::ZERO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Size {
|
impl std::fmt::Display for Size {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "({}, {})", self.x, self.y)
|
write!(f, "({}, {})", self.x, self.y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Len {
|
impl std::fmt::Display for LayoutLen {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
if self.abs != 0.0 {
|
if self.abs != 0.0 {
|
||||||
write!(f, "{} abs;", self.abs)?;
|
write!(f, "{} abs;", self.abs)?;
|
||||||
@@ -258,3 +350,55 @@ impl std::fmt::Display for Len {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Len {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
if self.abs != 0.0 {
|
||||||
|
write!(f, "{} abs;", self.abs)?;
|
||||||
|
}
|
||||||
|
if self.dp != 0.0 {
|
||||||
|
write!(f, "{} dp;", self.dp)?;
|
||||||
|
}
|
||||||
|
if self.rel != 0.0 {
|
||||||
|
write!(f, "{} rel;", self.rel)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn an_ordinary_length_enters_layout_without_claiming_rest() {
|
||||||
|
let layout = LayoutLen::from(Len {
|
||||||
|
abs: 3.0,
|
||||||
|
dp: 4.0,
|
||||||
|
rel: 0.5,
|
||||||
|
});
|
||||||
|
assert_eq!(layout.abs, 3.0);
|
||||||
|
assert_eq!(layout.dp, 4.0);
|
||||||
|
assert_eq!(layout.rel, 0.5);
|
||||||
|
assert_eq!(layout.rest, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ordinary_and_layout_lengths_keep_their_own_defaults() {
|
||||||
|
assert_eq!(Len::default(), Len::ZERO);
|
||||||
|
assert_eq!(LayoutLen::default(), LayoutLen::REST);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn adding_an_ordinary_length_preserves_a_layout_claim() {
|
||||||
|
assert_eq!(
|
||||||
|
LayoutLen::rest(2) + Len::dp(8),
|
||||||
|
LayoutLen {
|
||||||
|
abs: 0.0,
|
||||||
|
dp: 8.0,
|
||||||
|
rel: 0.0,
|
||||||
|
rest: 2.0,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
Axis, Len, MoveOffset, PaintId, RegionAlign, RenderedText, Size, StrongWidget, TextHandle,
|
Axis, LayoutLen, MoveOffset, PaintId, RegionAlign, RenderedText, Size, StrongWidget,
|
||||||
TextResources, TextureHandle, UiData, UiRegion, UiRenderState, UiRsc, UiScalar, UiVec2,
|
TextHandle, TextResources, TextureHandle, UiData, UiRegion, UiRenderState, UiRsc, UiScalar,
|
||||||
WidgetId,
|
UiVec2, WidgetId,
|
||||||
render::{
|
render::{
|
||||||
Drawn, GlyphPrimitive, IMAGE_BINDING, Mask, MaskIdx, MoveIdx, NOT_DRAWN, Primitive,
|
Drawn, GlyphPrimitive, IMAGE_BINDING, Mask, MaskIdx, MoveIdx, NOT_DRAWN, Primitive,
|
||||||
PrimitiveHandle, PrimitiveInst, RectPrimitive,
|
PrimitiveHandle, PrimitiveInst, RectPrimitive,
|
||||||
@@ -253,7 +253,7 @@ impl<'a> Painter<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn known_len<W: ?Sized>(&mut self, id: &StrongWidget<W>, axis: Axis) -> Option<Len> {
|
pub fn known_len<W: ?Sized>(&mut self, id: &StrongWidget<W>, axis: Axis) -> Option<LayoutLen> {
|
||||||
let len = if let Some(len) = self.rsc.widgets().get_dyn(id.id())?.size_hint(axis) {
|
let len = if let Some(len) = self.rsc.widgets().get_dyn(id.id())?.size_hint(axis) {
|
||||||
Some(len.fold_dp(self.density()))
|
Some(len.fold_dp(self.density()))
|
||||||
} else if !self.reuse_child_sizes[match axis {
|
} else if !self.reuse_child_sizes[match axis {
|
||||||
@@ -480,7 +480,7 @@ impl<'a> Painter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Physical pixels per `dp` -- see `UiRenderState::density`'s field
|
/// Physical pixels per `dp` -- see `UiRenderState::density`'s field
|
||||||
/// doc. What `Len::dp`'s `apply_rest` call resolves against.
|
/// doc. What `LayoutLen::dp`'s `apply_rest` call resolves against.
|
||||||
pub fn density(&self) -> f32 {
|
pub fn density(&self) -> f32 {
|
||||||
self.render_state.density
|
self.render_state.density
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ pub struct UiRenderState {
|
|||||||
pub primitives: Primitives,
|
pub primitives: Primitives,
|
||||||
pub layers: PrimitiveLayers,
|
pub layers: PrimitiveLayers,
|
||||||
pub(super) output_size: Vec2,
|
pub(super) output_size: Vec2,
|
||||||
/// Physical pixels per `dp` -- see `Len::dp`'s field doc. `1.0` (an
|
/// Physical pixels per `dp` -- see `LayoutLen::dp`'s field doc. `1.0` (an
|
||||||
/// unscaled display) until a backend that knows its own density calls
|
/// unscaled display) until a backend that knows its own density calls
|
||||||
/// `set_density` (Android's `content_scale`, read at `surface_changed`
|
/// `set_density` (Android's `content_scale`, read at `surface_changed`
|
||||||
/// time); the winit backend has no analogous per-monitor value wired up
|
/// time); the winit backend has no analogous per-monitor value wired up
|
||||||
@@ -207,7 +207,7 @@ impl UiRenderState {
|
|||||||
self.resized = true;
|
self.resized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the physical-pixels-per-dp ratio every `Len::dp` in the tree
|
/// Sets the physical-pixels-per-dp ratio every `LayoutLen::dp` in the tree
|
||||||
/// resolves against from the next layout pass on -- see `density`'s
|
/// resolves against from the next layout pass on -- see `density`'s
|
||||||
/// field doc. Not folded into `resize` because the two change on
|
/// field doc. Not folded into `resize` because the two change on
|
||||||
/// different triggers (a surface resize on every rotation or keyboard
|
/// different triggers (a surface resize on every rotation or keyboard
|
||||||
@@ -485,7 +485,7 @@ impl UiRenderState {
|
|||||||
debug_assert!(
|
debug_assert!(
|
||||||
size.x.dp == 0.0 && size.y.dp == 0.0,
|
size.x.dp == 0.0 && size.y.dp == 0.0,
|
||||||
"widget {id:?} reported an unresolved `dp` size ({size:?}); \
|
"widget {id:?} reported an unresolved `dp` size ({size:?}); \
|
||||||
report `Len::fold_dp(painter.density())` instead"
|
report `LayoutLen::fold_dp(painter.density())` instead"
|
||||||
);
|
);
|
||||||
for (axis, hint) in [Axis::X, Axis::Y]
|
for (axis, hint) in [Axis::X, Axis::Y]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::{Axis, Len, Painter, Size};
|
use crate::{Axis, LayoutLen, Painter, Size};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
mod data;
|
mod data;
|
||||||
@@ -28,7 +28,7 @@ pub enum ChildOrder {
|
|||||||
pub trait Widget: Any {
|
pub trait Widget: Any {
|
||||||
fn draw(&mut self, painter: &mut Painter);
|
fn draw(&mut self, painter: &mut Painter);
|
||||||
|
|
||||||
fn size_hint(&self, _axis: Axis) -> Option<Len> {
|
fn size_hint(&self, _axis: Axis) -> Option<LayoutLen> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,8 +63,8 @@ impl Widget for () {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self, _axis: Axis) -> Option<Len> {
|
fn size_hint(&self, _axis: Axis) -> Option<LayoutLen> {
|
||||||
Some(Len::ZERO)
|
Some(LayoutLen::ZERO)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+72
-27
@@ -18,7 +18,7 @@ struct FixedRect(f32);
|
|||||||
|
|
||||||
impl Widget for FixedRect {
|
impl Widget for FixedRect {
|
||||||
fn draw(&mut self, painter: &mut Painter) {
|
fn draw(&mut self, painter: &mut Painter) {
|
||||||
let size = Size::from_axis(Axis::Y, Len::abs(self.0), Len::REST);
|
let size = Size::from_axis(Axis::Y, LayoutLen::abs(self.0), LayoutLen::REST);
|
||||||
let paint = painter.paint(&PaintId::WHITE);
|
let paint = painter.paint(&PaintId::WHITE);
|
||||||
painter.primitive_within(
|
painter.primitive_within(
|
||||||
RectPrimitive::color(paint),
|
RectPrimitive::color(paint),
|
||||||
@@ -50,7 +50,11 @@ struct TracedLeaf {
|
|||||||
impl Widget for TracedLeaf {
|
impl Widget for TracedLeaf {
|
||||||
fn draw(&mut self, painter: &mut Painter) {
|
fn draw(&mut self, painter: &mut Painter) {
|
||||||
self.trace.borrow_mut().push("child");
|
self.trace.borrow_mut().push("child");
|
||||||
painter.set_size(Size::from_axis(Axis::Y, Len::abs(self.height), Len::REST));
|
painter.set_size(Size::from_axis(
|
||||||
|
Axis::Y,
|
||||||
|
LayoutLen::abs(self.height),
|
||||||
|
LayoutLen::REST,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +72,11 @@ struct CountedLeaf {
|
|||||||
impl Widget for CountedLeaf {
|
impl Widget for CountedLeaf {
|
||||||
fn draw(&mut self, painter: &mut Painter) {
|
fn draw(&mut self, painter: &mut Painter) {
|
||||||
self.draws.set(self.draws.get() + 1);
|
self.draws.set(self.draws.get() + 1);
|
||||||
painter.set_size(Size::from_axis(Axis::Y, Len::abs(self.height), Len::REST));
|
painter.set_size(Size::from_axis(
|
||||||
|
Axis::Y,
|
||||||
|
LayoutLen::abs(self.height),
|
||||||
|
LayoutLen::REST,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +154,10 @@ fn a_size_dependent_parent_is_invalidated_before_layout_runs_downward() {
|
|||||||
render.update(&root, &mut rsc);
|
render.update(&root, &mut rsc);
|
||||||
|
|
||||||
assert_eq!(&*trace.borrow(), &["parent", "child"]);
|
assert_eq!(&*trace.borrow(), &["parent", "child"]);
|
||||||
assert_eq!(render.active[&parent_weak.id()].size.y, Len::abs(40.0));
|
assert_eq!(
|
||||||
|
render.active[&parent_weak.id()].size.y,
|
||||||
|
LayoutLen::abs(40.0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -192,7 +203,7 @@ fn a_span_reuses_unchanged_sibling_sizes_when_only_its_along_extent_changes() {
|
|||||||
let span = rsc.ui.widgets.add_strong(Span {
|
let span = rsc.ui.widgets.add_strong(Span {
|
||||||
children: vec![changed.any(), sibling.any()],
|
children: vec![changed.any(), sibling.any()],
|
||||||
dir: Dir::DOWN,
|
dir: Dir::DOWN,
|
||||||
gap: Len::ZERO,
|
gap: LayoutLen::ZERO,
|
||||||
});
|
});
|
||||||
let root = rsc
|
let root = rsc
|
||||||
.ui
|
.ui
|
||||||
@@ -275,7 +286,7 @@ fn a_hinted_rest_draws_once_and_only_moves_the_fixed_child_after_it() {
|
|||||||
let fill = rsc.ui.widgets.add_strong(Sized {
|
let fill = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: fill.any(),
|
inner: fill.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::REST),
|
y: Some(LayoutLen::REST),
|
||||||
});
|
});
|
||||||
let last = rsc.ui.widgets.add_strong(FixedRect(40.0));
|
let last = rsc.ui.widgets.add_strong(FixedRect(40.0));
|
||||||
let last_w = last.weak();
|
let last_w = last.weak();
|
||||||
@@ -308,7 +319,7 @@ fn scrolled_rects(
|
|||||||
let row = rsc.ui.widgets.add_strong(Sized {
|
let row = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: rect.any(),
|
inner: rect.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(10.0)),
|
y: Some(LayoutLen::abs(10.0)),
|
||||||
});
|
});
|
||||||
span.push(row.any());
|
span.push(row.any());
|
||||||
}
|
}
|
||||||
@@ -531,7 +542,7 @@ fn a_scroll_measures_the_box_it_was_offered_not_the_window() {
|
|||||||
let tall = rsc.ui.widgets.add_strong(Sized {
|
let tall = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: rect.any(),
|
inner: rect.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(1000.0)),
|
y: Some(LayoutLen::abs(1000.0)),
|
||||||
});
|
});
|
||||||
let scroll = rsc
|
let scroll = rsc
|
||||||
.ui
|
.ui
|
||||||
@@ -542,7 +553,7 @@ fn a_scroll_measures_the_box_it_was_offered_not_the_window() {
|
|||||||
let capped = rsc.ui.widgets.add_strong(MaxSize {
|
let capped = rsc.ui.widgets.add_strong(MaxSize {
|
||||||
inner: scroll.any(),
|
inner: scroll.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(100.0)),
|
y: Some(LayoutLen::abs(100.0)),
|
||||||
});
|
});
|
||||||
let capped_id = capped.id();
|
let capped_id = capped.id();
|
||||||
let root = capped.any();
|
let root = capped.any();
|
||||||
@@ -555,11 +566,11 @@ fn a_scroll_measures_the_box_it_was_offered_not_the_window() {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
render.active.get(&scroll_id).unwrap().size.y,
|
render.active.get(&scroll_id).unwrap().size.y,
|
||||||
Len::abs(1000.0)
|
LayoutLen::abs(1000.0)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
render.active.get(&capped_id).unwrap().size.y,
|
render.active.get(&capped_id).unwrap().size.y,
|
||||||
Len::abs(100.0),
|
LayoutLen::abs(100.0),
|
||||||
"the cap, not the content and not the window"
|
"the cap, not the content and not the window"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -579,7 +590,7 @@ fn a_panned_widgets_own_hit_box_moves_exactly_once() {
|
|||||||
let tall = rsc.ui.widgets.add_strong(Sized {
|
let tall = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: rect.any(),
|
inner: rect.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(1000.0)),
|
y: Some(LayoutLen::abs(1000.0)),
|
||||||
});
|
});
|
||||||
let tall_w = tall.weak();
|
let tall_w = tall.weak();
|
||||||
let scroll = rsc
|
let scroll = rsc
|
||||||
@@ -624,7 +635,7 @@ fn a_masked_widget_keeps_one_mask_slot_that_is_always_its_own_region() {
|
|||||||
let capped = rsc.ui.widgets.add_strong(MaxSize {
|
let capped = rsc.ui.widgets.add_strong(MaxSize {
|
||||||
inner: masked.any(),
|
inner: masked.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(60.0)),
|
y: Some(LayoutLen::abs(60.0)),
|
||||||
});
|
});
|
||||||
let mut span = Span::empty(Dir::DOWN);
|
let mut span = Span::empty(Dir::DOWN);
|
||||||
span.push(filler.any());
|
span.push(filler.any());
|
||||||
@@ -658,12 +669,12 @@ fn a_dp_cap_is_reported_in_pixels_so_a_span_can_place_it() {
|
|||||||
let tall = rsc.ui.widgets.add_strong(Sized {
|
let tall = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: rect.any(),
|
inner: rect.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(1000.0)),
|
y: Some(LayoutLen::abs(1000.0)),
|
||||||
});
|
});
|
||||||
let capped = rsc.ui.widgets.add_strong(MaxSize {
|
let capped = rsc.ui.widgets.add_strong(MaxSize {
|
||||||
inner: tall.any(),
|
inner: tall.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::dp(100.0)),
|
y: Some(LayoutLen::dp(100.0)),
|
||||||
});
|
});
|
||||||
let capped_w = capped.weak();
|
let capped_w = capped.weak();
|
||||||
let filler = rsc.ui.widgets.add_strong(Rect::new(PaintId::BLACK));
|
let filler = rsc.ui.widgets.add_strong(Rect::new(PaintId::BLACK));
|
||||||
@@ -698,7 +709,7 @@ fn a_size_independent_widget_moved_by_its_parent_has_the_hit_box_it_is_drawn_at(
|
|||||||
let spacer = rsc.ui.widgets.add_strong(Sized {
|
let spacer = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: top.any(),
|
inner: top.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(100.0)),
|
y: Some(LayoutLen::abs(100.0)),
|
||||||
});
|
});
|
||||||
let spacer_w = spacer.weak();
|
let spacer_w = spacer.weak();
|
||||||
let below = rsc.ui.widgets.add_strong(Rect::new(PaintId::WHITE));
|
let below = rsc.ui.widgets.add_strong(Rect::new(PaintId::WHITE));
|
||||||
@@ -718,7 +729,7 @@ fn a_size_independent_widget_moved_by_its_parent_has_the_hit_box_it_is_drawn_at(
|
|||||||
first.top_left
|
first.top_left
|
||||||
);
|
);
|
||||||
|
|
||||||
rsc.ui.widgets.get_mut(&spacer_w).unwrap().y = Some(Len::abs(250.0));
|
rsc.ui.widgets.get_mut(&spacer_w).unwrap().y = Some(LayoutLen::abs(250.0));
|
||||||
render.update(&root, &mut rsc);
|
render.update(&root, &mut rsc);
|
||||||
let after = render.window_region(&below_w, &rsc).unwrap();
|
let after = render.window_region(&below_w, &rsc).unwrap();
|
||||||
assert!(
|
assert!(
|
||||||
@@ -763,7 +774,7 @@ fn a_widget_moved_by_its_parent_and_then_placed_inside_it_lands_at_the_placement
|
|||||||
let child = rsc.ui.widgets.add_strong(Sized {
|
let child = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: rect.any(),
|
inner: rect.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(40.0)),
|
y: Some(LayoutLen::abs(40.0)),
|
||||||
});
|
});
|
||||||
let child_w = child.weak();
|
let child_w = child.weak();
|
||||||
let parent = rsc.ui.widgets.add_strong(MoveThenPlace {
|
let parent = rsc.ui.widgets.add_strong(MoveThenPlace {
|
||||||
@@ -998,7 +1009,7 @@ fn a_scroll_area_opens_at_the_start_of_content_it_has_not_measured_yet() {
|
|||||||
let tall = rsc.ui.widgets.add_strong(Sized {
|
let tall = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: fill,
|
inner: fill,
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(5000.0)),
|
y: Some(LayoutLen::abs(5000.0)),
|
||||||
});
|
});
|
||||||
let scroll = rsc
|
let scroll = rsc
|
||||||
.ui
|
.ui
|
||||||
@@ -1032,7 +1043,7 @@ fn a_span_of_padded_children_inside_a_span_draws_each_where_its_box_is() {
|
|||||||
let header = rsc.ui.widgets.add_strong(Sized {
|
let header = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: header_fill,
|
inner: header_fill,
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(HEADER)),
|
y: Some(LayoutLen::abs(HEADER)),
|
||||||
});
|
});
|
||||||
let mut inner = Span::empty(Dir::DOWN);
|
let mut inner = Span::empty(Dir::DOWN);
|
||||||
let mut rects = Vec::new();
|
let mut rects = Vec::new();
|
||||||
@@ -1042,7 +1053,7 @@ fn a_span_of_padded_children_inside_a_span_draws_each_where_its_box_is() {
|
|||||||
let sized = rsc.ui.widgets.add_strong(Sized {
|
let sized = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: rect.any(),
|
inner: rect.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(ROW)),
|
y: Some(LayoutLen::abs(ROW)),
|
||||||
});
|
});
|
||||||
let padded = rsc.ui.widgets.add_strong(Pad {
|
let padded = rsc.ui.widgets.add_strong(Pad {
|
||||||
padding: Padding::uniform(PAD),
|
padding: Padding::uniform(PAD),
|
||||||
@@ -1056,7 +1067,7 @@ fn a_span_of_padded_children_inside_a_span_draws_each_where_its_box_is() {
|
|||||||
});
|
});
|
||||||
let wide = rsc.ui.widgets.add_strong(Sized {
|
let wide = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: card.any(),
|
inner: card.any(),
|
||||||
x: Some(Len::rest(1.0)),
|
x: Some(LayoutLen::rest(1.0)),
|
||||||
y: None,
|
y: None,
|
||||||
});
|
});
|
||||||
inner.push(wide.any());
|
inner.push(wide.any());
|
||||||
@@ -1065,7 +1076,7 @@ fn a_span_of_padded_children_inside_a_span_draws_each_where_its_box_is() {
|
|||||||
let outer = rsc.ui.widgets.add_strong(Span {
|
let outer = rsc.ui.widgets.add_strong(Span {
|
||||||
children: vec![header.any(), inner.any()],
|
children: vec![header.any(), inner.any()],
|
||||||
dir: Dir::DOWN,
|
dir: Dir::DOWN,
|
||||||
gap: Len::ZERO,
|
gap: LayoutLen::ZERO,
|
||||||
});
|
});
|
||||||
let mut list = LazySpan::new(Dir::DOWN, Pin::End);
|
let mut list = LazySpan::new(Dir::DOWN, Pin::End);
|
||||||
list.push_back(LazyItem::new(0, outer.any()));
|
list.push_back(LazyItem::new(0, outer.any()));
|
||||||
@@ -1101,6 +1112,40 @@ fn a_span_of_padded_children_inside_a_span_draws_each_where_its_box_is() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rest_padding_claims_leftover_space_around_fixed_content() {
|
||||||
|
let mut rsc = TestRsc { ui: Ui::default() };
|
||||||
|
let content = rect(PaintId::WHITE).sized((20, 10)).add_strong(&mut rsc);
|
||||||
|
let content_id = content.weak();
|
||||||
|
let padded = rsc.ui.widgets.add_strong(Pad {
|
||||||
|
inner: content.any(),
|
||||||
|
padding: Padding {
|
||||||
|
left: LayoutLen::rest(0.5),
|
||||||
|
right: LayoutLen::rest(0.5),
|
||||||
|
..Padding::ZERO
|
||||||
|
},
|
||||||
|
exact_region: false,
|
||||||
|
});
|
||||||
|
let root = rsc
|
||||||
|
.ui
|
||||||
|
.widgets
|
||||||
|
.add_strong(Sized {
|
||||||
|
inner: padded.any(),
|
||||||
|
x: Some(LayoutLen::abs(100)),
|
||||||
|
y: None,
|
||||||
|
})
|
||||||
|
.any();
|
||||||
|
let mut render = UiRenderState::new();
|
||||||
|
render.resize((100.0, 40.0));
|
||||||
|
|
||||||
|
render.update(&root, &mut rsc);
|
||||||
|
render.update(&root, &mut rsc);
|
||||||
|
|
||||||
|
let region = render.window_region(&content_id, &rsc).unwrap();
|
||||||
|
assert_eq!(region.top_left.x, 40.0);
|
||||||
|
assert_eq!(region.bot_right.x, 60.0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn a_new_child_in_a_growing_lazy_row_uses_its_final_box_immediately() {
|
fn a_new_child_in_a_growing_lazy_row_uses_its_final_box_immediately() {
|
||||||
const FIRST: f32 = 30.0;
|
const FIRST: f32 = 30.0;
|
||||||
@@ -1113,15 +1158,15 @@ fn a_new_child_in_a_growing_lazy_row_uses_its_final_box_immediately() {
|
|||||||
let first = rsc.ui.widgets.add_strong(Sized {
|
let first = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: first.any(),
|
inner: first.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(FIRST)),
|
y: Some(LayoutLen::abs(FIRST)),
|
||||||
});
|
});
|
||||||
let mut contents = Span::empty(Dir::DOWN).gap(Len::abs(GAP));
|
let mut contents = Span::empty(Dir::DOWN).gap(LayoutLen::abs(GAP));
|
||||||
contents.push(first.any());
|
contents.push(first.any());
|
||||||
let contents = rsc.ui.widgets.add_strong(contents);
|
let contents = rsc.ui.widgets.add_strong(contents);
|
||||||
let contents_w = contents.weak();
|
let contents_w = contents.weak();
|
||||||
let row = rsc.ui.widgets.add_strong(Sized {
|
let row = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: contents.any(),
|
inner: contents.any(),
|
||||||
x: Some(Len::rest(1.0)),
|
x: Some(LayoutLen::rest(1.0)),
|
||||||
y: None,
|
y: None,
|
||||||
});
|
});
|
||||||
let mut list = LazySpan::new(Dir::DOWN, Pin::End);
|
let mut list = LazySpan::new(Dir::DOWN, Pin::End);
|
||||||
@@ -1137,7 +1182,7 @@ fn a_new_child_in_a_growing_lazy_row_uses_its_final_box_immediately() {
|
|||||||
let second = rsc.ui.widgets.add_strong(Sized {
|
let second = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: second.any(),
|
inner: second.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(SECOND)),
|
y: Some(LayoutLen::abs(SECOND)),
|
||||||
});
|
});
|
||||||
rsc.ui
|
rsc.ui
|
||||||
.widgets
|
.widgets
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ fn a_finger_drag_over_a_scroll_area_pans_it() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let scroll_strong = rect(PaintId::WHITE)
|
let scroll_strong = rect(PaintId::WHITE)
|
||||||
.height(Len::abs(1000.0))
|
.height(LayoutLen::abs(1000.0))
|
||||||
.scrollable(Axis::Y, Pin::Start)
|
.scrollable(Axis::Y, Pin::Start)
|
||||||
.add_strong(&mut rsc);
|
.add_strong(&mut rsc);
|
||||||
let scroll = scroll_strong.weak();
|
let scroll = scroll_strong.weak();
|
||||||
@@ -367,7 +367,7 @@ fn a_scroll_area_that_captured_the_pointer_learns_its_gesture_ended() {
|
|||||||
events: EventManager::default(),
|
events: EventManager::default(),
|
||||||
};
|
};
|
||||||
let scroll_strong = rect(PaintId::WHITE)
|
let scroll_strong = rect(PaintId::WHITE)
|
||||||
.height(Len::abs(1000.0))
|
.height(LayoutLen::abs(1000.0))
|
||||||
.scrollable(Axis::Y, Pin::Start)
|
.scrollable(Axis::Y, Pin::Start)
|
||||||
.add_strong(&mut rsc);
|
.add_strong(&mut rsc);
|
||||||
let scroll = scroll_strong.weak();
|
let scroll = scroll_strong.weak();
|
||||||
@@ -522,8 +522,8 @@ fn a_drag_pans_whichever_nested_scroll_area_owns_its_axis() {
|
|||||||
let seen = Rc::new(Cell::new(None));
|
let seen = Rc::new(Cell::new(None));
|
||||||
let record = seen.clone();
|
let record = seen.clone();
|
||||||
let outer_strong = rect(PaintId::WHITE)
|
let outer_strong = rect(PaintId::WHITE)
|
||||||
.width(Len::abs(1000.0))
|
.width(LayoutLen::abs(1000.0))
|
||||||
.height(Len::abs(1000.0))
|
.height(LayoutLen::abs(1000.0))
|
||||||
.scrollable(Axis::X, Pin::Start)
|
.scrollable(Axis::X, Pin::Start)
|
||||||
.with_id(move |_rsc, id| {
|
.with_id(move |_rsc, id| {
|
||||||
record.set(Some(id));
|
record.set(Some(id));
|
||||||
@@ -581,13 +581,13 @@ fn a_press_does_not_reach_a_widget_the_pointer_has_just_left() {
|
|||||||
let half = |slot: &Rc<Cell<Option<WeakWidget<ScrollArea>>>>| {
|
let half = |slot: &Rc<Cell<Option<WeakWidget<ScrollArea>>>>| {
|
||||||
let record = slot.clone();
|
let record = slot.clone();
|
||||||
rect(PaintId::WHITE)
|
rect(PaintId::WHITE)
|
||||||
.height(Len::abs(1000.0))
|
.height(LayoutLen::abs(1000.0))
|
||||||
.scrollable(Axis::Y, Pin::Start)
|
.scrollable(Axis::Y, Pin::Start)
|
||||||
.with_id(move |_rsc, id| {
|
.with_id(move |_rsc, id| {
|
||||||
record.set(Some(id));
|
record.set(Some(id));
|
||||||
id
|
id
|
||||||
})
|
})
|
||||||
.height(Len::rel(0.5))
|
.height(LayoutLen::rel(0.5))
|
||||||
};
|
};
|
||||||
let root = (half(&seen[0]), half(&seen[1]))
|
let root = (half(&seen[0]), half(&seen[1]))
|
||||||
.span(Dir::DOWN)
|
.span(Dir::DOWN)
|
||||||
|
|||||||
+2
-2
@@ -12,8 +12,8 @@ impl Widget for Image {
|
|||||||
painter.set_size(Size::abs(size));
|
painter.set_size(Size::abs(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self, axis: Axis) -> Option<Len> {
|
fn size_hint(&self, axis: Axis) -> Option<LayoutLen> {
|
||||||
Some(Len::abs(self.handle.size().axis(axis)))
|
Some(LayoutLen::abs(self.handle.size().axis(axis)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_size_independent(&self) -> bool {
|
fn is_size_independent(&self) -> bool {
|
||||||
|
|||||||
@@ -811,8 +811,8 @@ impl Widget for LazySpan {
|
|||||||
painter.set_size(Size::REST);
|
painter.set_size(Size::REST);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self, _axis: Axis) -> Option<Len> {
|
fn size_hint(&self, _axis: Axis) -> Option<LayoutLen> {
|
||||||
Some(Len::REST)
|
Some(LayoutLen::REST)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -850,7 +850,7 @@ mod tests {
|
|||||||
let sized = rsc.ui.widgets.add_strong(Sized {
|
let sized = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: rect.any(),
|
inner: rect.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(height)),
|
y: Some(LayoutLen::abs(height)),
|
||||||
});
|
});
|
||||||
(sized.weak(), sized.any())
|
(sized.weak(), sized.any())
|
||||||
}
|
}
|
||||||
@@ -1054,7 +1054,7 @@ mod tests {
|
|||||||
let fg = rsc.ui.widgets.add_strong(Sized {
|
let fg = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: fg_rect.any(),
|
inner: fg_rect.any(),
|
||||||
x: None,
|
x: None,
|
||||||
y: Some(Len::abs(height)),
|
y: Some(LayoutLen::abs(height)),
|
||||||
});
|
});
|
||||||
let fg_weak = fg.weak();
|
let fg_weak = fg.weak();
|
||||||
let stack = Stack {
|
let stack = Stack {
|
||||||
@@ -1084,7 +1084,7 @@ mod tests {
|
|||||||
render.update(&root, &mut rsc);
|
render.update(&root, &mut rsc);
|
||||||
|
|
||||||
let (bg_id, fg) = rows[key_to_change as usize];
|
let (bg_id, fg) = rows[key_to_change as usize];
|
||||||
rsc.ui.widgets.get_mut(&fg).unwrap().y = Some(Len::abs(new_height));
|
rsc.ui.widgets.get_mut(&fg).unwrap().y = Some(LayoutLen::abs(new_height));
|
||||||
render.update(&root, &mut rsc);
|
render.update(&root, &mut rsc);
|
||||||
|
|
||||||
let px = render
|
let px = render
|
||||||
@@ -1190,7 +1190,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rsc.ui.widgets.get_mut(&list_weak).unwrap().note_tap(41.0);
|
rsc.ui.widgets.get_mut(&list_weak).unwrap().note_tap(41.0);
|
||||||
rsc.ui.widgets.get_mut(&row2).unwrap().y = Some(Len::abs(50.0));
|
rsc.ui.widgets.get_mut(&row2).unwrap().y = Some(LayoutLen::abs(50.0));
|
||||||
|
|
||||||
render.update(&root, &mut rsc);
|
render.update(&root, &mut rsc);
|
||||||
|
|
||||||
@@ -1227,7 +1227,7 @@ mod tests {
|
|||||||
|
|
||||||
let row2 = rows[2];
|
let row2 = rows[2];
|
||||||
rsc.ui.widgets.get_mut(&list_weak).unwrap().note_tap(59.0);
|
rsc.ui.widgets.get_mut(&list_weak).unwrap().note_tap(59.0);
|
||||||
rsc.ui.widgets.get_mut(&row2).unwrap().y = Some(Len::abs(50.0));
|
rsc.ui.widgets.get_mut(&row2).unwrap().y = Some(LayoutLen::abs(50.0));
|
||||||
render.update(&root, &mut rsc);
|
render.update(&root, &mut rsc);
|
||||||
|
|
||||||
let list_ref = rsc.ui.widgets.get(&list_weak).unwrap();
|
let list_ref = rsc.ui.widgets.get(&list_weak).unwrap();
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
pub struct MaxSize {
|
pub struct MaxSize {
|
||||||
pub inner: StrongWidget,
|
pub inner: StrongWidget,
|
||||||
pub x: Option<Len>,
|
pub x: Option<LayoutLen>,
|
||||||
pub y: Option<Len>,
|
pub y: Option<LayoutLen>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MaxSize {
|
impl MaxSize {
|
||||||
fn clamp(len: Len, max: Option<Len>, output: f32, density: f32) -> Len {
|
fn clamp(len: LayoutLen, max: Option<LayoutLen>, output: f32, density: f32) -> LayoutLen {
|
||||||
let Some(max) = max else {
|
let Some(max) = max else {
|
||||||
return len;
|
return len;
|
||||||
};
|
};
|
||||||
@@ -20,7 +20,7 @@ impl MaxSize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clamp_region(offered_px: f32, max: Option<Len>, output: f32, density: f32) -> UiSpan {
|
fn clamp_region(offered_px: f32, max: Option<LayoutLen>, output: f32, density: f32) -> UiSpan {
|
||||||
let Some(max) = max else {
|
let Some(max) = max else {
|
||||||
return UiSpan::FULL;
|
return UiSpan::FULL;
|
||||||
};
|
};
|
||||||
|
|||||||
+75
-37
@@ -10,16 +10,14 @@ impl Widget for Pad {
|
|||||||
fn draw(&mut self, painter: &mut Painter) {
|
fn draw(&mut self, painter: &mut Painter) {
|
||||||
let density = painter.density();
|
let density = painter.density();
|
||||||
let offered = painter.px_size();
|
let offered = painter.px_size();
|
||||||
let region = self.padding.region(density);
|
let used = painter
|
||||||
let used = painter.widget_within(&self.inner, region).size();
|
.widget_within(&self.inner, self.padding.fixed_region(density))
|
||||||
|
.size();
|
||||||
|
let region = self.padding.region_for(used, density);
|
||||||
painter.place_used(&self.inner, used, region);
|
painter.place_used(&self.inner, used, region);
|
||||||
let width =
|
|
||||||
self.padding.left.apply_rest(density).abs + self.padding.right.apply_rest(density).abs;
|
|
||||||
let height =
|
|
||||||
self.padding.top.apply_rest(density).abs + self.padding.bottom.apply_rest(density).abs;
|
|
||||||
let size = Size {
|
let size = Size {
|
||||||
x: used.x + Len::abs(width),
|
x: self.padding.left.fold_dp(density) + used.x + self.padding.right.fold_dp(density),
|
||||||
y: used.y + Len::abs(height),
|
y: self.padding.top.fold_dp(density) + used.y + self.padding.bottom.fold_dp(density),
|
||||||
};
|
};
|
||||||
let needed = size.to_uivec2(density).to_abs(painter.output_size());
|
let needed = size.to_uivec2(density).to_abs(painter.output_size());
|
||||||
if needed.x <= offered.x + 0.01 && needed.y <= offered.y + 0.01 {
|
if needed.x <= offered.x + 0.01 && needed.y <= offered.y + 0.01 {
|
||||||
@@ -34,21 +32,21 @@ impl Widget for Pad {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Padding {
|
pub struct Padding {
|
||||||
pub left: Len,
|
pub left: LayoutLen,
|
||||||
pub right: Len,
|
pub right: LayoutLen,
|
||||||
pub top: Len,
|
pub top: LayoutLen,
|
||||||
pub bottom: Len,
|
pub bottom: LayoutLen,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Padding {
|
impl Padding {
|
||||||
pub const ZERO: Self = Self {
|
pub const ZERO: Self = Self {
|
||||||
left: Len::ZERO,
|
left: LayoutLen::ZERO,
|
||||||
right: Len::ZERO,
|
right: LayoutLen::ZERO,
|
||||||
top: Len::ZERO,
|
top: LayoutLen::ZERO,
|
||||||
bottom: Len::ZERO,
|
bottom: LayoutLen::ZERO,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn uniform(amt: impl Into<Len>) -> Self {
|
pub fn uniform(amt: impl Into<LayoutLen>) -> Self {
|
||||||
let amt = amt.into();
|
let amt = amt.into();
|
||||||
Self {
|
Self {
|
||||||
left: amt,
|
left: amt,
|
||||||
@@ -57,79 +55,119 @@ impl Padding {
|
|||||||
bottom: amt,
|
bottom: amt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn region(&self, density: f32) -> UiRegion {
|
fn fixed_region(&self, density: f32) -> UiRegion {
|
||||||
let mut region = UiRegion::FULL;
|
let mut region = UiRegion::FULL;
|
||||||
region.x.start.abs += self.left.apply_rest(density).abs;
|
let left = self.left.fold_dp(density);
|
||||||
region.y.start.abs += self.top.apply_rest(density).abs;
|
let right = self.right.fold_dp(density);
|
||||||
region.x.end.abs -= self.right.apply_rest(density).abs;
|
let top = self.top.fold_dp(density);
|
||||||
region.y.end.abs -= self.bottom.apply_rest(density).abs;
|
let bottom = self.bottom.fold_dp(density);
|
||||||
|
region.x.start += UiScalar::new(left.rel, left.abs);
|
||||||
|
region.x.end -= UiScalar::new(right.rel, right.abs);
|
||||||
|
region.y.start += UiScalar::new(top.rel, top.abs);
|
||||||
|
region.y.end -= UiScalar::new(bottom.rel, bottom.abs);
|
||||||
region
|
region
|
||||||
}
|
}
|
||||||
pub fn x(amt: impl Into<Len>) -> Self {
|
|
||||||
|
fn region_for(&self, inner: Size, density: f32) -> UiRegion {
|
||||||
|
UiRegion {
|
||||||
|
x: padded_axis(self.left, inner.x, self.right, density),
|
||||||
|
y: padded_axis(self.top, inner.y, self.bottom, density),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn x(amt: impl Into<LayoutLen>) -> Self {
|
||||||
let amt = amt.into();
|
let amt = amt.into();
|
||||||
Self {
|
Self {
|
||||||
left: amt,
|
left: amt,
|
||||||
right: amt,
|
right: amt,
|
||||||
top: Len::ZERO,
|
top: LayoutLen::ZERO,
|
||||||
bottom: Len::ZERO,
|
bottom: LayoutLen::ZERO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn y(amt: impl Into<Len>) -> Self {
|
pub fn y(amt: impl Into<LayoutLen>) -> Self {
|
||||||
let amt = amt.into();
|
let amt = amt.into();
|
||||||
Self {
|
Self {
|
||||||
left: Len::ZERO,
|
left: LayoutLen::ZERO,
|
||||||
right: Len::ZERO,
|
right: LayoutLen::ZERO,
|
||||||
top: amt,
|
top: amt,
|
||||||
bottom: amt,
|
bottom: amt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn top(amt: impl Into<Len>) -> Self {
|
pub fn top(amt: impl Into<LayoutLen>) -> Self {
|
||||||
let mut s = Self::ZERO;
|
let mut s = Self::ZERO;
|
||||||
s.top = amt.into();
|
s.top = amt.into();
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bottom(amt: impl Into<Len>) -> Self {
|
pub fn bottom(amt: impl Into<LayoutLen>) -> Self {
|
||||||
let mut s = Self::ZERO;
|
let mut s = Self::ZERO;
|
||||||
s.bottom = amt.into();
|
s.bottom = amt.into();
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn left(amt: impl Into<Len>) -> Self {
|
pub fn left(amt: impl Into<LayoutLen>) -> Self {
|
||||||
let mut s = Self::ZERO;
|
let mut s = Self::ZERO;
|
||||||
s.left = amt.into();
|
s.left = amt.into();
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn right(amt: impl Into<Len>) -> Self {
|
pub fn right(amt: impl Into<LayoutLen>) -> Self {
|
||||||
let mut s = Self::ZERO;
|
let mut s = Self::ZERO;
|
||||||
s.right = amt.into();
|
s.right = amt.into();
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_top(mut self, amt: impl Into<Len>) -> Self {
|
pub fn with_top(mut self, amt: impl Into<LayoutLen>) -> Self {
|
||||||
self.top = amt.into();
|
self.top = amt.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_bottom(mut self, amt: impl Into<Len>) -> Self {
|
pub fn with_bottom(mut self, amt: impl Into<LayoutLen>) -> Self {
|
||||||
self.bottom = amt.into();
|
self.bottom = amt.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_left(mut self, amt: impl Into<Len>) -> Self {
|
pub fn with_left(mut self, amt: impl Into<LayoutLen>) -> Self {
|
||||||
self.left = amt.into();
|
self.left = amt.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_right(mut self, amt: impl Into<Len>) -> Self {
|
pub fn with_right(mut self, amt: impl Into<LayoutLen>) -> Self {
|
||||||
self.right = amt.into();
|
self.right = amt.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Into<Len>> From<T> for Padding {
|
fn padded_axis(before: LayoutLen, inner: LayoutLen, after: LayoutLen, density: f32) -> UiSpan {
|
||||||
|
let lengths = [
|
||||||
|
before.fold_dp(density),
|
||||||
|
inner.fold_dp(density),
|
||||||
|
after.fold_dp(density),
|
||||||
|
];
|
||||||
|
let total = lengths
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.fold(LayoutLen::ZERO, |sum, len| sum + len);
|
||||||
|
let fixed = UiScalar::new(total.rel, total.abs);
|
||||||
|
let mut cursor = UiScalar::ZERO;
|
||||||
|
let mut inner_span = UiSpan::FULL;
|
||||||
|
for (index, len) in lengths.into_iter().enumerate() {
|
||||||
|
let start = cursor;
|
||||||
|
if len.rest > 0.0 {
|
||||||
|
let rest_end = UiScalar::rel(len.rest / total.rest);
|
||||||
|
let available_end = (UiScalar::FULL + cursor) - fixed;
|
||||||
|
cursor = rest_end.within(&cursor.to(available_end));
|
||||||
|
}
|
||||||
|
cursor.rel += len.rel;
|
||||||
|
cursor.abs += len.abs;
|
||||||
|
if index == 1 {
|
||||||
|
inner_span = start.to(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inner_span
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Into<LayoutLen>> From<T> for Padding {
|
||||||
fn from(amt: T) -> Self {
|
fn from(amt: T) -> Self {
|
||||||
Self::uniform(amt.into())
|
Self::uniform(amt.into())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ mod tests {
|
|||||||
let mut rsc = TestRsc { ui: Ui::default() };
|
let mut rsc = TestRsc { ui: Ui::default() };
|
||||||
let fill = rsc.ui.widgets.add_strong(Rect::new(PaintId::WHITE)).any();
|
let fill = rsc.ui.widgets.add_strong(Rect::new(PaintId::WHITE)).any();
|
||||||
let id = fill.id();
|
let id = fill.id();
|
||||||
let long = Some(Len::abs(1000.0));
|
let long = Some(LayoutLen::abs(1000.0));
|
||||||
let tall = rsc.ui.widgets.add_strong(Sized {
|
let tall = rsc.ui.widgets.add_strong(Sized {
|
||||||
inner: fill,
|
inner: fill,
|
||||||
x: (axis == Axis::X).then_some(long).flatten(),
|
x: (axis == Axis::X).then_some(long).flatten(),
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use crate::prelude::*;
|
|||||||
|
|
||||||
pub struct Sized {
|
pub struct Sized {
|
||||||
pub inner: StrongWidget,
|
pub inner: StrongWidget,
|
||||||
pub x: Option<Len>,
|
pub x: Option<LayoutLen>,
|
||||||
pub y: Option<Len>,
|
pub y: Option<LayoutLen>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for Sized {
|
impl Widget for Sized {
|
||||||
@@ -25,7 +25,7 @@ impl Widget for Sized {
|
|||||||
painter.set_size(size);
|
painter.set_size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self, axis: Axis) -> Option<Len> {
|
fn size_hint(&self, axis: Axis) -> Option<LayoutLen> {
|
||||||
match axis {
|
match axis {
|
||||||
Axis::X => self.x,
|
Axis::X => self.x,
|
||||||
Axis::Y => self.y,
|
Axis::Y => self.y,
|
||||||
|
|||||||
+12
-12
@@ -4,7 +4,7 @@ use std::marker::PhantomData;
|
|||||||
pub struct Span {
|
pub struct Span {
|
||||||
pub children: Vec<StrongWidget>,
|
pub children: Vec<StrongWidget>,
|
||||||
pub dir: Dir,
|
pub dir: Dir,
|
||||||
pub gap: Len,
|
pub gap: LayoutLen,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for Span {
|
impl Widget for Span {
|
||||||
@@ -16,7 +16,7 @@ impl Widget for Span {
|
|||||||
let axis = self.dir.axis;
|
let axis = self.dir.axis;
|
||||||
let gap = self.gap.apply_rest(painter.density()).abs;
|
let gap = self.gap.apply_rest(painter.density()).abs;
|
||||||
|
|
||||||
let mut lens: Vec<Option<Len>> = self
|
let mut lens: Vec<Option<LayoutLen>> = self
|
||||||
.children
|
.children
|
||||||
.iter()
|
.iter()
|
||||||
.map(|child| painter.known_len(child, axis))
|
.map(|child| painter.known_len(child, axis))
|
||||||
@@ -43,13 +43,13 @@ impl Widget for Span {
|
|||||||
cursor.rel += len.rel;
|
cursor.rel += len.rel;
|
||||||
}
|
}
|
||||||
|
|
||||||
let lens: Vec<Len> = lens.into_iter().map(Option::unwrap).collect();
|
let lens: Vec<LayoutLen> = lens.into_iter().map(Option::unwrap).collect();
|
||||||
|
|
||||||
let gap_total = gap * self.children.len().saturating_sub(1) as f32;
|
let gap_total = gap * self.children.len().saturating_sub(1) as f32;
|
||||||
let total = lens.iter().fold(Len::abs(gap_total), |s, &l| s + l);
|
let total = lens.iter().fold(LayoutLen::abs(gap_total), |s, &l| s + l);
|
||||||
|
|
||||||
let mut start = UiScalar::rel_min();
|
let mut start = UiScalar::rel_min();
|
||||||
let mut ortho_len = Len::ZERO;
|
let mut ortho_len = LayoutLen::ZERO;
|
||||||
let mut ortho_mixed = false;
|
let mut ortho_mixed = false;
|
||||||
let mut placed = Vec::with_capacity(self.children.len());
|
let mut placed = Vec::with_capacity(self.children.len());
|
||||||
for (i, (child, &len)) in self.children.iter().zip(&lens).enumerate() {
|
for (i, (child, &len)) in self.children.iter().zip(&lens).enumerate() {
|
||||||
@@ -84,7 +84,7 @@ impl Widget for Span {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ortho_mixed {
|
if ortho_mixed {
|
||||||
ortho_len = Len::default();
|
ortho_len = LayoutLen::default();
|
||||||
} else {
|
} else {
|
||||||
let ortho = ortho_len
|
let ortho = ortho_len
|
||||||
.apply_rest(painter.density())
|
.apply_rest(painter.density())
|
||||||
@@ -98,7 +98,7 @@ impl Widget for Span {
|
|||||||
let along = if total.rest == 0.0 && total.rel == 0.0 {
|
let along = if total.rest == 0.0 && total.rel == 0.0 {
|
||||||
total
|
total
|
||||||
} else {
|
} else {
|
||||||
Len::default()
|
LayoutLen::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
painter.set_size(Size::from_axis(axis, along, ortho_len));
|
painter.set_size(Size::from_axis(axis, along, ortho_len));
|
||||||
@@ -110,11 +110,11 @@ impl Span {
|
|||||||
Self {
|
Self {
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
dir,
|
dir,
|
||||||
gap: Len::ZERO,
|
gap: LayoutLen::ZERO,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gap(mut self, gap: impl Into<Len>) -> Self {
|
pub fn gap(mut self, gap: impl Into<LayoutLen>) -> Self {
|
||||||
self.gap = gap.into();
|
self.gap = gap.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,7 @@ impl Span {
|
|||||||
pub struct SpanBuilder<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag> {
|
pub struct SpanBuilder<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag> {
|
||||||
pub children: Wa,
|
pub children: Wa,
|
||||||
pub dir: Dir,
|
pub dir: Dir,
|
||||||
pub gap: Len,
|
pub gap: LayoutLen,
|
||||||
_pd: PhantomData<(State, Tag)>,
|
_pd: PhantomData<(State, Tag)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,12 +157,12 @@ impl<State, const LEN: usize, Wa: WidgetArrLike<State, LEN, Tag>, Tag>
|
|||||||
Self {
|
Self {
|
||||||
children,
|
children,
|
||||||
dir,
|
dir,
|
||||||
gap: Len::ZERO,
|
gap: LayoutLen::ZERO,
|
||||||
_pd: PhantomData,
|
_pd: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gap(mut self, gap: impl Into<Len>) -> Self {
|
pub fn gap(mut self, gap: impl Into<LayoutLen>) -> Self {
|
||||||
self.gap = gap.into();
|
self.gap = gap.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,9 +53,9 @@ impl Widget for Stack {
|
|||||||
painter.set_size(size);
|
painter.set_size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self, _axis: Axis) -> Option<Len> {
|
fn size_hint(&self, _axis: Axis) -> Option<LayoutLen> {
|
||||||
match self.size {
|
match self.size {
|
||||||
StackSize::Default => Some(Len::REST),
|
StackSize::Default => Some(LayoutLen::REST),
|
||||||
StackSize::Child(_) => None,
|
StackSize::Child(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -49,8 +49,8 @@ impl Widget for Rect {
|
|||||||
painter.set_size(Size::REST);
|
painter.set_size(Size::REST);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn size_hint(&self, _axis: Axis) -> Option<Len> {
|
fn size_hint(&self, _axis: Axis) -> Option<LayoutLen> {
|
||||||
Some(Len::REST)
|
Some(LayoutLen::REST)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ widget_trait! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max_width(self, len: impl Into<Len>) -> impl WidgetFn<Rsc, MaxSize> {
|
fn max_width(self, len: impl Into<LayoutLen>) -> impl WidgetFn<Rsc, MaxSize> {
|
||||||
let len = len.into();
|
let len = len.into();
|
||||||
move |state| MaxSize {
|
move |state| MaxSize {
|
||||||
inner: self.add_strong(state),
|
inner: self.add_strong(state),
|
||||||
@@ -50,7 +50,7 @@ widget_trait! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max_height(self, len: impl Into<Len>) -> impl WidgetFn<Rsc, MaxSize> {
|
fn max_height(self, len: impl Into<LayoutLen>) -> impl WidgetFn<Rsc, MaxSize> {
|
||||||
let len = len.into();
|
let len = len.into();
|
||||||
move |state| MaxSize {
|
move |state| MaxSize {
|
||||||
inner: self.add_strong(state),
|
inner: self.add_strong(state),
|
||||||
@@ -59,7 +59,7 @@ widget_trait! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn width(self, len: impl Into<Len>) -> impl WidgetFn<Rsc, Sized> {
|
fn width(self, len: impl Into<LayoutLen>) -> impl WidgetFn<Rsc, Sized> {
|
||||||
let len = len.into();
|
let len = len.into();
|
||||||
move |state| Sized {
|
move |state| Sized {
|
||||||
inner: self.add_strong(state),
|
inner: self.add_strong(state),
|
||||||
@@ -68,7 +68,7 @@ widget_trait! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn height(self, len: impl Into<Len>) -> impl WidgetFn<Rsc, Sized> {
|
fn height(self, len: impl Into<LayoutLen>) -> impl WidgetFn<Rsc, Sized> {
|
||||||
let len = len.into();
|
let len = len.into();
|
||||||
move |state| Sized {
|
move |state| Sized {
|
||||||
inner: self.add_strong(state),
|
inner: self.add_strong(state),
|
||||||
|
|||||||
Reference in new issue
Block a user