Skip to content

Commit

Permalink
Merge branch 'main' into feat/parenthesis
Browse files Browse the repository at this point in the history
  • Loading branch information
marc2332 authored Nov 10, 2024
2 parents de81825 + 00ca902 commit e943c00
Show file tree
Hide file tree
Showing 15 changed files with 583 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ If you are interested in supporting the development of this project feel free to

Thanks to my sponsors for supporting this project! 😄

<!-- sponsors --><a href="https://github.com/piny4man"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;8446285?u&#x3D;fd37db4dd9b4ba94dabe0bccc3a95ef2a35376ab&amp;v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/gqf2008"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;2295878?v&#x3D;4" width="60px" alt="高庆丰" /></a><!-- sponsors -->
<!-- sponsors --><a href="https://github.com/piny4man"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;8446285?u&#x3D;fd37db4dd9b4ba94dabe0bccc3a95ef2a35376ab&amp;v&#x3D;4" width="60px" alt="" /></a><a href="https://github.com/gqf2008"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;2295878?v&#x3D;4" width="60px" alt="高庆丰" /></a><a href="https://github.com/lino-levan"><img src="https:&#x2F;&#x2F;avatars.githubusercontent.com&#x2F;u&#x2F;11367844?v&#x3D;4" width="60px" alt="Lino Le Van" /></a><!-- sponsors -->

### Special thanks 💪

Expand Down
3 changes: 2 additions & 1 deletion crates/core/src/elements/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ pub trait ElementUtils {
}
}

Some(drawing_area)
// Inflate the area by 1px in each side to cover potential off-bounds rendering caused by antialising
Some(drawing_area.inflate(1.0, 1.0))
}

/// Measure the area for this element considering other
Expand Down
5 changes: 4 additions & 1 deletion crates/core/src/render/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,13 +367,15 @@ mod test {
height: "100",
width: "200",
background: "red",
margin: "0 0 2 0",
onclick: move |_| height += 10,
}
rect {
height: "{height}",
width: "200",
background: "green",
shadow: "0 {shadow} 8 0 rgb(0, 0, 0, 0.5)",
margin: "0 0 2 0",
onclick: move |_| height -= 10,
}
rect {
Expand Down Expand Up @@ -418,7 +420,7 @@ mod test {

let (_, _, painted_nodes) = run_compositor(&utils, &mut compositor);

// Root + First + Second rect + Third rect
// Root + First rect + Second rect + Third Rect
assert_eq!(painted_nodes, 4);
}

Expand All @@ -440,6 +442,7 @@ mod test {
height: "200",
width: "200",
direction: "horizontal",
spacing: "2",
rect {
onclick: move |_| msg_state.toggle(),
height: "200",
Expand Down
6 changes: 4 additions & 2 deletions crates/elements/src/_docs/attributes/content.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ Accepted values:

- `normal` (default): Uses parent bounds.
- `fit`: Uses parent bounds but later shrunks to the size of the biggest element inside.
- `flex`: Marks the container as flex container, children of this element will be able to use `size`/`size(n)` in their `width` and `height` attributes.

The `fit` mode will allow the inner elements using `width: fill-min` to expand to the biggest element inside this element.

### Example
### `fit`

The `fit` mode will allow the inner elements using `width: fill-min` to expand to the biggest element inside this element.

```rust, no_run
# use freya::prelude::*;
Expand Down
27 changes: 27 additions & 0 deletions crates/elements/src/_docs/size_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,30 @@
//! )
//! }
//! ```
//!
//! #### Flex Factor
//!
//! When being a children of an element with `content: flex` you may change the growth factor of the size attributes.
//!
//! ```rust, no_run
//! # use freya::prelude::*;
//! fn app() -> Element {
//! rsx!(
//! rect {
//! content: "flex",
//! width: "200",
//! height: "200",
//! rect {
//! height: "flex(1)",
//! width: "100%",
//! background: "red"
//! }
//! rect {
//! height: "flex(3)",
//! width: "100%",
//! background: "blue"
//! }
//! }
//! )
//! }
//! ```
1 change: 1 addition & 0 deletions crates/state/src/values/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ impl Parse for Content {
fn parse(value: &str) -> Result<Self, ParseError> {
Ok(match value {
"fit" => Content::Fit,
"flex" => Content::Flex,
_ => Content::Normal,
})
}
Expand Down
10 changes: 10 additions & 0 deletions crates/state/src/values/size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ impl Parse for Size {
fn parse(value: &str) -> Result<Self, ParseError> {
if value == "auto" {
Ok(Size::Inner)
} else if value == "flex" {
Ok(Size::Flex(Length::new(1.0)))
} else if value.contains("flex") {
Ok(Size::Flex(Length::new(
value
.replace("flex(", "")
.replace(')', "")
.parse::<f32>()
.map_err(|_| ParseError)?,
)))
} else if value == "fill" {
Ok(Size::Fill)
} else if value == "fill-min" {
Expand Down
1 change: 1 addition & 0 deletions crates/testing/src/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub fn launch_test_with_config<T: 'static + Clone>(
};

handler.init_dom();
handler.resize(handler.config.size);

handler
}
Expand Down
5 changes: 5 additions & 0 deletions crates/testing/src/test_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@ impl<T: 'static + Clone> TestingHandler<T> {
state.information.viewport_size = size;
});
self.utils.sdom().get_mut().layout().reset();
self.utils
.sdom()
.get_mut()
.compositor_dirty_area()
.unite_or_insert(&Area::new((0.0, 0.0).into(), size));
}

/// Get the current [CursorIcon].
Expand Down
111 changes: 99 additions & 12 deletions crates/torin/src/measure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{
AreaModel,
DirectionMode,
LayoutMetadata,
Length,
Torin,
},
};
Expand Down Expand Up @@ -308,8 +309,9 @@ where
) {
let children = self.dom_adapter.children_of(parent_node_id);

let mut initial_phase_flex_grows = FxHashMap::default();
let mut initial_phase_sizes = FxHashMap::default();
let mut initial_phase_inner_sizes = *inner_sizes;
let mut initial_phase_inner_sizes = Size2D::default();

// Used to calculate the spacing and some alignments
let (non_absolute_children_len, first_child, last_child) = if parent_node.spacing.get() > 0.
Expand Down Expand Up @@ -342,16 +344,18 @@ where
)
};

// Initial phase: Measure the size and position of the children if the parent has a
// non-start cross alignment, non-start main aligment of a fit-content.
if parent_node.cross_alignment.is_not_start()
let needs_initial_phase = parent_node.cross_alignment.is_not_start()
|| parent_node.main_alignment.is_not_start()
|| parent_node.content.is_fit()
{
let mut initial_phase_area = *area;
let mut initial_phase_inner_area = *inner_area;
let mut initial_phase_available_area = *available_area;
|| parent_node.content.is_flex();

let mut initial_phase_area = *area;
let mut initial_phase_inner_area = *inner_area;
let mut initial_phase_available_area = *available_area;

// Initial phase: Measure the size and position of the children if the parent has a
// non-start cross alignment, non-start main aligment of a fit-content.
if needs_initial_phase {
// Measure the children
for child_id in children.iter() {
let Some(child_data) = self.dom_adapter.get_node(child_id) else {
Expand Down Expand Up @@ -382,20 +386,74 @@ where
Self::stack_child(
&mut initial_phase_available_area,
parent_node,
&child_data,
&mut initial_phase_area,
&mut initial_phase_inner_area,
&mut initial_phase_inner_sizes,
&child_areas.area,
is_last_child,
Phase::Initial,
);

if parent_node.cross_alignment.is_not_start()
|| parent_node.main_alignment.is_spaced()
{
initial_phase_sizes.insert(*child_id, child_areas.area.size);
}

if parent_node.content.is_flex() {
match parent_node.direction {
DirectionMode::Vertical => {
if let Some(ff) = child_data.height.flex_grow() {
initial_phase_flex_grows.insert(*child_id, ff);
}
}
DirectionMode::Horizontal => {
if let Some(ff) = child_data.width.flex_grow() {
initial_phase_flex_grows.insert(*child_id, ff);
}
}
}
}
}
}

let initial_available_area = *available_area;

let flex_grows = initial_phase_flex_grows
.values()
.cloned()
.reduce(|acc, v| acc + v)
.unwrap_or_default()
.max(Length::new(1.0));

let flex_axis = AlignAxis::new(&parent_node.direction, AlignmentDirection::Main);

let flex_available_width = initial_available_area.width() - initial_phase_inner_sizes.width;
let flex_available_height =
initial_available_area.height() - initial_phase_inner_sizes.height;

let initial_phase_inner_sizes_with_flex =
initial_phase_flex_grows
.values()
.fold(initial_phase_inner_sizes, |mut acc, f| {
let flex_grow_per = f.get() / flex_grows.get() * 100.;

match flex_axis {
AlignAxis::Height => {
let size = flex_available_height / 100. * flex_grow_per;
acc.height += size;
}
AlignAxis::Width => {
let size = flex_available_width / 100. * flex_grow_per;
acc.width += size;
}
}

acc
});

if needs_initial_phase {
if parent_node.main_alignment.is_not_start() {
// Adjust the available and inner areas of the Main axis
Self::shrink_area_to_fit_when_unbounded(
Expand All @@ -410,7 +468,7 @@ where
Self::align_content(
available_area,
&initial_phase_inner_area,
&initial_phase_inner_sizes,
&initial_phase_inner_sizes_with_flex,
&parent_node.main_alignment,
&parent_node.direction,
AlignmentDirection::Main,
Expand Down Expand Up @@ -442,14 +500,33 @@ where

let mut adapted_available_area = *available_area;

if parent_node.content.is_flex() {
let flex_grow = initial_phase_flex_grows.get(&child_id);

if let Some(flex_grow) = flex_grow {
let flex_grow_per = flex_grow.get() / flex_grows.get() * 100.;

match flex_axis {
AlignAxis::Height => {
let size = flex_available_height / 100. * flex_grow_per;
adapted_available_area.size.height = size;
}
AlignAxis::Width => {
let size = flex_available_width / 100. * flex_grow_per;
adapted_available_area.size.width = size;
}
}
}
}

// Only the stacked children will be aligned
if parent_node.main_alignment.is_spaced() && !child_data.position.is_absolute() {
// Align the Main axis if necessary
Self::align_position(
AlignmentDirection::Main,
&mut adapted_available_area,
&initial_available_area,
&initial_phase_inner_sizes,
&initial_phase_inner_sizes_with_flex,
&parent_node.main_alignment,
&parent_node.direction,
non_absolute_children_len,
Expand Down Expand Up @@ -492,11 +569,13 @@ where
Self::stack_child(
available_area,
parent_node,
&child_data,
area,
inner_area,
inner_sizes,
&child_areas.area,
is_last_child,
Phase::Final,
);
}

Expand Down Expand Up @@ -612,11 +691,13 @@ where
fn stack_child(
available_area: &mut Area,
parent_node: &Node,
child_node: &Node,
parent_area: &mut Area,
inner_area: &mut Area,
inner_sizes: &mut Size2D,
child_area: &Area,
is_last_sibiling: bool,
phase: Phase,
) {
// Only apply the spacing to elements after `i > 0` and `i < len - 1`
let spacing = (!is_last_sibiling)
Expand All @@ -630,7 +711,10 @@ where
available_area.size.width -= child_area.size.width + spacing.get();

inner_sizes.height = child_area.height().max(inner_sizes.height);
inner_sizes.width += child_area.width() + spacing.get();
inner_sizes.width += spacing.get();
if !child_node.width.is_flex() || phase == Phase::Final {
inner_sizes.width += child_area.width();
}

// Keep the biggest height
if parent_node.height.inner_sized() {
Expand All @@ -656,7 +740,10 @@ where
available_area.size.height -= child_area.size.height + spacing.get();

inner_sizes.width = child_area.width().max(inner_sizes.width);
inner_sizes.height += child_area.height() + spacing.get();
inner_sizes.height += spacing.get();
if !child_node.height.is_flex() || phase == Phase::Final {
inner_sizes.height += child_area.height();
}

// Keep the biggest width
if parent_node.width.inner_sized() {
Expand Down
6 changes: 6 additions & 0 deletions crates/torin/src/values/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,25 @@ pub enum Content {
#[default]
Normal,
Fit,
Flex,
}

impl Content {
pub fn is_fit(&self) -> bool {
self == &Self::Fit
}

pub fn is_flex(&self) -> bool {
self == &Self::Flex
}
}

impl Content {
pub fn pretty(&self) -> String {
match self {
Self::Normal => "normal".to_owned(),
Self::Fit => "fit".to_owned(),
Self::Flex => "flex".to_owned(),
}
}
}
Loading

0 comments on commit e943c00

Please sign in to comment.