Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ten3roberts committed Dec 7, 2024
1 parent 495b227 commit b2a3106
Show file tree
Hide file tree
Showing 20 changed files with 207 additions and 100 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

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

10 changes: 5 additions & 5 deletions examples/buttons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ use tracing_subscriber::{layer::SubscriberExt, registry, util::SubscriberInitExt
use tracing_tree::HierarchicalLayer;

use violet::core::{
layout::Alignment,
style::StyleExt,
unit::Unit,
widget::{List, Rectangle, SignalWidget, Stack, Text},
Scope, Widget,
};
use violet_core::{
layout::Align,
style::{self, primary_surface, secondary_surface, spacing_small, Background, SizeExt},
text::Wrap,
widget::{card, col, label, row, Button, ButtonStyle, SliderWithLabel, TextInput},
Expand Down Expand Up @@ -102,7 +102,7 @@ impl Widget for MainApp {
.collect_vec()),
))
.with_background(Background::new(primary_surface()))
.contain_margins(true)
.with_contain_margins(true)
.mount(scope)
}
}
Expand Down Expand Up @@ -166,14 +166,14 @@ impl Widget for ItemList {
.with_padding(spacing_small())
.with_margin(spacing_small())
// .with_cross_align(Alignment::Center)
.with_vertical_alignment(Alignment::Center)
.with_horizontal_alignment(Alignment::Center)
.with_vertical_alignment(Align::Center)
.with_horizontal_alignment(Align::Center)
.with_size(Unit::px2(size, size))
.with_max_size(Unit::px2(size, size))
})
.collect::<Vec<_>>(),
)
.with_cross_align(Alignment::Center)
.with_cross_align(Align::Center)
.mount(scope)
}
}
4 changes: 2 additions & 2 deletions examples/counter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use tracing_subscriber::{prelude::*, registry, util::SubscriberInitExt, EnvFilte
use tracing_tree::HierarchicalLayer;
use violet::core::{
components::size,
layout::Alignment,
layout::Align,
unit::Unit,
widget::{Button, List, SignalWidget, Stack, Text},
Scope, Widget,
Expand Down Expand Up @@ -61,7 +61,7 @@ impl Widget for MainApp {
)),
))
.with_background(Background::new(accent_element()))
.with_cross_align(Alignment::Center)
.with_cross_align(Align::Center)
.mount(scope);
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fn app() -> impl Widget {
row((Button::label("Longer Button"), Button::label("Button"))),
))
.with_background(Background::new(EMERALD_900)))
.contain_margins(true)
.with_contain_margins(true)
.with_background(Background::new(COPPER_500))
// .with_padding(spacing_medium())
}
2 changes: 1 addition & 1 deletion examples/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl Widget for MainApp {
.with_padding(spacing_small()),
))
// .with_padding(spacing_medium())
.contain_margins(true),
.with_contain_margins(true),
)
.with_background(Background::new(primary_surface()))
.mount(scope)
Expand Down
3 changes: 1 addition & 2 deletions examples/sizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,8 @@ impl Widget for MainApp {
))),
row((label("This is a row of longer text that is wrapped. When the text wraps it will take up more vertical space in the layout, and will as such increase the overall height. Another sentence for good measure to force the text to wrap"), card(Text::new(":P").with_wrap(Wrap::None)))),
SignalWidget::new(size.signal().map(|size| FlowSizing { size })),
// AnimatedSize,
))
.contain_margins(true)
.with_contain_margins(true)
.with_background(Background::new(primary_surface()))
.mount(scope)
}
Expand Down
2 changes: 2 additions & 0 deletions violet-core/src/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ component! {

pub(crate) atoms,

pub(crate) context_store(id): (),

pub on_animation_frame: OnAnimationFrame,

pub handles: Vec<UntypedHandle>,
Expand Down
6 changes: 3 additions & 3 deletions violet-core/src/layout/flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ impl AlignCursor {

let cross_pos = self.align.align_offset(
self.cross_size,
block.rect.pad(&block.margin).size().dot(self.cross_axis),
block.rect.pad(block.margin).size().dot(self.cross_axis),
) + start_margin;

// tracing::debug!( main_pos, %cross_pos, ?block, "aligning");
Expand All @@ -206,7 +206,7 @@ impl AlignCursor {

let outer = block
.rect
.pad(&block.margin)
.pad(block.margin)
.translate(self.cross_axis + cross_pos);
self.cross_inner.0 = self.cross_inner.0.min(outer.min.dot(self.cross_axis));
self.cross_inner.1 = self.cross_inner.1.max(outer.max.dot(self.cross_axis));
Expand All @@ -224,7 +224,7 @@ impl AlignCursor {
placement_pos =
main_pos * self.axis + (self.cross_cursor + cross_pos) * self.cross_axis;

let outer = block.rect.pad(&block.margin).translate(cross_pos);
let outer = block.rect.pad(block.margin).translate(cross_pos);
let inner = block.rect.translate(cross_pos);

self.cross_inner.0 = self.cross_inner.0.min(inner.min.dot(self.cross_axis));
Expand Down
19 changes: 3 additions & 16 deletions violet-core/src/layout/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ pub(crate) fn query_size(world: &World, entity: &EntityRef, args: QueryArgs) ->

Sizing {
margin: (sizing.margin - padding).max(margin),
min: sizing.min.pad(&padding),
preferred: sizing.preferred.pad(&padding),
min: sizing.min.pad(padding),
preferred: sizing.preferred.pad(padding),
hints: sizing.hints.combine(hints),
maximize: sizing.maximize + entity.get_copy(maximize()).unwrap_or_default(),
}
Expand Down Expand Up @@ -359,19 +359,6 @@ pub(crate) fn query_size(world: &World, entity: &EntityRef, args: QueryArgs) ->
sizing.min = sizing.min.translate(min_offset);
sizing.preferred = sizing.preferred.translate(offset);

// // Widget size is limited by itself and is not affected by the size of the parent
// if let Some(max_size) = max_size {
// if sizing
// .preferred
// .size()
// .abs_diff_eq(max_size, LAYOUT_TOLERANCE)
// {
// sizing.hints.can_grow = false;
// }
// }

// validate_sizing(entity, &sizing, limits);

cache.insert_query(
args.direction,
CachedValue::new(limits, args.content_area, sizing),
Expand Down Expand Up @@ -497,7 +484,7 @@ pub(crate) fn apply_layout(world: &World, entity: &EntityRef, args: LayoutArgs)
);

Block {
rect: block.rect.pad(&padding),
rect: block.rect.pad(padding),
margin: (block.margin - padding).max(margin),
can_grow: block.can_grow | can_grow,
}
Expand Down
101 changes: 64 additions & 37 deletions violet-core/src/layout/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ use super::{
/// content, as they are their own content)
/// - Centering widgets (this isn't HTML :P)
/// - Limiting and expanding size of widgets
///
/// Margins:
/// By default, the stack layout will inherit the margins of the inner children
#[derive(Default, Debug, Clone)]
pub struct StackLayout {
pub horizontal_alignment: Align,
pub vertical_alignment: Align,
pub contain_margins: bool,
pub clip: BVec2,
}

Expand All @@ -44,11 +48,10 @@ impl StackLayout {
max: Vec2::MIN,
};

let c = vec2(self.clip.x as u32 as f32, self.clip.y as u32 as f32);
let clip = vec2(self.clip.x as u32 as f32, self.clip.y as u32 as f32);
let child_limits = LayoutLimits {
min_size: Vec2::ZERO,
max_size: args.limits.max_size,
// overflow_limit: limits.max_size,
};

let blocks = args
Expand All @@ -57,9 +60,6 @@ impl StackLayout {
.map(|&child| {
let entity = world.entity(child).expect("invalid child");

// let pos = resolve_pos(&entity, content_area, preferred_size);

// tracing::info!(?child_limits, %self.clip, %c, "Applying stack layout");
let block = apply_layout(
world,
&entity,
Expand All @@ -69,36 +69,53 @@ impl StackLayout {
},
);

bounds = bounds.merge(block.rect.translate(args.offset));
let contained_margins = if self.contain_margins {
block.margin
} else {
Edges::ZERO
};

bounds = bounds.merge(
block
.rect
.pad(contained_margins)
.translate(args.offset + contained_margins.topleft()),
);

(entity, block)
})
.collect_vec();

// The size used for alignment calculation
let size = bounds.size().max(args.preferred_size);
// .clamp(limits.min_size, limits.max_size);
let total_size = bounds.size().max(args.preferred_size);

let mut aligned_bounds =
StackableBounds::from_rect(Rect::from_size_pos(args.preferred_size, args.offset));

let mut can_grow = BVec2::FALSE;

let offset = args.offset + resolve_pos(entity, args.content_area, size);
let offset = args.offset + resolve_pos(entity, args.content_area, total_size);

let contain_margins = self.contain_margins as i32 as f32;

for (entity, block) in blocks {
let block_size = block.rect.size();
let contained_margins = block.margin * contain_margins;
let block_size = block.rect.pad(contained_margins).size();

let offset = offset
+ vec2(
self.horizontal_alignment.align_offset(size.x, block_size.x),
self.vertical_alignment.align_offset(size.y, block_size.y),
);
self.horizontal_alignment
.align_offset(total_size.x, block_size.x),
self.vertical_alignment
.align_offset(total_size.y, block_size.y),
)
+ contained_margins.topleft();

let clip_mask = Rect::from_size(c * args.limits.max_size + Vec2::MAX * (1.0 - c));
let clip_mask = Rect::from_size(clip * args.limits.max_size + Vec2::MAX * (1.0 - clip));

aligned_bounds = aligned_bounds.merge(&StackableBounds::new(
block.rect.translate(offset),
block.margin,
block.margin * (1.0 - contain_margins),
));

can_grow |= block.can_grow;
Expand All @@ -109,19 +126,22 @@ impl StackLayout {
.update_dedup(components::local_position(), offset)
.unwrap();

// tracing::info!(%clip_mask, "updating clip mask");

entity
.update_dedup(components::clip_mask(), clip_mask)
.unwrap();
}

// aligned_bounds.inner = aligned_bounds.inner.max_size(limits.min_size);
let mut rect = aligned_bounds.inner.max_size(args.limits.min_size);
let rect = if self.contain_margins {
aligned_bounds.outer
} else {
aligned_bounds.inner
};

let mut rect = rect.max_size(args.limits.min_size);

rect = rect.min_size(args.limits.max_size * c + Vec2::MAX * (1.0 - c));
rect = rect.min_size(args.limits.max_size * clip + Vec2::MAX * (1.0 - clip));

let margin = aligned_bounds.margin();
let margin = aligned_bounds.margin() * (1.0 - contain_margins);

Block::new(rect, margin, can_grow)
}
Expand All @@ -142,7 +162,7 @@ impl StackLayout {
let mut hints = SizingHints::default();
let mut maximize = Vec2::ZERO;

let c = vec2(self.clip.x as u32 as f32, self.clip.y as u32 as f32);
let clip = vec2(self.clip.x as u32 as f32, self.clip.y as u32 as f32);
let child_limits = LayoutLimits {
min_size: Vec2::ZERO,
max_size: args.limits.max_size,
Expand Down Expand Up @@ -171,27 +191,34 @@ impl StackLayout {
preferred_bounds.merge(&StackableBounds::new(sizing.preferred, sizing.margin));
}

let min_rect;
let preferred_rect;
if self.contain_margins {
min_rect = min_bounds.outer;
preferred_rect = preferred_bounds.outer;
} else {
min_rect = min_bounds.inner;
preferred_rect = preferred_bounds.inner;
}

let min_margin = min_bounds.margin();
let preferred_margin = preferred_bounds.margin();

// tracing::info!(%args.limits.max_size);

let min = min_bounds.inner.max_size(args.limits.min_size);
let preferred = preferred_bounds.inner.max_size(preferred_size);
// ensure size is not smaller than min
let min = min_rect.max_size(args.limits.min_size);
let preferred = preferred_rect.max_size(preferred_size);

let clamp_size = args.limits.max_size * c + Vec2::MAX * (1.0 - c);
// let clamp_size = args.limits.max_size;
// if clip, clamp to limited max size, otherwise, clip to max
let clamp_size = args.limits.max_size * clip + Vec2::MAX * (1.0 - clip);

Sizing {
min: min.min_size((1.0 - c) * min.size()),
// min: min.with_size(Vec2::ZERO),
// min: if self.clip {
// min.with_size(Vec2::ZERO)
// } else {
// min.min_size(clamp_size)
// },
min: min.min_size((1.0 - clip) * min.size()),
preferred: preferred.min_size(clamp_size),
margin: min_margin.max(preferred_margin),
margin: if self.contain_margins {
Edges::ZERO
} else {
min_margin.max(preferred_margin)
},
hints,
maximize,
}
Expand Down Expand Up @@ -223,7 +250,7 @@ impl StackableBounds {
fn new(rect: Rect, margin: Edges) -> Self {
Self {
inner: rect,
outer: rect.pad(&margin),
outer: rect.pad(margin),
}
}

Expand Down
Loading

0 comments on commit b2a3106

Please sign in to comment.