Skip to content
Draft
1 change: 1 addition & 0 deletions crates/core/src/dom/dom_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ impl DOMAdapter<NodeId> for DioxusDOMAdapter<'_> {
content: layout.content,
contains_text,
spacing: layout.spacing,
grid_position: layout.grid_position,
};

node.scale_if_needed(self.scale_factor);
Expand Down
74 changes: 71 additions & 3 deletions crates/core/src/states/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ pub struct LayoutState {
pub content: Content,
pub node_ref: Option<NodeReference>,
pub node_id: NodeId,
pub spacing: Length,
pub spacing: Size2D,
pub grid_position: GridPosition,
}

impl ParseAttribute for LayoutState {
Expand Down Expand Up @@ -173,7 +174,61 @@ impl ParseAttribute for LayoutState {
}
AttributeName::Content => {
if let Some(value) = attr.value.as_text() {
self.content = Content::parse(value)?;
let value = Content::parse(value)?;

if !self.content.is_same_type(&value) {
self.content = value;
}
}
}
AttributeName::GridColumns => {
if let Some(value) = attr.value.as_text() {
let values = value
.split(",")
.map(|value| GridSize::parse(value.trim()))
.collect::<Result<_, ParseError>>()?;

self.content.set_columns(values);
}
}
AttributeName::GridRows => {
if let Some(value) = attr.value.as_text() {
let values = value
.split(",")
.map(|value| GridSize::parse(value.trim()))
.collect::<Result<_, ParseError>>()?;

self.content.set_rows(values);
}
}
AttributeName::GridColumn => {
if let Some(value) = attr.value.as_text() {
let value = value
.split("/")
.map(|value| value.trim().parse().map_err(|_| ParseError))
.collect::<Result<Vec<_>, ParseError>>()?;

if value.len() == 2 {
self.grid_position.column = value[0];
self.grid_position.column_span = value[1];
} else if value.len() == 1 {
self.grid_position.column = value[0];
}
}
}
AttributeName::GridRow => {
if let Some(value) = attr.value.as_text() {
let value = value
.split("/")
.map(|value| value.trim().parse().map_err(|_| ParseError))
.collect::<Result<Vec<_>, ParseError>>()?;

if value.len() == 2 {
self.grid_position.row = value[0];
self.grid_position.row_span = value[1];
} else if value.len() == 1 {
self.grid_position.row = value[0];
}
}
}
AttributeName::Reference => {
Expand All @@ -185,7 +240,16 @@ impl ParseAttribute for LayoutState {
}
AttributeName::Spacing => {
if let Some(value) = attr.value.as_text() {
self.spacing = Length::new(value.parse::<f32>().map_err(|_| ParseError)?);
let value = value
.split(" ")
.map(|value| value.trim().parse().map_err(|_| ParseError))
.collect::<Result<Vec<_>, ParseError>>()?;

if value.len() == 2 {
self.spacing = Size2D::new(value[0], value[1]);
} else if value.len() == 1 {
self.spacing = Size2D::new(value[0], value[0]);
}
}
}
_ => {}
Expand Down Expand Up @@ -226,6 +290,10 @@ impl State<CustomAttributeValues> for LayoutState {
AttributeName::PositionBottom,
AttributeName::PositionLeft,
AttributeName::Content,
AttributeName::GridColumns,
AttributeName::GridRows,
AttributeName::GridColumn,
AttributeName::GridRow,
AttributeName::Spacing,
]));

Expand Down
1 change: 1 addition & 0 deletions crates/core/src/values/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ impl Parse for Content {
Ok(match value {
"fit" => Content::Fit,
"flex" => Content::Flex,
"grid" => Content::new_grid(),
_ => Content::Normal,
})
}
Expand Down
25 changes: 25 additions & 0 deletions crates/core/src/values/grid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use torin::prelude::{
GridSize,
Length,
};

use crate::parsing::{
Parse,
ParseError,
};

impl Parse for GridSize {
fn parse(value: &str) -> Result<Self, ParseError> {
if value == "auto" {
Ok(Self::Inner)
} else if value.ends_with('w') {
Ok(Self::Weight(Length::new(
value.replace('w', "").parse().map_err(|_| ParseError)?,
)))
} else {
Ok(Self::Pixels(Length::new(
value.parse().map_err(|_| ParseError)?,
)))
}
}
}
1 change: 1 addition & 0 deletions crates/core/src/values/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod focusable;
mod font;
mod gaps;
mod gradient;
mod grid;
mod highlight;
mod image_cover;
mod overflow;
Expand Down
70 changes: 69 additions & 1 deletion crates/elements/src/attributes/layout_attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def_attribute!(
/// ```
min_width,

//// Specify a minimum width for the given element.
/// Specify a minimum width for the given element.
/// This can be useful if you use it alongside a percentage for the target size.
///
/// See syntax for [`Size Units`](crate::_docs::size_unit).
Expand Down Expand Up @@ -290,6 +290,7 @@ def_attribute!(
/// - `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.
/// - `grid`: Marks the container as grid container, children of this element will be able to use `grid_column` and `grid_row` attributes.
///
///
/// ### `fit`
Expand Down Expand Up @@ -327,7 +328,74 @@ def_attribute!(
/// )
/// }
/// ```
///
/// ### `grid`
///
/// The `grid` mode will allow you to line up the internal elements in a grid.
/// Columns and rows are specified via `grid_columns` and `grid_rows` attributes.
/// An element in `grid` mode can also specify different `spacing` for columns
/// and rows.
///
/// ```rust, no_run
/// # use freya::prelude::*;
/// fn app() -> Element {
/// rsx!(
/// rect {
/// spacing: "8 12",
/// content: "grid",
/// grid_columns: "100, 1w, 1w",
/// grid_rows: "1w",
/// width: "600",
/// height: "600",
/// rect {
/// width: "fill",
/// height: "fill",
/// grid_column: "0 / 1", // Will have a width of 100px
/// background: "red",
/// }
/// rect {
/// width: "fill",
/// height: "fill",
/// grid_column: "1 / 1", // Will have a width of 250px
/// background: "green",
/// }
/// rect {
/// width: "fill-min",
/// height: "fill",
/// grid_column: "2 / 1", // Will have a width of 250px
/// background: "blue",
/// }
/// }
/// )
/// }
/// ```
content,
/// Specify a comma-separated list of column sizes.
///
/// Accepted values:
///
/// - `auto`: The size of the column will be based on the sizes of the elements
/// bound to it (however, only elements with `column_span` equal to 1 are used
/// in the size calculation)
/// - `100` (pixels): The size of the column will be a fixed number of pixels
/// - `1w` (weight): The size of the column will be a fraction of the remaining
/// free space (using the formula `weight * ((size - pixel_columns_size -
/// auto_columns_size) / weights_columns_sum)`)
grid_columns,
/// Specify a comma-separated list of row sizes.
///
/// Accepted values:
///
/// - `auto`: The size of the row will be based on the sizes of the elements
/// bound to it (however, only elements with `row_span` equal to 1 are used
/// in the size calculation)
/// - `100` (pixels): The size of the row will be a fixed number of pixels
/// - `1w` (weight): The size of the row will be a fraction of the remaining
/// free space (using the formula `weight * ((size - pixel_rows_size -
/// auto_rows_size) / weights_rows_sum)`)
grid_rows,
grid_column,
grid_row,

/// ### main_align & cross_align
///
Expand Down
4 changes: 4 additions & 0 deletions crates/elements/src/elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def_element!(
// Children layout
direction,
content,
grid_columns,
grid_rows,
grid_column,
grid_row,
main_align,
cross_align,
spacing,
Expand Down
8 changes: 8 additions & 0 deletions crates/native-core/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub enum AttributeName {
PositionLeft,
Opacity,
Content,
GridColumns,
GridRows,
GridColumn,
GridRow,
CanvasReference,
Layer,
OffsetY,
Expand Down Expand Up @@ -282,6 +286,10 @@ impl FromStr for AttributeName {
"position_left" => Ok(AttributeName::PositionLeft),
"opacity" => Ok(AttributeName::Opacity),
"content" => Ok(AttributeName::Content),
"grid_columns" => Ok(AttributeName::GridColumns),
"grid_rows" => Ok(AttributeName::GridRows),
"grid_column" => Ok(AttributeName::GridColumn),
"grid_row" => Ok(AttributeName::GridRow),
"canvas_reference" => Ok(AttributeName::CanvasReference),
"layer" => Ok(AttributeName::Layer),
"offset_y" => Ok(AttributeName::OffsetY),
Expand Down
Loading
Loading