Move generalization/specialization methods 🚚

This commit is contained in:
Laurenz 2019-11-16 11:10:53 +01:00
parent 261ef9e33a
commit ac4d501945
6 changed files with 44 additions and 40 deletions

View File

@ -129,7 +129,7 @@ impl FlexLayouter {
/// Layout a content box into the current flex run or start a new run if /// Layout a content box into the current flex run or start a new run if
/// it does not fit. /// it does not fit.
fn layout_box(&mut self, boxed: Layout) -> LayoutResult<()> { fn layout_box(&mut self, boxed: Layout) -> LayoutResult<()> {
let size = boxed.dimensions.generalized(self.ctx.axes); let size = self.ctx.axes.generalize(boxed.dimensions);
let space = self.space.unwrap_or(Size::zero()); let space = self.space.unwrap_or(Size::zero());
let new_run_size = self.run.size.x + space + size.x; let new_run_size = self.run.size.x + space + size.x;
@ -166,14 +166,14 @@ impl FlexLayouter {
fn finish_run(&mut self) -> LayoutResult<()> { fn finish_run(&mut self) -> LayoutResult<()> {
let mut actions = LayoutActionList::new(); let mut actions = LayoutActionList::new();
for (x, layout) in self.run.content.drain(..) { for (x, layout) in self.run.content.drain(..) {
let position = Size2D::with_x(x).specialized(self.ctx.axes); let position = self.ctx.axes.specialize(Size2D::with_x(x));
actions.add_layout(position, layout); actions.add_layout(position, layout);
} }
self.run.size.y += self.ctx.flex_spacing; self.run.size.y += self.ctx.flex_spacing;
self.stack.add(Layout { self.stack.add(Layout {
dimensions: self.run.size.specialized(self.ctx.axes), dimensions: self.ctx.axes.specialize(self.run.size),
actions: actions.into_vec(), actions: actions.into_vec(),
debug_render: false, debug_render: false,
})?; })?;
@ -183,6 +183,11 @@ impl FlexLayouter {
Ok(()) Ok(())
} }
/// Update the axes in use by this flex layouter.
pub fn set_axes(&self, axes: LayoutAxes) {
}
/// This layouter's context. /// This layouter's context.
pub fn ctx(&self) -> FlexContext { pub fn ctx(&self) -> FlexContext {
self.ctx self.ctx

View File

@ -199,10 +199,30 @@ pub struct LayoutAxes {
} }
impl LayoutAxes { impl LayoutAxes {
/// Returns the generalized version of a `Size2D` dependent on
/// the layouting axes, that is:
/// - The x coordinate describes the primary axis instead of the horizontal one.
/// - The y coordinate describes the secondary axis instead of the vertical one.
pub fn generalize(&self, space: Size2D) -> Size2D {
if self.primary.axis.is_horizontal() {
space
} else {
Size2D { x: space.y, y: space.x }
}
}
/// Returns the specialized version of this generalized Size2D.
/// (Inverse to `generalized`).
pub fn specialize(&self, space: Size2D) -> Size2D {
// In fact, generalized is its own inverse. For reasons of clarity
// at the call site, we still have this second function.
self.generalize(space)
}
/// The position of the anchor specified by the two aligned axes /// The position of the anchor specified by the two aligned axes
/// in the given generalized space. /// in the given generalized space.
pub fn anchor(&self, area: Size2D) -> Size2D { pub fn anchor(&self, space: Size2D) -> Size2D {
Size2D::new(self.primary.anchor(area.x), self.secondary.anchor(area.y)) Size2D::new(self.primary.anchor(space.x), self.secondary.anchor(space.y))
} }
} }

View File

@ -29,7 +29,7 @@ pub struct StackContext {
impl StackLayouter { impl StackLayouter {
/// Create a new stack layouter. /// Create a new stack layouter.
pub fn new(ctx: StackContext) -> StackLayouter { pub fn new(ctx: StackContext) -> StackLayouter {
let usable = ctx.spaces[0].usable().generalized(ctx.axes); let usable = ctx.axes.generalize(ctx.spaces[0].usable());
StackLayouter { StackLayouter {
ctx, ctx,
layouts: MultiLayout::new(), layouts: MultiLayout::new(),
@ -44,7 +44,7 @@ impl StackLayouter {
/// Add a sublayout. /// Add a sublayout.
pub fn add(&mut self, layout: Layout) -> LayoutResult<()> { pub fn add(&mut self, layout: Layout) -> LayoutResult<()> {
let size = layout.dimensions.generalized(self.ctx.axes); let size = self.ctx.axes.generalize(layout.dimensions);
let mut new_dimensions = self.size_with(size); let mut new_dimensions = self.size_with(size);
// Search for a suitable space to insert the box. // Search for a suitable space to insert the box.
@ -114,7 +114,7 @@ impl StackLayouter {
for (offset, layout_anchor, layout) in self.boxes.drain(..) { for (offset, layout_anchor, layout) in self.boxes.drain(..) {
let general_position = anchor - layout_anchor + Size2D::with_y(offset * factor); let general_position = anchor - layout_anchor + Size2D::with_y(offset * factor);
let position = start + general_position.specialized(self.ctx.axes); let position = start + self.ctx.axes.specialize(general_position);
actions.add_layout(position, layout); actions.add_layout(position, layout);
} }
@ -137,11 +137,16 @@ impl StackLayouter {
/// content is added to it. /// content is added to it.
fn start_new_space(&mut self, include_empty: bool) { fn start_new_space(&mut self, include_empty: bool) {
self.active_space = self.next_space(); self.active_space = self.next_space();
self.usable = self.ctx.spaces[self.active_space].usable().generalized(self.ctx.axes); self.usable = self.ctx.axes.generalize(self.ctx.spaces[self.active_space].usable());
self.dimensions = start_dimensions(self.usable, self.ctx.axes); self.dimensions = start_dimensions(self.usable, self.ctx.axes);
self.include_empty = include_empty; self.include_empty = include_empty;
} }
/// Update the axes in use by this stack layouter.
pub fn set_axes(&self, axes: LayoutAxes) {
}
/// This layouter's context. /// This layouter's context.
pub fn ctx(&self) -> StackContext { pub fn ctx(&self) -> StackContext {
self.ctx self.ctx
@ -154,9 +159,9 @@ impl StackLayouter {
/// The remaining spaces for new layouts in the current space. /// The remaining spaces for new layouts in the current space.
pub fn remaining(&self, shrink_to_fit: bool) -> LayoutSpaces { pub fn remaining(&self, shrink_to_fit: bool) -> LayoutSpaces {
let remains = Size2D::new(self.usable.x, self.usable.y - self.dimensions.y);
let mut spaces = smallvec![LayoutSpace { let mut spaces = smallvec![LayoutSpace {
dimensions: Size2D::new(self.usable.x, self.usable.y - self.dimensions.y) dimensions: self.ctx.axes.specialize(remains),
.specialized(self.ctx.axes),
padding: SizeBox::zero(), padding: SizeBox::zero(),
shrink_to_fit, shrink_to_fit,
}]; }];

View File

@ -100,12 +100,8 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
Command::SetStyle(style) => *self.style.to_mut() = style, Command::SetStyle(style) => *self.style.to_mut() = style,
Command::SetAxes(axes) => { Command::SetAxes(axes) => {
if axes.secondary != self.ctx.axes.secondary { self.stack.set_axes(axes);
self.stack.set_axis(axes.secondary); self.flex.set_axes(axes);
} else if axes.primary != self.ctx.axes.primary {
self.flex.set_axis(axes.primary);
}
self.ctx.axes = axes; self.ctx.axes = axes;
} }
} }

View File

@ -149,7 +149,7 @@ macro_rules! spacefunc {
layout(this, ctx) { layout(this, ctx) {
let $var = match this.0 { let $var = match this.0 {
Spacing::Absolute(s) => s, Spacing::Absolute(s) => s,
Spacing::Relative(f) => Size::pt(f * ctx.style.font_size), Spacing::Relative(f) => f * ctx.style.font_size,
}; };
Ok(commands![$command]) Ok(commands![$command])

View File

@ -142,28 +142,6 @@ impl Size2D {
} }
} }
/// Returns the generalized version of this Size2D dependent on
/// the given layouting axes, that is:
/// - The x coordinate describes the primary axis instead of the horizontal one.
/// - The y coordinate describes the secondary axis instead of the vertical one.
#[inline]
pub fn generalized(&self, axes: LayoutAxes) -> Size2D {
if axes.primary.axis.is_horizontal() {
*self
} else {
Size2D { x: self.y, y: self.x }
}
}
/// Returns the specialized version of this generalized Size2D.
/// (Inverse to `generalized`).
#[inline]
pub fn specialized(&self, axes: LayoutAxes) -> Size2D {
// In fact, generalized is its own inverse. For reasons of clarity
// at the call site, we still have this second function.
self.generalized(axes)
}
/// Whether the given 2D-size fits into this one, that is, /// Whether the given 2D-size fits into this one, that is,
/// both coordinate values are smaller or equal. /// both coordinate values are smaller or equal.
#[inline] #[inline]