Skip to content

Commit

Permalink
fix: account for margin for fit calculation
Browse files Browse the repository at this point in the history
  • Loading branch information
ten3roberts committed Oct 30, 2023
1 parent 322c5a5 commit 458908d
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 93 deletions.
118 changes: 62 additions & 56 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use tracing_subscriber::{
use tracing_tree::HierarchicalLayer;
use violet::{
assets::{fs::BytesFromFile, AssetKey},
components::{self, color, filled_rect, flow, font_size, size, text, Edges},
components::{self, color, filled_rect, flow, font_size, padding, size, text, Edges},
input::{on_focus, on_mouse_input},
layout::{CrossAlign, Direction, Flow},
shapes::FilledRect,
Expand All @@ -35,7 +35,7 @@ macro_rules! srgba {
}};
}

const MARGIN: Edges = Edges::even(0.0);
const MARGIN: Edges = Edges::even(10.0);

const EERIE_BLACK: Srgba = srgba!("#222525");
const EERIE_BLACK_300: Srgba = srgba!("#151616");
Expand Down Expand Up @@ -406,6 +406,7 @@ impl Widget for MainApp {
fn mount(self, scope: &mut Scope) {
scope
.set(name(), "MainApp".into())
.set(padding(), Edges::even(10.0))
.set(size(), Unit::rel(vec2(1.0, 1.0)));

// scope.attach(Counter);
Expand Down Expand Up @@ -542,39 +543,42 @@ impl Widget for MainApp {
// .with_cross_align(CrossAlign::Stretch)
// .with_background_color(Hsla::new(190.0, 0.048, 0.143, 1.0).into_color());

scope.attach(
List::new((
LayoutTest {
contain_margins: false,
},
LayoutTest {
contain_margins: false,
},
LayoutTest {
contain_margins: true,
},
LayoutTest {
contain_margins: true,
},
LayoutTest {
contain_margins: false,
},
// Text::new("Hello, World!"),
))
.contain_margins(true)
.with_direction(Direction::Vertical)
.with_padding(Edges::even(0.0)),
// List::new((
// // list3,
// List::new((list1, list2))
// .with_cross_align(CrossAlign::Stretch)
// .with_direction(Direction::Vertical)
// .with_background_color(Hsla::new(190.0, 0.048, 0.1, 1.0).into_color()),
// ))
// .with_cross_align(CrossAlign::Stretch)
// .with_direction(Direction::Horizontal)
// .with_background_color(Hsla::new(190.0, 0.048, 0.1, 1.0).into_color()),
);
scope.attach(LayoutTest {
contain_margins: true,
});
// scope.attach(
// List::new((
// LayoutTest {
// contain_margins: false,
// },
// LayoutTest {
// contain_margins: false,
// },
// LayoutTest {
// contain_margins: true,
// },
// LayoutTest {
// contain_margins: true,
// },
// LayoutTest {
// contain_margins: false,
// },
// // Text::new("Hello, World!"),
// ))
// .contain_margins(true)
// .with_direction(Direction::Vertical)
// .with_padding(Edges::even(0.0)),
// // List::new((
// // // list3,
// // List::new((list1, list2))
// // .with_cross_align(CrossAlign::Stretch)
// // .with_direction(Direction::Vertical)
// // .with_background_color(Hsla::new(190.0, 0.048, 0.1, 1.0).into_color()),
// // ))
// // .with_cross_align(CrossAlign::Stretch)
// // .with_direction(Direction::Horizontal)
// // .with_background_color(Hsla::new(190.0, 0.048, 0.1, 1.0).into_color()),
// );
}
}

Expand Down Expand Up @@ -625,39 +629,41 @@ struct LayoutTest {

impl Widget for LayoutTest {
fn mount(self, scope: &mut Scope<'_>) {
let row_2 = List::new((
Rectangle { color: BRONZE }
.with_margin(MARGIN)
.with_size(Unit::px(vec2(100.0, 50.0))),
Rectangle { color: EMERALD }
.with_margin(MARGIN)
.with_size(Unit::px(vec2(20.0, 50.0))),
))
.contain_margins(self.contain_margins)
.with_background_color(EERIE_BLACK_300)
.with_margin(MARGIN);
// let row_2 = List::new((
// Rectangle { color: BRONZE }
// .with_margin(MARGIN)
// .with_size(Unit::px(vec2(100.0, 50.0))),
// Rectangle { color: EMERALD }
// .with_margin(MARGIN)
// .with_size(Unit::px(vec2(20.0, 50.0))),
// ))
// .contain_margins(self.contain_margins)
// .with_background_color(EERIE_BLACK_300)
// .with_margin(MARGIN);

let row_1 = List::new((
Rectangle { color: CHILI_RED }
.with_margin(MARGIN)
.with_size(Unit::px(vec2(200.0, 50.0))),
row_2,
StackTest {},
// row_2,
// StackTest {},
// Text::new("Hello, World!"),
Rectangle { color: TEAL }
.with_margin(MARGIN)
// .with_margin(MARGIN)
.with_size(Unit::px(vec2(100.0, 50.0))),
Rectangle { color: TEAL }
.with_margin(MARGIN)
.with_size(Unit::px(vec2(50.0, 50.0))),
// Rectangle { color: TEAL }
// // .with_margin(MARGIN)
// .with_size(Unit::px(vec2(50.0, 50.0))),
))
.contain_margins(self.contain_margins)
.with_background_color(EERIE_BLACK)
.with_margin(MARGIN);

List::new((row_1,))
.contain_margins(self.contain_margins)
.with_background_color(EERIE_BLACK_300)
.mount(scope);
row_1.mount(scope)
// List::new((row_1,))
// .contain_margins(self.contain_margins)
// .with_background_color(EERIE_BLACK_300)
// .mount(scope);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl App {

frame.delta_time = delta_time;

tracing::info!(?dt, fps = 1.0 / delta_time);
// tracing::info!(?dt, fps = 1.0 / delta_time);

ex.tick(&mut frame);

Expand Down
69 changes: 49 additions & 20 deletions src/layout/flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
layout::query_size,
};

use super::{update_subtree, Block, LayoutLimits, SizeQuery};
use super::{update_subtree, Block, LayoutLimits, Sizing};

#[derive(Debug, Clone)]
struct MarginCursor {
Expand All @@ -23,6 +23,7 @@ struct MarginCursor {
main_margin: (f32, f32),
cross_margin: (f32, f32),
contain_margins: bool,
total_margin: f32,
}

impl MarginCursor {
Expand All @@ -41,6 +42,7 @@ impl MarginCursor {
main_margin: (0.0, 0.0),
cross_margin: (0.0, 0.0),
contain_margins,
total_margin: 0.0,
}
}

Expand All @@ -56,10 +58,12 @@ impl MarginCursor {
self.main_margin.0 = self.main_margin.0.max(back_margin - self.main_cursor);
}

self.total_margin += advance;
self.pending_margin = front_margin;

self.main_cursor += advance + block.rect.support(-self.axis);

// Cross axis margin calculation
let (start_margin, end_margin) = block.margin.in_axis(self.cross_axis);
let placement_pos;

Expand Down Expand Up @@ -92,7 +96,8 @@ impl MarginCursor {
self.main_margin.1 = self.main_margin.1.max(self.pending_margin);

if self.contain_margins {
self.main_cursor += self.pending_margin
self.main_cursor += self.pending_margin;
self.total_margin += self.pending_margin;
}

self.pending_margin = 0.0;
Expand Down Expand Up @@ -158,6 +163,14 @@ impl CrossAlign {
}
}

pub(crate) struct Row<'a> {
pub(crate) min: Rect,
pub(crate) preferred: Rect,
pub(crate) margin: Edges,
pub(crate) blocks: Vec<(EntityRef<'a>, Sizing)>,
pub(crate) total_margin: f32,
}

#[derive(Default, Debug)]
pub struct Flow {
pub cross_align: CrossAlign,
Expand All @@ -179,10 +192,21 @@ impl Flow {
let _span = tracing::info_span!("Flow::apply", ?limits, flow=?self).entered();
let (axis, cross_axis) = self.direction.axis();

let (_, total_preferred_size, _, blocks) = self.query_size(world, entity, content_area);
let row = self.query_size(world, entity, content_area);

// Size remaining if everything got at least its preferred size
let total_preferred_size = total_preferred_size.size().dot(axis);
let total_preferred_size = row.preferred.size().dot(axis) - row.total_margin;

let target_size = total_preferred_size.min(limits.max_size.dot(axis));
let max_size = limits.max_size.dot(axis) - row.total_margin;

tracing::info!(
row.total_margin,
total_preferred_size,
target_size,
%limits.max_size,
"query size"
);

let available_size = limits.max_size;

Expand All @@ -201,33 +225,34 @@ impl Flow {

let mut sum = 0.0;

let blocks = blocks
let blocks = row
.blocks
.into_iter()
.map(|(entity, block)| {
.map(|(entity, sizing)| {
// The size required to go from min to preferred size
let min_size = block.min.size().dot(axis);
let preferred_size = block.preferred.size().dot(axis);
let min_size = sizing.min.size().dot(axis);
let preferred_size = sizing.preferred.size().dot(axis);

let to_preferred = preferred_size - min_size;
let ratio = to_preferred / total_preferred_size;
tracing::info!("sizing: {}", ratio);

sum += ratio;
let axis_sizing = (min_size
+ (limits.max_size.dot(axis) * (to_preferred / total_preferred_size)))
* axis;

let axis_sizing = (min_size + (max_size * ratio)) * axis;
tracing::info!(%axis_sizing, "sizing: {}", ratio);

let child_constraints = if let CrossAlign::Stretch = self.cross_align {
let margin = entity.get_copy(margin()).unwrap_or_default();

let size = inner_rect.size().min(limits.max_size) - margin.size();
LayoutLimits {
min_size: size * cross_axis,
max_size: size * cross_axis + axis_sizing,
max_size: axis_sizing + size * cross_axis,
}
} else {
LayoutLimits {
min_size: Vec2::ZERO,
max_size: available_size * cross_axis + axis_sizing,
max_size: axis_sizing + available_size * cross_axis,
}
};

Expand Down Expand Up @@ -289,7 +314,7 @@ impl Flow {
world: &'a World,
entity: &EntityRef,
inner_rect: Rect,
) -> (Rect, Rect, Edges, Vec<(EntityRef<'a>, SizeQuery)>) {
) -> Row<'a> {
let children = entity.get(children()).ok();
let children = children.as_ref().map(|v| v.as_slice()).unwrap_or_default();

Expand Down Expand Up @@ -335,11 +360,15 @@ impl Flow {

assert_eq!(min_margin, preferred_margin);

(
min_cursor.finish(),
preferred_cursor.finish(),
min_margin,
let preferred = preferred_cursor.finish();
let min = min_cursor.finish();

Row {
min,
preferred,
margin: preferred_margin,
total_margin: preferred_cursor.total_margin,
blocks,
)
}
}
}
Loading

0 comments on commit 458908d

Please sign in to comment.