Skip to content

Commit

Permalink
chore: make grow 2D
Browse files Browse the repository at this point in the history
  • Loading branch information
ten3roberts committed Mar 14, 2024
1 parent a050a75 commit 836596d
Show file tree
Hide file tree
Showing 22 changed files with 340 additions and 285 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
RUST_LOG="info"
# RUST_LOG="info"
# RUST_BACKTRACE=1
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ opt-level = 2
[profile.dev.package.parking_lot]
opt-level = 2

[profile.dev.package.puffin]
opt-level = 2

[profile.dev.package.puffin_server]
opt-level = 2

[patch.crates-io]
palette = { git = "https://github.com/Ogeon/palette" }

Expand Down
4 changes: 3 additions & 1 deletion examples/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ impl Widget for MainApp {
row((
column((
Rectangle::new(JADE_DEFAULT).with_size(Unit::px2(900.0, 40.0)),
Rectangle::new(JADE_400).with_size(Unit::px2(900.0, 40.0)),
Rectangle::new(JADE_400)
.with_size(Unit::px2(900.0, 40.0))
.with_min_size(Unit::px2(400.0, 40.0)),
)),
Rectangle::new(LION_DEFAULT).with_size(Unit::px2(900.0, 40.0)),
)),
Expand Down
3 changes: 3 additions & 0 deletions recipes.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"run demo": {
"cmd": "cargo run --package violet-demo"
},
"run demo release": {
"cmd": "cargo run --package violet-demo --release"
},
"run basic": {
"cmd": "cargo run --package violet --example basic"
},
Expand Down
10 changes: 5 additions & 5 deletions violet-core/src/constraints.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use glam::{vec2, Vec2};
use glam::{vec2, BVec2, Vec2};

use crate::layout::{Direction, LayoutLimits, SizeResolver, SizingHints};

Expand Down Expand Up @@ -42,8 +42,8 @@ impl SizeResolver for FixedAreaConstraint {
min * self.unit_size,
vec2(size.x, (self.area / size.x).ceil()) * self.unit_size,
SizingHints {
can_grow: true,
fixed_size: false,
can_grow: BVec2::TRUE,
relative_size: BVec2::TRUE,
},
)
}
Expand All @@ -53,11 +53,11 @@ impl SizeResolver for FixedAreaConstraint {
_: &flax::EntityRef,
_: Vec2,
limits: crate::layout::LayoutLimits,
) -> (Vec2, bool) {
) -> (Vec2, BVec2) {
let width = (limits.max_size.x / self.unit_size).floor().max(1.0);

let height = (self.area / width).ceil();

(vec2(width, height) * self.unit_size, true)
(vec2(width, height) * self.unit_size, BVec2::TRUE)
}
}
55 changes: 36 additions & 19 deletions violet-core/src/layout/cache.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use flax::{component, components::child_of, Entity, FetchExt, RelationExt, World};
use glam::Vec2;
use glam::{BVec2, Vec2};

use super::{flow::Row, Block, Direction, LayoutLimits, Sizing, SizingHints};
use super::{flow::Row, Block, Direction, LayoutLimits, Sizing};

#[derive(Debug)]
pub struct CachedValue<T> {
Expand Down Expand Up @@ -34,7 +34,7 @@ pub struct LayoutCache {
pub(crate) query_row: Option<CachedValue<Row>>,
pub(crate) layout: Option<CachedValue<Block>>,
on_invalidated: Option<Box<dyn Fn(LayoutUpdate) + Send + Sync>>,
pub(crate) fixed_size: bool,
pub(crate) relative_size: BVec2,
}

impl LayoutCache {
Expand All @@ -44,7 +44,7 @@ impl LayoutCache {
query_row: None,
layout: None,
on_invalidated,
fixed_size: false,
relative_size: BVec2::TRUE,
}
}

Expand Down Expand Up @@ -86,15 +86,12 @@ impl LayoutCache {
pub fn query(&self) -> &[Option<CachedValue<Sizing>>; 2] {
&self.query
}

pub fn fixed_size(&self) -> bool {
self.fixed_size
}
}

/// Invalidates a widgets layout cache along with its ancestors
pub(crate) fn invalidate_widget(world: &World, id: Entity) {
let entity = world.entity(id).unwrap();
tracing::info!(%entity, "invalidating widget");

let query = (layout_cache().as_mut(), child_of.first_relation().opt());
let mut query = entity.query(&query);
Expand All @@ -117,7 +114,14 @@ pub(crate) fn validate_cached_query(
let min_size = value.min.size();
let preferred_size = value.preferred.size();

tracing::debug!( ?preferred_size, %cache.limits.max_size, %limits.max_size, "validate_cached_query");
// tracing::debug!( ?preferred_size, %cache.limits.max_size, %limits.max_size, "validate_cached_query");

let hints = &value.hints;
if hints.can_grow.x && cache.limits.max_size.x < limits.max_size.x
|| (hints.can_grow.x && cache.limits.max_size.y < limits.max_size.y)
{
tracing::info!(%hints.can_grow, ?cache.limits.max_size, %limits.max_size, "invalidated by can_grow");
}

min_size.x >= limits.min_size.x - LAYOUT_TOLERANCE
&& min_size.y >= limits.min_size.y - LAYOUT_TOLERANCE
Expand All @@ -126,30 +130,40 @@ pub(crate) fn validate_cached_query(
&& min_size.y <= limits.max_size.y + LAYOUT_TOLERANCE
&& preferred_size.x <= limits.max_size.x + LAYOUT_TOLERANCE
&& preferred_size.y <= limits.max_size.y + LAYOUT_TOLERANCE
&& (!value.hints.can_grow || cache.limits.max_size.abs_diff_eq(limits.max_size, LAYOUT_TOLERANCE))
&& (value.hints.fixed_size || cache.content_area.abs_diff_eq(content_area, LAYOUT_TOLERANCE))
&& (!hints.can_grow.x || cache.limits.max_size.x >= limits.max_size.x - LAYOUT_TOLERANCE)
&& (!hints.can_grow.y || cache.limits.max_size.y >= limits.max_size.y - LAYOUT_TOLERANCE)
&& (!hints.relative_size.x || (cache.content_area.x - content_area.x).abs() < LAYOUT_TOLERANCE)
&& (!hints.relative_size.y || (cache.content_area.y - content_area.y).abs() < LAYOUT_TOLERANCE)
}

pub(crate) fn validate_cached_layout(
cache: &CachedValue<Block>,
limits: LayoutLimits,
content_area: Vec2,
// Calculated from the query stage
fixed_size: bool,
relative_size: BVec2,
) -> bool {
let value = &cache.value;

let size = value.rect.size();
let size = value.rect.size().min(cache.limits.max_size);

// tracing::debug!( ?size, %cache.limits.max_size, %limits.max_size, "validate_cached_layout");

tracing::debug!( ?size, %cache.limits.max_size, %limits.max_size, "validate_cached_layout");
if value.can_grow.x && cache.limits.max_size.x < limits.max_size.x
|| (value.can_grow.x && cache.limits.max_size.y < limits.max_size.y)
{
tracing::info!(%value.can_grow, ?cache.limits.max_size, %limits.max_size, "invalidated layout by can_grow");
}

size.x >= limits.min_size.x - LAYOUT_TOLERANCE
&& size.y >= limits.min_size.y - LAYOUT_TOLERANCE
// Min may be larger than preferred for the orthogonal optimization direction
&& size.x <= limits.max_size.x + LAYOUT_TOLERANCE
&& size.y <= limits.max_size.y + LAYOUT_TOLERANCE
&& (!value.can_grow || cache.limits.max_size.abs_diff_eq(limits.max_size, LAYOUT_TOLERANCE))
&& (fixed_size || cache.content_area.abs_diff_eq(content_area, LAYOUT_TOLERANCE))
&& (!value.can_grow.x || cache.limits.max_size.x >= limits.max_size.x - LAYOUT_TOLERANCE)
&& (!value.can_grow.y || cache.limits.max_size.y >= limits.max_size.y - LAYOUT_TOLERANCE)
&& (!relative_size.x || (cache.content_area.x - content_area.x).abs() < LAYOUT_TOLERANCE)
&& (!relative_size.y || (cache.content_area.y - content_area.y).abs() < LAYOUT_TOLERANCE)
}

pub(crate) fn validate_cached_row(
Expand All @@ -161,8 +175,9 @@ pub(crate) fn validate_cached_row(

let min_size = value.min.size();
let preferred_size = value.preferred.size();
let hints = value.hints;

tracing::debug!( ?preferred_size, %cache.limits.max_size, %limits.max_size, "validate_cached_row");
// tracing::debug!( ?preferred_size, %cache.limits.max_size, %limits.max_size, "validate_cached_row");

min_size.x >= limits.min_size.x - LAYOUT_TOLERANCE
&& min_size.y >= limits.min_size.y - LAYOUT_TOLERANCE
Expand All @@ -171,8 +186,10 @@ pub(crate) fn validate_cached_row(
&& min_size.y <= limits.max_size.y + LAYOUT_TOLERANCE
&& preferred_size.x <= limits.max_size.x + LAYOUT_TOLERANCE
&& preferred_size.y <= limits.max_size.y + LAYOUT_TOLERANCE
&& (!value.hints.can_grow || cache.limits.max_size.abs_diff_eq(limits.max_size, LAYOUT_TOLERANCE))
&& (value.hints.fixed_size || cache.content_area.abs_diff_eq(content_area, LAYOUT_TOLERANCE))
&& (!hints.can_grow.x || cache.limits.max_size.x >= limits.max_size.x - LAYOUT_TOLERANCE)
&& (!hints.can_grow.y || cache.limits.max_size.y >= limits.max_size.y - LAYOUT_TOLERANCE)
&& (!hints.relative_size.x || (cache.content_area.x - content_area.x).abs() < LAYOUT_TOLERANCE)
&& (!hints.relative_size.y || (cache.content_area.y - content_area.y).abs() < LAYOUT_TOLERANCE)
}

component! {
Expand Down
11 changes: 4 additions & 7 deletions violet-core/src/layout/flow.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::sync::Arc;

use flax::{Entity, EntityRef, World};
use glam::{vec2, Vec2};
use glam::{vec2, BVec2, Vec2};
use itertools::Itertools;

use crate::{
Expand Down Expand Up @@ -260,7 +260,7 @@ impl FlowLayout {

let cross_size = row.preferred.size().max(preferred_size).dot(cross_axis);

let mut can_grow = false;
let mut can_grow = BVec2::FALSE;
// Distribute the size to the widgets and apply their layout
let blocks = row
.blocks
Expand Down Expand Up @@ -328,7 +328,7 @@ impl FlowLayout {
// let local_rect = widget_outer_bounds(world, &child, size);
let block = update_subtree(world, &entity, content_area.size(), child_limits);

can_grow = can_grow || block.can_grow;
can_grow |= block.can_grow;
tracing::debug!(?block, "updated subtree");

// block.rect = block
Expand Down Expand Up @@ -462,10 +462,7 @@ impl FlowLayout {
let mut sum = 0.0;

let cross_size = row.preferred.size().max(preferred_size).dot(cross_axis);
let mut hints = SizingHints {
fixed_size: true,
can_grow: false,
};
let mut hints = SizingHints::default();

// Distribute the size to the widgets and apply their layout
row
Expand Down
Loading

0 comments on commit 836596d

Please sign in to comment.