diff --git a/crates/dc_bundle/src/definition/layout.rs b/crates/dc_bundle/src/definition/layout.rs index 458ce920c..c5b98f0e1 100644 --- a/crates/dc_bundle/src/definition/layout.rs +++ b/crates/dc_bundle/src/definition/layout.rs @@ -13,5 +13,63 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +use crate::definition::element::{DimensionProto, DimensionRect, Size}; +use crate::definition::layout::item_spacing::ItemSpacingType; +use crate::Error; +use crate::Error::MissingFieldError; include!(concat!(env!("OUT_DIR"), "/designcompose.definition.layout.rs")); + +impl ItemSpacing { + pub fn new_default() -> Option { + Some(Self { item_spacing_type: Some(ItemSpacingType::Fixed(0)) }) + } +} + +impl LayoutStyle { + pub fn bounding_box(&self) -> Result<&Size, Error> { + self.bounding_box.as_ref().ok_or(MissingFieldError { field: "bounding_box".to_string() }) + } + + pub(crate) fn new_default() -> LayoutStyle { + LayoutStyle { + margin: DimensionRect::new(), + padding: DimensionRect::new(), + item_spacing: ItemSpacing::new_default(), + top: DimensionProto::new_undefined(), + left: DimensionProto::new_undefined(), + bottom: DimensionProto::new_undefined(), + right: DimensionProto::new_undefined(), + width: DimensionProto::new_undefined(), + height: DimensionProto::new_undefined(), + min_width: DimensionProto::new_undefined(), + max_width: DimensionProto::new_undefined(), + min_height: DimensionProto::new_undefined(), + max_height: DimensionProto::new_undefined(), + bounding_box: Some(Size::default()), + flex_grow: 0.0, + flex_shrink: 0.0, + flex_basis: DimensionProto::new_undefined(), + align_self: AlignSelf::Auto.into(), + align_content: AlignContent::Stretch.into(), + align_items: AlignItems::Stretch.into(), + flex_direction: FlexDirection::Row.into(), + justify_content: JustifyContent::FlexStart.into(), + position_type: PositionType::Relative.into(), + } + } +} + +impl ItemSpacing { + pub fn fixed(value: i32) -> Self { + Self { item_spacing_type: Some(item_spacing::ItemSpacingType::Fixed(value)) } + } + pub fn auto(width: i32, height: i32) -> Self { + Self { + item_spacing_type: Some(item_spacing::ItemSpacingType::Auto(item_spacing::Auto { + width, + height, + })), + } + } +} diff --git a/crates/dc_bundle/src/legacy_definition.rs b/crates/dc_bundle/src/legacy_definition.rs index 2c34b37c5..d7832432e 100644 --- a/crates/dc_bundle/src/legacy_definition.rs +++ b/crates/dc_bundle/src/legacy_definition.rs @@ -23,13 +23,11 @@ use std::sync::Arc; // To help keep the legacy definition files clear we alias `crate::definition`, which is the base // module for the generated protobuf files to `proto`, so that all of the protobuf-generated types // inside `legacy_definition` must be prepended with `proto::` -pub(crate) use crate::definition as proto; use crate::definition::element::ImageKey; use crate::definition::element::VariableMap; use crate::legacy_definition::element::node::NodeQuery; pub mod element; -pub mod layout; pub mod plugin; pub mod view; diff --git a/crates/dc_bundle/src/legacy_definition/layout.rs b/crates/dc_bundle/src/legacy_definition/layout.rs deleted file mode 100644 index 86097249e..000000000 --- a/crates/dc_bundle/src/legacy_definition/layout.rs +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -pub mod layout_style; -pub mod positioning; diff --git a/crates/dc_bundle/src/legacy_definition/layout/layout_style.rs b/crates/dc_bundle/src/legacy_definition/layout/layout_style.rs deleted file mode 100644 index 00843c522..000000000 --- a/crates/dc_bundle/src/legacy_definition/layout/layout_style.rs +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -use crate::definition::element::{DimensionProto, DimensionRect, Size}; -use crate::legacy_definition::layout::positioning::{ - AlignContent, AlignItems, AlignSelf, FlexDirection, ItemSpacing, JustifyContent, PositionType, -}; -use crate::legacy_definition::proto; -use crate::Error; -use crate::Error::MissingFieldError; -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub struct LayoutStyle { - pub margin: Option, - pub padding: Option, - pub item_spacing: ItemSpacing, - pub top: Option, - pub left: Option, - pub bottom: Option, - pub right: Option, - pub width: Option, - pub height: Option, - pub min_width: Option, - pub max_width: Option, - pub min_height: Option, - pub max_height: Option, - pub bounding_box: Size, - pub flex_grow: f32, - pub flex_shrink: f32, - pub flex_basis: Option, - pub align_self: AlignSelf, - pub align_content: AlignContent, - pub align_items: AlignItems, - pub flex_direction: FlexDirection, - pub justify_content: JustifyContent, - pub position_type: PositionType, -} - -impl Default for LayoutStyle { - fn default() -> LayoutStyle { - LayoutStyle { - margin: (DimensionRect::new()), - padding: (DimensionRect::new()), - item_spacing: ItemSpacing::default(), - top: DimensionProto::new_undefined(), - left: DimensionProto::new_undefined(), - bottom: DimensionProto::new_undefined(), - right: DimensionProto::new_undefined(), - width: DimensionProto::new_undefined(), - height: DimensionProto::new_undefined(), - min_width: DimensionProto::new_undefined(), - max_width: DimensionProto::new_undefined(), - min_height: DimensionProto::new_undefined(), - max_height: DimensionProto::new_undefined(), - bounding_box: Size::default(), - flex_grow: 0.0, - flex_shrink: 0.0, - flex_basis: DimensionProto::new_undefined(), - align_self: AlignSelf::Auto, - align_content: AlignContent::Stretch, - align_items: AlignItems::Stretch, - flex_direction: FlexDirection::Row, - justify_content: JustifyContent::FlexStart, - position_type: PositionType::Relative, - } - } -} - -impl TryFrom for LayoutStyle { - type Error = Error; - - fn try_from(proto: proto::layout::LayoutStyle) -> Result { - let layout_style = LayoutStyle { - margin: proto.margin.clone(), - padding: proto.padding.clone(), - item_spacing: proto - .item_spacing - .clone() - .ok_or(MissingFieldError { field: "item_spacing".to_string() })? - .try_into()?, - top: proto.top, - left: proto.left, - right: proto.right, - bottom: proto.bottom, - width: proto.width, - height: proto.height, - min_width: proto.min_width, - min_height: proto.min_height, - max_width: proto.max_width, - max_height: proto.max_height, - bounding_box: proto - .bounding_box - .clone() - .ok_or(MissingFieldError { field: "bounding_box".to_string() })? - .into(), - flex_grow: proto.flex_grow, - flex_shrink: proto.flex_shrink, - flex_basis: proto.flex_basis, - align_self: proto.align_self().try_into()?, - align_content: proto.align_content().try_into()?, - align_items: proto.align_items().try_into()?, - flex_direction: proto.flex_direction().try_into()?, - justify_content: proto.justify_content().try_into()?, - position_type: proto.position_type().try_into()?, - }; - Ok(layout_style) - } -} diff --git a/crates/dc_bundle/src/legacy_definition/layout/positioning.rs b/crates/dc_bundle/src/legacy_definition/layout/positioning.rs deleted file mode 100644 index 2712d53d1..000000000 --- a/crates/dc_bundle/src/legacy_definition/layout/positioning.rs +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright 2024 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -use serde::{Deserialize, Serialize}; - -use crate::legacy_definition::proto; -use crate::Error; - -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)] -pub enum AlignItems { - FlexStart, - FlexEnd, - Center, - Baseline, - Stretch, -} - -impl Default for AlignItems { - fn default() -> Self { - Self::Stretch - } -} - -impl TryFrom for AlignItems { - type Error = Error; - fn try_from(proto: proto::layout::AlignItems) -> Result { - match proto { - proto::layout::AlignItems::FlexStart => Ok(AlignItems::FlexStart), - proto::layout::AlignItems::FlexEnd => Ok(AlignItems::FlexEnd), - proto::layout::AlignItems::Center => Ok(AlignItems::Center), - proto::layout::AlignItems::Baseline => Ok(AlignItems::Baseline), - proto::layout::AlignItems::Stretch => Ok(AlignItems::Stretch), - _ => Err(Error::UnknownEnumVariant { enum_name: "AlignItems".to_string() }), - } - } -} - -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)] -pub enum AlignSelf { - Auto, - FlexStart, - FlexEnd, - Center, - Baseline, - Stretch, -} - -impl Default for AlignSelf { - fn default() -> Self { - Self::Auto - } -} - -impl TryFrom for AlignSelf { - type Error = Error; - - fn try_from(proto: proto::layout::AlignSelf) -> Result { - match proto { - proto::layout::AlignSelf::Auto => Ok(AlignSelf::Auto), - proto::layout::AlignSelf::FlexStart => Ok(AlignSelf::FlexStart), - proto::layout::AlignSelf::FlexEnd => Ok(AlignSelf::FlexEnd), - proto::layout::AlignSelf::Center => Ok(AlignSelf::Center), - proto::layout::AlignSelf::Baseline => Ok(AlignSelf::Baseline), - proto::layout::AlignSelf::Stretch => Ok(AlignSelf::Stretch), - _ => Err(Error::UnknownEnumVariant { enum_name: "AlignSelf".to_string() }), - } - } -} - -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)] -pub enum AlignContent { - FlexStart, - FlexEnd, - Center, - Stretch, - SpaceBetween, - SpaceAround, -} - -impl Default for AlignContent { - fn default() -> Self { - Self::Stretch - } -} - -impl TryFrom for AlignContent { - type Error = Error; - - fn try_from(proto: proto::layout::AlignContent) -> Result { - match proto { - proto::layout::AlignContent::Center => Ok(AlignContent::Center), - proto::layout::AlignContent::FlexStart => Ok(AlignContent::FlexStart), - proto::layout::AlignContent::FlexEnd => Ok(AlignContent::FlexEnd), - proto::layout::AlignContent::Stretch => Ok(AlignContent::Stretch), - proto::layout::AlignContent::SpaceBetween => Ok(AlignContent::SpaceBetween), - proto::layout::AlignContent::SpaceAround => Ok(AlignContent::SpaceAround), - _ => Err(Error::UnknownEnumVariant { enum_name: "AlignContent".to_string() }), - } - } -} - -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)] -pub enum FlexDirection { - Row, - Column, - RowReverse, - ColumnReverse, - None, -} - -impl Default for FlexDirection { - fn default() -> Self { - Self::Row - } -} - -impl TryFrom for FlexDirection { - type Error = Error; - - fn try_from(proto: proto::layout::FlexDirection) -> Result { - match proto { - proto::layout::FlexDirection::Row => Ok(FlexDirection::Row), - proto::layout::FlexDirection::Column => Ok(FlexDirection::Column), - proto::layout::FlexDirection::RowReverse => Ok(FlexDirection::RowReverse), - proto::layout::FlexDirection::ColumnReverse => Ok(FlexDirection::ColumnReverse), - proto::layout::FlexDirection::None => Ok(FlexDirection::None), - _ => Err(Error::UnknownEnumVariant { enum_name: "FlexDirection".to_string() }), - } - } -} - -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)] -pub enum JustifyContent { - FlexStart, - FlexEnd, - Center, - SpaceBetween, - SpaceAround, - SpaceEvenly, -} - -impl Default for JustifyContent { - fn default() -> Self { - Self::FlexStart - } -} - -impl TryFrom for JustifyContent { - type Error = Error; - - fn try_from(proto: proto::layout::JustifyContent) -> Result { - match proto { - proto::layout::JustifyContent::FlexStart => Ok(JustifyContent::FlexStart), - proto::layout::JustifyContent::FlexEnd => Ok(JustifyContent::FlexEnd), - proto::layout::JustifyContent::Center => Ok(JustifyContent::Center), - proto::layout::JustifyContent::SpaceBetween => Ok(JustifyContent::SpaceBetween), - proto::layout::JustifyContent::SpaceAround => Ok(JustifyContent::SpaceAround), - proto::layout::JustifyContent::SpaceEvenly => Ok(JustifyContent::SpaceEvenly), - _ => Err(Error::UnknownEnumVariant { enum_name: "JustifyContent".to_string() }), - } - } -} - -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)] -pub enum PositionType { - Relative, - Absolute, -} - -impl Default for PositionType { - fn default() -> Self { - Self::Relative - } -} - -impl TryFrom for PositionType { - type Error = Error; - - fn try_from(proto: proto::layout::PositionType) -> Result { - match proto { - proto::layout::PositionType::Relative => Ok(PositionType::Relative), - proto::layout::PositionType::Absolute => Ok(PositionType::Absolute), - _ => Err(Error::UnknownEnumVariant { enum_name: "PositionType".to_string() }), - } - } -} - -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] -pub enum ItemSpacing { - Fixed(i32), - // Fixed space between columns/rows - Auto(i32, i32), // Min space between columns/rows, item width/height -} - -impl Default for ItemSpacing { - fn default() -> Self { - ItemSpacing::Fixed(0) - } -} - -impl TryFrom for ItemSpacing { - type Error = Error; - - fn try_from(proto: proto::layout::ItemSpacing) -> Result { - match proto - .r#type - .as_ref() - .ok_or(Error::MissingFieldError { field: "ItemSpacing".to_string() })? - { - proto::layout::item_spacing::Type::Fixed(s) => Ok(ItemSpacing::Fixed(*s)), - proto::layout::item_spacing::Type::Auto(s) => Ok(ItemSpacing::Auto(s.width, s.height)), - } - } -} - -#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq)] -#[serde(rename_all = "SCREAMING_SNAKE_CASE")] -#[derive(Default)] -pub enum OverflowDirection { - #[default] - None, - HorizontalScrolling, - VerticalScrolling, - HorizontalAndVerticalScrolling, -} - -#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)] -pub enum Overflow { - Visible, - Hidden, - Scroll, -} - -impl Default for Overflow { - fn default() -> Self { - Self::Visible - } -} - -#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Default, Copy)] -#[serde(rename_all = "SCREAMING_SNAKE_CASE")] -pub enum LayoutSizing { - #[default] - Fixed, - Hug, - Fill, -} diff --git a/crates/dc_bundle/src/legacy_definition/view/node_style.rs b/crates/dc_bundle/src/legacy_definition/view/node_style.rs index b6138b7b2..2c2bc33b8 100644 --- a/crates/dc_bundle/src/legacy_definition/view/node_style.rs +++ b/crates/dc_bundle/src/legacy_definition/view/node_style.rs @@ -22,12 +22,11 @@ use crate::definition::element::{ }; use crate::definition::element::{Background, FontStretch, FontWeight}; use crate::definition::interaction::PointerEvents; -use crate::definition::layout::{FlexWrap, GridLayoutType, GridSpan}; +use crate::definition::layout::{FlexWrap, GridLayoutType, GridSpan, LayoutSizing, Overflow}; use crate::definition::modifier::{ BlendMode, FilterOp, TextAlign, TextAlignVertical, TextOverflow, }; use crate::definition::modifier::{BoxShadow, LayoutTransform, TextShadow}; -use crate::legacy_definition::layout::positioning::{LayoutSizing, Overflow}; use crate::legacy_definition::plugin::meter_data::MeterData; use serde::{Deserialize, Serialize}; @@ -141,13 +140,13 @@ impl Default for NodeStyle { grid_columns_rows: 0, grid_adaptive_min_size: 1, grid_span_content: vec![], - overflow: Overflow::default(), + overflow: Overflow::Visible, max_children: None, overflow_node_id: None, overflow_node_name: None, cross_axis_item_spacing: 0.0, - horizontal_sizing: LayoutSizing::default(), - vertical_sizing: LayoutSizing::default(), + horizontal_sizing: LayoutSizing::Fixed, + vertical_sizing: LayoutSizing::Fixed, aspect_ratio: Number::default(), pointer_events: PointerEvents::Inherit, meter_data: None, diff --git a/crates/dc_bundle/src/legacy_definition/view/view.rs b/crates/dc_bundle/src/legacy_definition/view/view.rs index 491b95981..60b15305c 100644 --- a/crates/dc_bundle/src/legacy_definition/view/view.rs +++ b/crates/dc_bundle/src/legacy_definition/view/view.rs @@ -16,8 +16,8 @@ use crate::definition::element::{Rectangle, ViewShape}; use crate::definition::interaction::Reaction; +use crate::definition::layout::OverflowDirection; use crate::definition::plugin::FrameExtras; -use crate::legacy_definition::layout::positioning::OverflowDirection; use crate::legacy_definition::view::component::ComponentInfo; use crate::legacy_definition::view::text_style::StyledTextRun; use crate::legacy_definition::view::view_style::ViewStyle; diff --git a/crates/dc_bundle/src/legacy_definition/view/view_style.rs b/crates/dc_bundle/src/legacy_definition/view/view_style.rs index e27fba822..2fdbd2794 100644 --- a/crates/dc_bundle/src/legacy_definition/view/view_style.rs +++ b/crates/dc_bundle/src/legacy_definition/view/view_style.rs @@ -14,16 +14,22 @@ * limitations under the License. */ -use crate::legacy_definition::layout::layout_style::LayoutStyle; +use crate::definition::layout::LayoutStyle; use crate::legacy_definition::view::node_style::NodeStyle; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, Default)] +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] pub struct ViewStyle { pub layout_style: LayoutStyle, pub node_style: NodeStyle, } +impl Default for ViewStyle { + fn default() -> Self { + Self { layout_style: LayoutStyle::new_default(), node_style: NodeStyle::default() } + } +} + impl ViewStyle { /// Compute the difference between this style and the given style, returning a style /// that can be applied to this style to make it equal the given style using apply_non_default. diff --git a/crates/figma_import/src/figma_schema.rs b/crates/figma_import/src/figma_schema.rs index bd8d18cdd..fb767a8ec 100644 --- a/crates/figma_import/src/figma_schema.rs +++ b/crates/figma_import/src/figma_schema.rs @@ -716,15 +716,19 @@ impl OverflowDirection { } } -impl Into - for OverflowDirection -{ - fn into(self) -> dc_bundle::legacy_definition::layout::positioning::OverflowDirection { +impl Into for OverflowDirection { + fn into(self) -> dc_bundle::definition::layout::OverflowDirection { match self { - OverflowDirection::None => dc_bundle::legacy_definition::layout::positioning::OverflowDirection::None, - OverflowDirection::HorizontalScrolling => dc_bundle::legacy_definition::layout::positioning::OverflowDirection::HorizontalScrolling, - OverflowDirection::VerticalScrolling => dc_bundle::legacy_definition::layout::positioning::OverflowDirection::VerticalScrolling, - OverflowDirection::HorizontalAndVerticalScrolling => dc_bundle::legacy_definition::layout::positioning::OverflowDirection::HorizontalAndVerticalScrolling, + OverflowDirection::None => dc_bundle::definition::layout::OverflowDirection::None, + OverflowDirection::HorizontalScrolling => { + dc_bundle::definition::layout::OverflowDirection::HorizontalScrolling + } + OverflowDirection::VerticalScrolling => { + dc_bundle::definition::layout::OverflowDirection::VerticalScrolling + } + OverflowDirection::HorizontalAndVerticalScrolling => { + dc_bundle::definition::layout::OverflowDirection::HorizontalAndVerticalScrolling + } } } } @@ -1270,6 +1274,19 @@ impl BoundVariables { } None } + + pub(crate) fn get_var_from_hash(&self, hash_name: &str, var_name: &str) -> Option { + let var_hash = self.variables.get(hash_name); + if let Some(var) = var_hash { + if let VariableAliasOrList::Map(map) = var { + let var = map.get(var_name); + if let Some(var) = var { + return Some(var.id.clone()); + } + } + } + None + } } // We use the "untagged" serde attribute because the value of a variable is diff --git a/crates/figma_import/src/reflection.rs b/crates/figma_import/src/reflection.rs index 52b2efee1..887b6f517 100644 --- a/crates/figma_import/src/reflection.rs +++ b/crates/figma_import/src/reflection.rs @@ -22,13 +22,13 @@ pub fn registry() -> serde_reflection::Result { let samples = Samples::new(); tracer - .trace_type::(&samples) + .trace_type::(&samples) .expect("couldn't trace AlignContent"); tracer - .trace_type::(&samples) + .trace_type::(&samples) .expect("couldn't trace AlignItems"); tracer - .trace_type::(&samples) + .trace_type::(&samples) .expect("couldn't trace AlignSelf"); tracer .trace_type::(&samples) @@ -62,7 +62,7 @@ pub fn registry() -> serde_reflection::Result { .trace_type::(&samples) .expect("couldn't trace FilterOpType"); tracer - .trace_type::(&samples) + .trace_type::(&samples) .expect("couldn't trace FlexDirection"); tracer .trace_type::(&samples) @@ -74,7 +74,7 @@ pub fn registry() -> serde_reflection::Result { .trace_type::(&samples) .expect("couldn't trace TextDecoration"); tracer - .trace_type::(&samples) + .trace_type::(&samples) .expect("couldn't trace JustifyContent"); tracer .trace_type::(&samples) @@ -83,13 +83,13 @@ pub fn registry() -> serde_reflection::Result { .trace_type::(&samples) .expect("couldn't trace Number"); tracer - .trace_type::(&samples) + .trace_type::(&samples) .expect("couldn't trace Overflow"); tracer .trace_type::(&samples) .expect("couldn't trace PointerEvents"); tracer - .trace_type::(&samples) + .trace_type::(&samples) .expect("couldn't trace ItemSpacing"); tracer .trace_type::(&samples) @@ -114,7 +114,7 @@ pub fn registry() -> serde_reflection::Result { .trace_type::(&samples) .expect("couldn't trace MeterData"); tracer - .trace_type::(&samples) + .trace_type::(&samples) .expect("couldn't trace PositionType"); tracer .trace_type::(&samples) @@ -138,7 +138,7 @@ pub fn registry() -> serde_reflection::Result { .trace_type::(&samples) .expect("couldn't trace TextOverflow"); tracer - .trace_type::(&samples) + .trace_type::(&samples) .expect("couldn't trace LayoutSizing"); tracer .trace_type::(&samples) @@ -184,9 +184,7 @@ pub fn registry() -> serde_reflection::Result { .trace_type::(&samples) .expect("couldn't trace ComponentInfo"); tracer - .trace_type::( - &samples, - ) + .trace_type::(&samples) .expect("couldn't trace OverflowDirection"); tracer .trace_type::(&samples) @@ -259,6 +257,9 @@ pub fn registry() -> serde_reflection::Result { .expect("couldn't trace SerializedDesignDoc"); tracer.trace_type::(&samples).expect("couldn't trace ServerFigmaDoc"); tracer.trace_type::(&samples).expect("couldn't trace ConvertResponse"); + tracer + .trace_type::(&samples) + .expect("couldn't trace ItemSpacingType"); tracer.registry() } diff --git a/crates/figma_import/src/tools/fetch_layout.rs b/crates/figma_import/src/tools/fetch_layout.rs index 148f7588c..3d3034433 100644 --- a/crates/figma_import/src/tools/fetch_layout.rs +++ b/crates/figma_import/src/tools/fetch_layout.rs @@ -17,8 +17,8 @@ use crate::{Document, ProxyConfig}; use clap::Parser; use dc_bundle::definition::element::dimension_proto::Dimension; use dc_bundle::definition::element::DimensionProto; +use dc_bundle::definition::layout::LayoutSizing; use dc_bundle::legacy_definition::element::node::NodeQuery; -use dc_bundle::legacy_definition::layout::positioning::LayoutSizing; use dc_bundle::legacy_definition::view::view::{View, ViewData}; use dc_bundle::legacy_definition::DesignComposeDefinition; use layout::LayoutManager; @@ -156,9 +156,9 @@ fn test_layout( } else { let mut fixed_view = view.clone(); fixed_view.style.layout_style.width = - DimensionProto::new_points(view.style.layout_style.bounding_box.width); + DimensionProto::new_points(view.style.layout_style.bounding_box().unwrap().width); fixed_view.style.layout_style.height = - DimensionProto::new_points(view.style.layout_style.bounding_box.height); + DimensionProto::new_points(view.style.layout_style.bounding_box().unwrap().height); layout_manager .add_style( my_id, @@ -167,8 +167,8 @@ fn test_layout( fixed_view.style.layout_style.clone(), fixed_view.name.clone(), false, - Some(view.style.layout_style.bounding_box.width as i32), - Some(view.style.layout_style.bounding_box.height as i32), + Some(view.style.layout_style.bounding_box().unwrap().width as i32), + Some(view.style.layout_style.bounding_box().unwrap().height as i32), ) .expect("Failed to add style"); } diff --git a/crates/figma_import/src/transform_flexbox.rs b/crates/figma_import/src/transform_flexbox.rs index b4489a56c..2232254a3 100644 --- a/crates/figma_import/src/transform_flexbox.rs +++ b/crates/figma_import/src/transform_flexbox.rs @@ -29,7 +29,7 @@ use crate::{ use crate::{figma_schema, Error}; use dc_bundle::definition::element::{ view_shape, DimensionProto, DimensionRect, DimensionRectExt, FontFeature, FontStyle, - FontWeight, ViewShape, + FontWeight, Size, ViewShape, }; use crate::figma_schema::LayoutPositioning; @@ -44,16 +44,16 @@ use dc_bundle::definition::element::{ background, stroke_weight, Background, StrokeAlign, StrokeWeight, }; use dc_bundle::definition::interaction::Reaction; -use dc_bundle::definition::layout::{FlexWrap, GridLayoutType, GridSpan}; +use dc_bundle::definition::layout::{ + AlignContent, AlignItems, AlignSelf, FlexDirection, FlexWrap, GridLayoutType, GridSpan, + ItemSpacing, JustifyContent, LayoutSizing, Overflow, OverflowDirection, PositionType, +}; use dc_bundle::definition::modifier::{ filter_op, BoxShadow, FilterOp, TextAlign, TextAlignVertical, TextOverflow, TextShadow, }; use dc_bundle::definition::modifier::{BlendMode, LayoutTransform}; use dc_bundle::definition::plugin::FrameExtras; -use dc_bundle::legacy_definition::layout::positioning::{ - AlignContent, AlignItems, AlignSelf, FlexDirection, ItemSpacing, JustifyContent, LayoutSizing, - Overflow, OverflowDirection, PositionType, -}; + use dc_bundle::legacy_definition::view::component::ComponentInfo; use dc_bundle::legacy_definition::view::text_style::{StyledTextRun, TextStyle}; use dc_bundle::legacy_definition::view::view::{RenderMethod, ScrollInfo, View}; @@ -115,15 +115,15 @@ fn compute_layout( let mut hug_height = false; if let Some(bounds) = node.absolute_bounding_box { - style.layout_style.bounding_box.width = bounds.width(); - style.layout_style.bounding_box.height = bounds.height(); + style.layout_style.bounding_box = + Some(Size { width: bounds.width(), height: bounds.height() }) } // Frames can implement Auto Layout on their children. if let Some(frame) = node.frame() { style.layout_style.position_type = match frame.layout_positioning { - LayoutPositioning::Absolute => PositionType::Absolute, - LayoutPositioning::Auto => PositionType::Relative, + LayoutPositioning::Absolute => PositionType::Absolute.into(), + LayoutPositioning::Auto => PositionType::Relative.into(), }; style.layout_style.width = DimensionProto::new_auto(); style.layout_style.height = DimensionProto::new_auto(); @@ -144,15 +144,15 @@ fn compute_layout( let flex_direction_override = check_child_size_override(node); if let Some(dir) = flex_direction_override { style.layout_style.flex_direction = match dir { - LayoutType::Horizontal => FlexDirection::Row, - LayoutType::Vertical => FlexDirection::Column, - _ => FlexDirection::None, + LayoutType::Horizontal => FlexDirection::Row.into(), + LayoutType::Vertical => FlexDirection::Column.into(), + _ => FlexDirection::None.into(), }; } else { style.layout_style.flex_direction = match frame.layout_mode { - figma_schema::LayoutMode::Horizontal => FlexDirection::Row, - figma_schema::LayoutMode::Vertical => FlexDirection::Column, - figma_schema::LayoutMode::None => FlexDirection::None, + figma_schema::LayoutMode::Horizontal => FlexDirection::Row.into(), + figma_schema::LayoutMode::Vertical => FlexDirection::Column.into(), + figma_schema::LayoutMode::None => FlexDirection::None.into(), }; } style.layout_style.padding = Some(DimensionRect { @@ -162,34 +162,33 @@ fn compute_layout( bottom: DimensionProto::new_points(frame.padding_bottom), }); - style.layout_style.item_spacing = ItemSpacing::Fixed(frame.item_spacing as i32); - + style.layout_style.item_spacing = Some(ItemSpacing::fixed(frame.item_spacing as i32)); match frame.layout_align { // Counter axis stretch Some(figma_schema::LayoutAlign::Stretch) => { - style.layout_style.align_self = AlignSelf::Stretch; + style.layout_style.align_self = AlignSelf::Stretch.into(); } _ => (), }; style.layout_style.align_items = match frame.counter_axis_align_items { - figma_schema::LayoutAlignItems::Center => AlignItems::Center, - figma_schema::LayoutAlignItems::Max => AlignItems::FlexEnd, - figma_schema::LayoutAlignItems::Min => AlignItems::FlexStart, - figma_schema::LayoutAlignItems::SpaceBetween => AlignItems::FlexStart, // XXX - figma_schema::LayoutAlignItems::Baseline => AlignItems::FlexStart, + figma_schema::LayoutAlignItems::Center => AlignItems::Center.into(), + figma_schema::LayoutAlignItems::Max => AlignItems::FlexEnd.into(), + figma_schema::LayoutAlignItems::Min => AlignItems::FlexStart.into(), + figma_schema::LayoutAlignItems::SpaceBetween => AlignItems::FlexStart.into(), // XXX + figma_schema::LayoutAlignItems::Baseline => AlignItems::FlexStart.into(), }; style.layout_style.justify_content = match frame.primary_axis_align_items { - figma_schema::LayoutAlignItems::Center => JustifyContent::Center, - figma_schema::LayoutAlignItems::Max => JustifyContent::FlexEnd, - figma_schema::LayoutAlignItems::Min => JustifyContent::FlexStart, - figma_schema::LayoutAlignItems::SpaceBetween => JustifyContent::SpaceBetween, - figma_schema::LayoutAlignItems::Baseline => JustifyContent::FlexStart, + figma_schema::LayoutAlignItems::Center => JustifyContent::Center.into(), + figma_schema::LayoutAlignItems::Max => JustifyContent::FlexEnd.into(), + figma_schema::LayoutAlignItems::Min => JustifyContent::FlexStart.into(), + figma_schema::LayoutAlignItems::SpaceBetween => JustifyContent::SpaceBetween.into(), + figma_schema::LayoutAlignItems::Baseline => JustifyContent::FlexStart.into(), }; // The toolkit picks "Stretch" as a sensible default, but we don't // want that for Figma elements. - style.layout_style.align_content = AlignContent::FlexStart; + style.layout_style.align_content = AlignContent::FlexStart.into(); - let align_self_stretch = style.layout_style.align_self == AlignSelf::Stretch; + let align_self_stretch = style.layout_style.align_self() == AlignSelf::Stretch; if let Some(bounds) = node.absolute_bounding_box { // If align_self is set to stretch, we want width/height to be Auto, even if the // frame's primary or counter axis sizing mode is set to Fixed. @@ -294,7 +293,7 @@ fn compute_layout( } } if is_widget_or_parent_widget { - style.layout_style.position_type = PositionType::Absolute; + style.layout_style.position_type = PositionType::Absolute.into(); style.layout_style.width = DimensionProto::new_auto(); style.layout_style.height = DimensionProto::new_auto(); style.layout_style.left = DimensionProto::new_points(0.0); @@ -308,13 +307,13 @@ fn compute_layout( match vector.layout_align { // Counter axis stretch Some(figma_schema::LayoutAlign::Stretch) => { - style.layout_style.align_self = AlignSelf::Stretch; + style.layout_style.align_self = AlignSelf::Stretch.into(); } _ => (), }; style.layout_style.position_type = match vector.layout_positioning { - LayoutPositioning::Absolute => PositionType::Absolute, - LayoutPositioning::Auto => PositionType::Relative, + LayoutPositioning::Absolute => PositionType::Absolute.into(), + LayoutPositioning::Auto => PositionType::Relative.into(), }; style.layout_style.width = DimensionProto::new_auto(); style.layout_style.height = DimensionProto::new_auto(); @@ -386,10 +385,10 @@ fn compute_layout( } } - if !parent_is_flexbox || style.layout_style.position_type == PositionType::Absolute { + if !parent_is_flexbox || style.layout_style.position_type() == PositionType::Absolute { match (node.absolute_bounding_box, parent_bounding_box) { (Some(bounds), Some(parent_bounds)) => { - style.layout_style.position_type = PositionType::Absolute; + style.layout_style.position_type = PositionType::Absolute.into(); // Figure out all the values we might need when calculating the layout constraints. let (width, height) = if let Some(size) = &node.size { @@ -990,14 +989,14 @@ fn visit_node( style.layout_style.item_spacing = if gld.auto_spacing { if horizontal { - ItemSpacing::Auto(gld.horizontal_spacing, gld.auto_spacing_item_size) + Some(ItemSpacing::auto(gld.horizontal_spacing, gld.auto_spacing_item_size)) } else { - ItemSpacing::Auto(gld.vertical_spacing, gld.auto_spacing_item_size) + Some(ItemSpacing::auto(gld.vertical_spacing, gld.auto_spacing_item_size)) } } else if horizontal { - ItemSpacing::Fixed(gld.horizontal_spacing) + Some(ItemSpacing::fixed(gld.horizontal_spacing)) } else { - ItemSpacing::Fixed(gld.vertical_spacing) + Some(ItemSpacing::fixed(gld.vertical_spacing)) }; style.node_style.cross_axis_item_spacing = if horizontal { gld.vertical_spacing as f32 @@ -1048,7 +1047,7 @@ fn visit_node( }; } if extended_auto_layout.auto_layout_data.space_between { - style.layout_style.justify_content = JustifyContent::SpaceBetween; + style.layout_style.justify_content = JustifyContent::SpaceBetween.into(); } is_widget_list = true; size_policy = extended_auto_layout.auto_layout_data.size_policy; @@ -1083,11 +1082,11 @@ fn visit_node( // we need to set our size depending on whether the size policy is hug or fixed. if is_widget_list { if size_policy == SizePolicy::Hug { - style.layout_style.position_type = PositionType::Relative; + style.layout_style.position_type = PositionType::Relative.into(); style.layout_style.width = DimensionProto::new_auto(); style.layout_style.height = DimensionProto::new_auto(); } else { - style.layout_style.position_type = PositionType::Absolute; + style.layout_style.position_type = PositionType::Absolute.into(); } } @@ -1465,19 +1464,50 @@ fn visit_node( // Collect the corner radii values to be saved into the view. If the corner radii are set // to variables, they will be set to NumOrVar::Var. Otherwise they will be set to NumOrVar::Num. let corner_radius = if let Some(vars) = &node.bound_variables { - let top_left = NumOrVarType::from_var(vars, "topLeftRadius", corner_radius_values[0]); - let top_right = NumOrVarType::from_var(vars, "topRightRadius", corner_radius_values[1]); - let bottom_right = - NumOrVarType::from_var(vars, "bottomRightRadius", corner_radius_values[2]); - let bottom_left = NumOrVarType::from_var(vars, "bottomLeftRadius", corner_radius_values[3]); + let corner_values = if vars.has_var("rectangleCornerRadii") { + ( + NumOrVarType::from_var_hash( + vars, + "rectangleCornerRadii", + "RECTANGLE_TOP_LEFT_CORNER_RADIUS", + corner_radius_values[0], + ), + NumOrVarType::from_var_hash( + vars, + "rectangleCornerRadii", + "RECTANGLE_TOP_RIGHT_CORNER_RADIUS", + corner_radius_values[1], + ), + NumOrVarType::from_var_hash( + vars, + "rectangleCornerRadii", + "RECTANGLE_BOTTOM_LEFT_CORNER_RADIUS", + corner_radius_values[2], + ), + NumOrVarType::from_var_hash( + vars, + "rectangleCornerRadii", + "RECTANGLE_BOTTOM_RIGHT_CORNER_RADIUS", + corner_radius_values[3], + ), + ) + } else { + ( + NumOrVarType::from_var(vars, "topLeftRadius", corner_radius_values[0]), + NumOrVarType::from_var(vars, "topRightRadius", corner_radius_values[1]), + NumOrVarType::from_var(vars, "bottomRightRadius", corner_radius_values[2]), + NumOrVarType::from_var(vars, "bottomLeftRadius", corner_radius_values[3]), + ) + }; if vars.has_var("topLeftRadius") || vars.has_var("topRightRadius") || vars.has_var("bottomRightRadius") || vars.has_var("bottomLeftRadius") + || vars.has_var("rectangleCornerRadii") { has_corner_radius = true; } - [top_left, top_right, bottom_right, bottom_left] + [corner_values.0, corner_values.1, corner_values.2, corner_values.3] } else { [ NumOrVarType::Num(corner_radius_values[0]), diff --git a/crates/figma_import/src/variable_utils.rs b/crates/figma_import/src/variable_utils.rs index 13ce3faed..d6814c733 100644 --- a/crates/figma_import/src/variable_utils.rs +++ b/crates/figma_import/src/variable_utils.rs @@ -31,6 +31,13 @@ pub(crate) trait FromFigmaVar { var_name: &str, var_value: VarType, ) -> Self; + + fn from_var_hash( + bound_variables: &figma_schema::BoundVariables, + hash_name: &str, + var_name: &str, + var_value: VarType, + ) -> Self; } // Create a NumOrVar from Figma variable name and number value impl FromFigmaVar for NumOrVarType { @@ -46,6 +53,19 @@ impl FromFigmaVar for NumOrVarType { NumOrVarType::Num(var_value) } } + fn from_var_hash( + bound_variables: &figma_schema::BoundVariables, + hash_name: &str, + var_name: &str, + var_value: f32, + ) -> Self { + let var = bound_variables.get_var_from_hash(hash_name, var_name); + if let Some(var) = var { + NumOrVarType::Var(NumVar { id: var, fallback: var_value }) + } else { + NumOrVarType::Num(var_value) + } + } } // Create a ColorOrVar from Figma variable name and color value impl FromFigmaVar<&FloatColor> for ColorOrVar { @@ -61,6 +81,15 @@ impl FromFigmaVar<&FloatColor> for ColorOrVar { ColorOrVar::new_color(color.into()) } } + fn from_var_hash( + _bound_variables: &figma_schema::BoundVariables, + _hash_name: &str, + _var_name: &str, + color: &FloatColor, + ) -> Self { + // Currently, no color variables from a hash are yet supported + ColorOrVar::new_color(color.into()) + } } // Create a VariableValue from figma_schema::VariableValue diff --git a/crates/figma_import/tests/layout-unit-tests.dcf b/crates/figma_import/tests/layout-unit-tests.dcf index 70bfde19b..932d88998 100644 Binary files a/crates/figma_import/tests/layout-unit-tests.dcf and b/crates/figma_import/tests/layout-unit-tests.dcf differ diff --git a/crates/figma_import/tests/layout_tests.rs b/crates/figma_import/tests/layout_tests.rs index 10c6e2c76..41cfa6272 100644 --- a/crates/figma_import/tests/layout_tests.rs +++ b/crates/figma_import/tests/layout_tests.rs @@ -25,8 +25,8 @@ use dc_bundle::definition::element::dimension_proto::Dimension; use dc_bundle::definition::element::DimensionProto; +use dc_bundle::definition::layout::LayoutSizing; use dc_bundle::legacy_definition::element::node::NodeQuery; -use dc_bundle::legacy_definition::layout::positioning::LayoutSizing; use dc_bundle::legacy_definition::view::view::{View, ViewData}; use dc_bundle::legacy_definition::{DesignComposeDefinition, DesignComposeDefinitionHeader}; use layout::LayoutManager; @@ -97,9 +97,9 @@ fn add_view_to_layout( } else { let mut fixed_view = view.clone(); fixed_view.style.layout_style.width = - DimensionProto::new_points(view.style.layout_style.bounding_box.width); + DimensionProto::new_points(view.style.layout_style.bounding_box().unwrap().width); fixed_view.style.layout_style.height = - DimensionProto::new_points(view.style.layout_style.bounding_box.height); + DimensionProto::new_points(view.style.layout_style.bounding_box().unwrap().height); manager .add_style( my_id, diff --git a/crates/layout/src/layout_manager.rs b/crates/layout/src/layout_manager.rs index 44b972f47..9b78b4366 100644 --- a/crates/layout/src/layout_manager.rs +++ b/crates/layout/src/layout_manager.rs @@ -14,7 +14,7 @@ use crate::into_taffy::TryIntoTaffy; use crate::types::Layout; -use dc_bundle::legacy_definition::layout::layout_style::LayoutStyle; +use dc_bundle::definition::layout::LayoutStyle; use dc_bundle::Error; use log::{error, trace}; use serde::{Deserialize, Serialize}; diff --git a/crates/layout/src/layout_node.rs b/crates/layout/src/layout_node.rs index 480f8334d..24f6ea83f 100644 --- a/crates/layout/src/layout_node.rs +++ b/crates/layout/src/layout_node.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use dc_bundle::legacy_definition::layout::layout_style::LayoutStyle; +use dc_bundle::definition::layout::LayoutStyle; use serde::{Deserialize, Serialize}; // A representation of a Figma node to register for layout. diff --git a/crates/layout/src/layout_style.rs b/crates/layout/src/layout_style.rs index ca7a136a3..3d0ef202b 100644 --- a/crates/layout/src/layout_style.rs +++ b/crates/layout/src/layout_style.rs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::into_taffy::{IntoTaffy, TryIntoTaffy}; +use crate::into_taffy::TryIntoTaffy; use dc_bundle::definition::element::DimensionExt; -use dc_bundle::legacy_definition::layout::layout_style::LayoutStyle; +use dc_bundle::definition::layout::LayoutStyle; impl TryIntoTaffy for &LayoutStyle { type Error = dc_bundle::Error; @@ -26,14 +26,14 @@ impl TryIntoTaffy for &LayoutStyle { tstyle.flex_grow = self.flex_grow; tstyle.flex_shrink = self.flex_shrink; tstyle.flex_basis = (&self.flex_basis).try_into_taffy()?; - tstyle.gap.width = (&self.item_spacing).into_taffy(); - tstyle.gap.height = (&self.item_spacing).into_taffy(); + tstyle.gap.width = (&self.item_spacing).try_into_taffy()?; + tstyle.gap.height = (&self.item_spacing).try_into_taffy()?; - tstyle.align_content = Some((&self.align_content).into_taffy()); - tstyle.justify_content = Some((&self.justify_content).into_taffy()); - tstyle.align_items = Some((&self.align_items).into_taffy()); - tstyle.flex_direction = (&self.flex_direction).into_taffy(); - tstyle.align_self = (&self.align_self).into_taffy(); + tstyle.align_content = Some(self.align_content().try_into_taffy()?); + tstyle.justify_content = Some(self.justify_content().try_into_taffy()?); + tstyle.align_items = Some(self.align_items().try_into_taffy()?); + tstyle.flex_direction = self.flex_direction().try_into_taffy()?; + tstyle.align_self = self.align_self().try_into_taffy()?; tstyle.size.width = (&self.width).try_into_taffy()?; tstyle.size.height = (&self.height).try_into_taffy()?; @@ -46,17 +46,17 @@ impl TryIntoTaffy for &LayoutStyle { // account scale and rotation, and disregard min/max sizes. // TODO support this with non-fixed sizes also! if self.width.is_points()? { - tstyle.size.width = taffy::prelude::Dimension::Length(self.bounding_box.width); + tstyle.size.width = taffy::prelude::Dimension::Length(self.bounding_box()?.width); tstyle.min_size.width = taffy::prelude::Dimension::Auto; tstyle.max_size.width = taffy::prelude::Dimension::Auto; } if self.height.is_points()? { - tstyle.size.height = taffy::prelude::Dimension::Length(self.bounding_box.height); + tstyle.size.height = taffy::prelude::Dimension::Length(self.bounding_box()?.height); tstyle.min_size.height = taffy::prelude::Dimension::Auto; tstyle.max_size.height = taffy::prelude::Dimension::Auto; } - tstyle.position = (&self.position_type).into_taffy(); + tstyle.position = self.position_type().try_into_taffy()?; tstyle.inset.left = (&self.left).try_into_taffy()?; tstyle.inset.right = (&self.right).try_into_taffy()?; tstyle.inset.top = (&self.top).try_into_taffy()?; diff --git a/crates/layout/src/proto/layout_node.rs b/crates/layout/src/proto/layout_node.rs index 674b7980c..d8981518c 100644 --- a/crates/layout/src/proto/layout_node.rs +++ b/crates/layout/src/proto/layout_node.rs @@ -29,8 +29,7 @@ impl TryFrom for layout_node::LayoutNode { child_index: proto.child_index, style: proto .style - .ok_or(dc_bundle::Error::MissingFieldError { field: "style".to_string() })? - .try_into()?, + .ok_or(dc_bundle::Error::MissingFieldError { field: "style".to_string() })?, name: proto.name, use_measure_func: proto.use_measure_func, fixed_width: proto.fixed_width, diff --git a/crates/layout/src/styles.rs b/crates/layout/src/styles.rs index 68f9c79c0..8415001b4 100644 --- a/crates/layout/src/styles.rs +++ b/crates/layout/src/styles.rs @@ -12,90 +12,124 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::into_taffy::IntoTaffy; +use crate::into_taffy::TryIntoTaffy; use ::taffy::style_helpers::TaffyZero; -use dc_bundle::legacy_definition::layout::positioning::{ - AlignContent, AlignItems, AlignSelf, FlexDirection, ItemSpacing, JustifyContent, PositionType, +use dc_bundle::definition::layout::{ + item_spacing, AlignContent, AlignItems, AlignSelf, FlexDirection, ItemSpacing, JustifyContent, + PositionType, }; +use dc_bundle::Error; use taffy::prelude as taffy; -impl IntoTaffy for &AlignItems { - fn into_taffy(self) -> taffy::AlignItems { +impl TryIntoTaffy for AlignItems { + type Error = dc_bundle::Error; + fn try_into_taffy(self) -> Result { match self { - AlignItems::Center => taffy::AlignItems::Center, - AlignItems::FlexStart => taffy::AlignItems::FlexStart, - AlignItems::FlexEnd => taffy::AlignItems::FlexEnd, - AlignItems::Baseline => taffy::AlignItems::Baseline, - AlignItems::Stretch => taffy::AlignItems::Stretch, + AlignItems::Center => Ok(taffy::AlignItems::Center), + AlignItems::FlexStart => Ok(taffy::AlignItems::FlexStart), + AlignItems::FlexEnd => Ok(taffy::AlignItems::FlexEnd), + AlignItems::Baseline => Ok(taffy::AlignItems::Baseline), + AlignItems::Stretch => Ok(taffy::AlignItems::Stretch), + AlignItems::Unspecified => { + Err(Error::UnknownEnumVariant { enum_name: "AlignItems".to_string() }) + } } } } -impl IntoTaffy> for &AlignSelf { - fn into_taffy(self) -> Option { +impl TryIntoTaffy> for AlignSelf { + type Error = dc_bundle::Error; + fn try_into_taffy(self) -> Result, Self::Error> { match self { - AlignSelf::Auto => None, - AlignSelf::FlexStart => Some(taffy::AlignItems::FlexStart), - AlignSelf::FlexEnd => Some(taffy::AlignItems::FlexEnd), - AlignSelf::Center => Some(taffy::AlignItems::Center), - AlignSelf::Baseline => Some(taffy::AlignItems::Baseline), - AlignSelf::Stretch => Some(taffy::AlignItems::Stretch), + AlignSelf::Auto => Ok(None), + AlignSelf::FlexStart => Ok(Some(taffy::AlignItems::FlexStart)), + AlignSelf::FlexEnd => Ok(Some(taffy::AlignItems::FlexEnd)), + AlignSelf::Center => Ok(Some(taffy::AlignItems::Center)), + AlignSelf::Baseline => Ok(Some(taffy::AlignItems::Baseline)), + AlignSelf::Stretch => Ok(Some(taffy::AlignItems::Stretch)), + AlignSelf::Unspecified => { + Err(Error::UnknownEnumVariant { enum_name: "AlignSelf".to_string() }) + } } } } -impl IntoTaffy for &AlignContent { - fn into_taffy(self) -> taffy::AlignContent { +impl TryIntoTaffy for AlignContent { + type Error = dc_bundle::Error; + fn try_into_taffy(self) -> Result { match self { - AlignContent::Center => taffy::AlignContent::Center, - AlignContent::FlexStart => taffy::AlignContent::FlexStart, - AlignContent::FlexEnd => taffy::AlignContent::FlexEnd, - AlignContent::SpaceAround => taffy::AlignContent::SpaceAround, - AlignContent::SpaceBetween => taffy::AlignContent::SpaceBetween, - AlignContent::Stretch => taffy::AlignContent::Stretch, + AlignContent::Center => Ok(taffy::AlignContent::Center), + AlignContent::FlexStart => Ok(taffy::AlignContent::FlexStart), + AlignContent::FlexEnd => Ok(taffy::AlignContent::FlexEnd), + AlignContent::SpaceAround => Ok(taffy::AlignContent::SpaceAround), + AlignContent::SpaceBetween => Ok(taffy::AlignContent::SpaceBetween), + AlignContent::Stretch => Ok(taffy::AlignContent::Stretch), + AlignContent::Unspecified => { + Err(Error::UnknownEnumVariant { enum_name: "AlignContent".to_string() }) + } } } } -impl IntoTaffy for &FlexDirection { - fn into_taffy(self) -> taffy::FlexDirection { +impl TryIntoTaffy for FlexDirection { + type Error = dc_bundle::Error; + fn try_into_taffy(self) -> Result { match self { - FlexDirection::Row => taffy::FlexDirection::Row, - FlexDirection::Column => taffy::FlexDirection::Column, - FlexDirection::RowReverse => taffy::FlexDirection::RowReverse, - FlexDirection::ColumnReverse => taffy::FlexDirection::ColumnReverse, - FlexDirection::None => taffy::FlexDirection::Row, + FlexDirection::Row => Ok(taffy::FlexDirection::Row), + FlexDirection::Column => Ok(taffy::FlexDirection::Column), + FlexDirection::RowReverse => Ok(taffy::FlexDirection::ColumnReverse), + FlexDirection::ColumnReverse => Ok(taffy::FlexDirection::ColumnReverse), + FlexDirection::None => Ok(taffy::FlexDirection::Row), + FlexDirection::Unspecified => { + Err(Error::UnknownEnumVariant { enum_name: "FlexDirection".to_string() }) + } } } } -impl IntoTaffy for &JustifyContent { - fn into_taffy(self) -> taffy::JustifyContent { +impl TryIntoTaffy for JustifyContent { + type Error = dc_bundle::Error; + fn try_into_taffy(self) -> Result { match self { - JustifyContent::Center => taffy::JustifyContent::Center, - JustifyContent::FlexStart => taffy::JustifyContent::FlexStart, - JustifyContent::FlexEnd => taffy::JustifyContent::FlexEnd, - JustifyContent::SpaceAround => taffy::JustifyContent::SpaceAround, - JustifyContent::SpaceBetween => taffy::JustifyContent::SpaceBetween, - JustifyContent::SpaceEvenly => taffy::JustifyContent::SpaceEvenly, + JustifyContent::Center => Ok(taffy::JustifyContent::Center), + JustifyContent::FlexStart => Ok(taffy::JustifyContent::FlexStart), + JustifyContent::FlexEnd => Ok(taffy::JustifyContent::FlexEnd), + JustifyContent::SpaceAround => Ok(taffy::JustifyContent::SpaceAround), + JustifyContent::SpaceBetween => Ok(taffy::JustifyContent::SpaceBetween), + JustifyContent::SpaceEvenly => Ok(taffy::JustifyContent::SpaceEvenly), + JustifyContent::Unspecified => { + Err(Error::UnknownEnumVariant { enum_name: "JustifyContent".to_string() }) + } } } } -impl IntoTaffy for &PositionType { - fn into_taffy(self) -> taffy::Position { +impl TryIntoTaffy for PositionType { + type Error = dc_bundle::Error; + fn try_into_taffy(self) -> Result { match self { - PositionType::Absolute => taffy::Position::Absolute, - PositionType::Relative => taffy::Position::Relative, + PositionType::Absolute => Ok(taffy::Position::Absolute), + PositionType::Relative => Ok(taffy::Position::Relative), + PositionType::Unspecified => { + Err(Error::UnknownEnumVariant { enum_name: "PositionType".to_string() }) + } } } } - -impl IntoTaffy for &ItemSpacing { - fn into_taffy(self) -> taffy::LengthPercentage { +impl TryIntoTaffy for &Option { + type Error = dc_bundle::Error; + fn try_into_taffy(self) -> Result { match self { - ItemSpacing::Fixed(s) => taffy::LengthPercentage::Length(*s as f32), - ItemSpacing::Auto(..) => taffy::LengthPercentage::ZERO, + Some(spacing) => match spacing.item_spacing_type { + Some(item_spacing::ItemSpacingType::Fixed(s)) => { + Ok(taffy::LengthPercentage::Length(s as f32)) + } + Some(item_spacing::ItemSpacingType::Auto(..)) => Ok(taffy::LengthPercentage::ZERO), + None => Err(dc_bundle::Error::UnknownEnumVariant { + enum_name: "ItemSpacing".to_string(), + }), + }, + None => Err(Error::MissingFieldError { field: "ItemSpacing".to_string() }), } } } diff --git a/designcompose/src/main/assets/figma/DesignSwitcherDoc_Ljph4e3sC0lHcynfXpoh9f.dcf b/designcompose/src/main/assets/figma/DesignSwitcherDoc_Ljph4e3sC0lHcynfXpoh9f.dcf index 654725c31..1d53f0093 100644 Binary files a/designcompose/src/main/assets/figma/DesignSwitcherDoc_Ljph4e3sC0lHcynfXpoh9f.dcf and b/designcompose/src/main/assets/figma/DesignSwitcherDoc_Ljph4e3sC0lHcynfXpoh9f.dcf differ diff --git a/designcompose/src/main/java/com/android/designcompose/DesignFrame.kt b/designcompose/src/main/java/com/android/designcompose/DesignFrame.kt index 13bf42f17..f560d3d4f 100644 --- a/designcompose/src/main/java/com/android/designcompose/DesignFrame.kt +++ b/designcompose/src/main/java/com/android/designcompose/DesignFrame.kt @@ -32,7 +32,6 @@ import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -54,10 +53,11 @@ import androidx.tracing.trace import com.android.designcompose.proto.getDim import com.android.designcompose.proto.start import com.android.designcompose.proto.top +import com.android.designcompose.proto.type import com.android.designcompose.serdegen.Dimension import com.android.designcompose.serdegen.GridLayoutType import com.android.designcompose.serdegen.GridSpan -import com.android.designcompose.serdegen.ItemSpacing +import com.android.designcompose.serdegen.ItemSpacingType import com.android.designcompose.serdegen.NodeQuery import com.android.designcompose.serdegen.View import com.android.designcompose.serdegen.ViewData @@ -454,7 +454,8 @@ internal fun DesignFrame( // for the first frame and then in another on the second frame after the main axis // size has been set. val showInitContent = - (gridMainAxisSize <= 0 && layoutInfo.mainAxisSpacing is ItemSpacing.Auto) + (gridMainAxisSize <= 0 && + layoutInfo.mainAxisSpacing.type() is ItemSpacingType.Auto) if (showInitContent) items( count = 1, @@ -563,9 +564,7 @@ internal fun DesignFrame( ) { val columnCount = calculateColumnRowCount(layoutInfo, gridMainAxisSize) val horizontalSpacing = - if (layoutInfo.mainAxisSpacing is ItemSpacing.Fixed) - layoutInfo.mainAxisSpacing.value - else 0 + (layoutInfo.mainAxisSpacing.type() as? ItemSpacingType.Fixed)?.value ?: 0 val verticalSpacing = layoutInfo.crossAxisSpacing DesignParentLayout(rootParentLayoutInfo) { @@ -588,15 +587,17 @@ internal fun DesignFrame( }, horizontalArrangement = Arrangement.spacedBy( - (if (layoutInfo.mainAxisSpacing is ItemSpacing.Fixed) { - layoutInfo.mainAxisSpacing.value - } else if (layoutInfo.mainAxisSpacing is ItemSpacing.Auto) { - if (columnCount > 1) - (gridMainAxisSize - - (layoutInfo.mainAxisSpacing.field1 * columnCount)) / - (columnCount - 1) - else layoutInfo.mainAxisSpacing.field0 - } else horizontalSpacing) + (when (val spacing = layoutInfo.mainAxisSpacing.type()) { + is ItemSpacingType.Fixed -> spacing.value + is ItemSpacingType.Auto -> { + if (columnCount > 1) + (gridMainAxisSize - + (spacing.value.height * columnCount)) / + (columnCount - 1) + else spacing.value.width + } + else -> horizontalSpacing + }) .dp ), verticalArrangement = Arrangement.spacedBy(verticalSpacing.dp), @@ -616,9 +617,8 @@ internal fun DesignFrame( val rowCount = calculateColumnRowCount(layoutInfo, gridMainAxisSize) val horizontalSpacing = layoutInfo.crossAxisSpacing val verticalSpacing = - if (layoutInfo.mainAxisSpacing is ItemSpacing.Fixed) - layoutInfo.mainAxisSpacing.value - else 0 + (layoutInfo.mainAxisSpacing.type() as? ItemSpacingType.Fixed)?.value ?: 0 + DesignParentLayout(rootParentLayoutInfo) { LazyHorizontalGrid( modifier = layoutInfo.selfModifier.then(gridSizeModifier).then(m), @@ -640,16 +640,17 @@ internal fun DesignFrame( horizontalArrangement = Arrangement.spacedBy(horizontalSpacing.dp), verticalArrangement = Arrangement.spacedBy( - (if (layoutInfo.mainAxisSpacing is ItemSpacing.Fixed) { - layoutInfo.mainAxisSpacing.value - } else if (layoutInfo.mainAxisSpacing is ItemSpacing.Auto) { - - if (rowCount > 1) - (gridMainAxisSize - - (layoutInfo.mainAxisSpacing.field1 * rowCount)) / - (rowCount - 1) - else layoutInfo.mainAxisSpacing.field0 - } else verticalSpacing) + (when (val spacing = layoutInfo.mainAxisSpacing.type()) { + is ItemSpacingType.Fixed -> spacing.value + is ItemSpacingType.Auto -> { + if (rowCount > 1) + (gridMainAxisSize - + (spacing.value.height * rowCount)) / + (rowCount - 1) + else spacing.value.width + } + else -> verticalSpacing + }) .dp ), userScrollEnabled = layoutInfo.scrollingEnabled, diff --git a/designcompose/src/main/java/com/android/designcompose/DesignView.kt b/designcompose/src/main/java/com/android/designcompose/DesignView.kt index b1da5874f..629845428 100644 --- a/designcompose/src/main/java/com/android/designcompose/DesignView.kt +++ b/designcompose/src/main/java/com/android/designcompose/DesignView.kt @@ -496,19 +496,19 @@ internal fun DesignView( // Only add scroll modifiers if not a grid layout because grid layout adds its own scrolling if (viewLayoutInfo !is LayoutInfoGrid && viewLayoutInfo !is LayoutInfoAbsolute) { when (view.scroll_info.overflow) { - is OverflowDirection.VERTICAL_SCROLLING -> { + is OverflowDirection.VerticalScrolling -> { m = Modifier.verticalScroll(rememberScrollState()).then(m) } - is OverflowDirection.HORIZONTAL_SCROLLING -> { + is OverflowDirection.HorizontalScrolling -> { m = Modifier.horizontalScroll(rememberScrollState()).then(m) } - is OverflowDirection.HORIZONTAL_AND_VERTICAL_SCROLLING -> { + is OverflowDirection.HorizontalAndVerticalScrolling -> { m = Modifier.horizontalScroll(rememberScrollState()) .verticalScroll(rememberScrollState()) .then(m) } - is OverflowDirection.NONE -> {} + is OverflowDirection.None -> {} } } diff --git a/designcompose/src/main/java/com/android/designcompose/Layout.kt b/designcompose/src/main/java/com/android/designcompose/Layout.kt index 8d745f411..5c6875709 100644 --- a/designcompose/src/main/java/com/android/designcompose/Layout.kt +++ b/designcompose/src/main/java/com/android/designcompose/Layout.kt @@ -38,10 +38,13 @@ import androidx.compose.ui.text.ParagraphIntrinsics import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp +import com.android.designcompose.proto.alignItemsFromInt import com.android.designcompose.proto.bottom import com.android.designcompose.proto.end +import com.android.designcompose.proto.justifyContentFromInt import com.android.designcompose.proto.start import com.android.designcompose.proto.top +import com.android.designcompose.proto.type import com.android.designcompose.serdegen.AlignItems import com.android.designcompose.serdegen.AlignSelf import com.android.designcompose.serdegen.Dimension @@ -49,6 +52,7 @@ import com.android.designcompose.serdegen.DimensionRect import com.android.designcompose.serdegen.GridLayoutType import com.android.designcompose.serdegen.GridSpan import com.android.designcompose.serdegen.ItemSpacing +import com.android.designcompose.serdegen.ItemSpacingType import com.android.designcompose.serdegen.JustifyContent import com.android.designcompose.serdegen.Layout import com.android.designcompose.serdegen.LayoutTransform @@ -220,9 +224,9 @@ internal class LayoutInfoGrid( ) : SimplifiedLayoutInfo(selfModifier) internal fun itemSpacingAbs(itemSpacing: ItemSpacing): Int { - return when (itemSpacing) { - is ItemSpacing.Fixed -> itemSpacing.value - is ItemSpacing.Auto -> itemSpacing.field0 + return when (val type = itemSpacing.type()) { + is ItemSpacingType.Fixed -> type.value + is ItemSpacingType.Auto -> type.value.width else -> 0 } } @@ -243,7 +247,7 @@ internal fun calcLayoutInfo( val gridLayout = style.node_style.grid_layout.get() val isHorizontalLayout = gridLayout is GridLayoutType.Horizontal val isVerticalLayout = gridLayout is GridLayoutType.Vertical - val itemSpacing = itemSpacingAbs(style.layout_style.item_spacing) + val itemSpacing = itemSpacingAbs(style.layout_style.item_spacing.get()) val marginModifier = Modifier.padding( if (style.layout_style.padding.start is Dimension.Points) @@ -262,7 +266,7 @@ internal fun calcLayoutInfo( if (isHorizontalLayout) { return LayoutInfoRow( arrangement = - when (style.layout_style.justify_content) { + when (justifyContentFromInt(style.layout_style.justify_content)) { is JustifyContent.FlexStart -> if (itemSpacing != 0) Arrangement.spacedBy(itemSpacing.dp) else Arrangement.Start @@ -280,7 +284,7 @@ internal fun calcLayoutInfo( else -> Arrangement.Start }, alignment = - when (style.layout_style.align_items) { + when (alignItemsFromInt(style.layout_style.align_items)) { is AlignItems.FlexStart -> Alignment.Top is AlignItems.Center -> Alignment.CenterVertically is AlignItems.FlexEnd -> Alignment.Bottom @@ -293,7 +297,7 @@ internal fun calcLayoutInfo( } else if (isVerticalLayout) { return LayoutInfoColumn( arrangement = - when (style.layout_style.justify_content) { + when (justifyContentFromInt(style.layout_style.justify_content)) { is JustifyContent.FlexStart -> if (itemSpacing != 0) Arrangement.spacedBy(itemSpacing.dp) else Arrangement.Top @@ -311,7 +315,7 @@ internal fun calcLayoutInfo( else -> Arrangement.Top }, alignment = - when (style.layout_style.align_items) { + when (alignItemsFromInt(style.layout_style.align_items)) { is AlignItems.FlexStart -> Alignment.Start is AlignItems.Center -> Alignment.CenterHorizontally is AlignItems.FlexEnd -> Alignment.End @@ -327,15 +331,15 @@ internal fun calcLayoutInfo( gridLayout is GridLayoutType.AutoColumns val scrollingEnabled = when (view.scroll_info.overflow) { - is OverflowDirection.VERTICAL_SCROLLING -> isColumnLayout - is OverflowDirection.HORIZONTAL_SCROLLING -> !isColumnLayout - is OverflowDirection.HORIZONTAL_AND_VERTICAL_SCROLLING -> true + is OverflowDirection.VerticalScrolling -> isColumnLayout + is OverflowDirection.HorizontalScrolling -> !isColumnLayout + is OverflowDirection.HorizontalAndVerticalScrolling -> true else -> false } return LayoutInfoGrid( layout = style.node_style.grid_layout.get(), minColumnRowSize = style.node_style.grid_adaptive_min_size, - mainAxisSpacing = style.layout_style.item_spacing, + mainAxisSpacing = style.layout_style.item_spacing.get(), crossAxisSpacing = style.node_style.cross_axis_item_spacing.toInt(), // TODO support these other alignments? /* @@ -368,13 +372,13 @@ internal fun calcLayoutInfo( var horizontalScroll = false var verticalScroll = false when (view.scroll_info.overflow) { - is OverflowDirection.VERTICAL_SCROLLING -> { + is OverflowDirection.VerticalScrolling -> { verticalScroll = true } - is OverflowDirection.HORIZONTAL_SCROLLING -> { + is OverflowDirection.HorizontalScrolling -> { horizontalScroll = true } - is OverflowDirection.HORIZONTAL_AND_VERTICAL_SCROLLING -> { + is OverflowDirection.HorizontalAndVerticalScrolling -> { // Currently we don't support both horizontal and vertical scrolling so disable both verticalScroll = false horizontalScroll = false diff --git a/designcompose/src/main/java/com/android/designcompose/Utils.kt b/designcompose/src/main/java/com/android/designcompose/Utils.kt index 7a4fd452c..96eaa4d47 100644 --- a/designcompose/src/main/java/com/android/designcompose/Utils.kt +++ b/designcompose/src/main/java/com/android/designcompose/Utils.kt @@ -51,25 +51,34 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.android.designcompose.proto.StrokeAlignType import com.android.designcompose.proto.WindingRuleType +import com.android.designcompose.proto.alignContentFromInt +import com.android.designcompose.proto.alignItemsFromInt +import com.android.designcompose.proto.alignSelfFromInt import com.android.designcompose.proto.end +import com.android.designcompose.proto.flexDirectionFromInt import com.android.designcompose.proto.get import com.android.designcompose.proto.getDim import com.android.designcompose.proto.getType import com.android.designcompose.proto.isDefault import com.android.designcompose.proto.isType +import com.android.designcompose.proto.justifyContentFromInt import com.android.designcompose.proto.newDimensionProtoUndefined import com.android.designcompose.proto.newDimensionRectPointsZero import com.android.designcompose.proto.newFontWeight +import com.android.designcompose.proto.positionTypeFromInt import com.android.designcompose.proto.scaleModeFromInt import com.android.designcompose.proto.start import com.android.designcompose.proto.strokeAlignTypeToInt +import com.android.designcompose.proto.toInt import com.android.designcompose.proto.toOptDimProto import com.android.designcompose.proto.top +import com.android.designcompose.proto.type import com.android.designcompose.proto.windingRuleFromInt import com.android.designcompose.serdegen.AffineTransform import com.android.designcompose.serdegen.AlignContent import com.android.designcompose.serdegen.AlignItems import com.android.designcompose.serdegen.AlignSelf +import com.android.designcompose.serdegen.Auto import com.android.designcompose.serdegen.Background import com.android.designcompose.serdegen.BackgroundType import com.android.designcompose.serdegen.BlendMode @@ -81,6 +90,7 @@ import com.android.designcompose.serdegen.FlexWrap import com.android.designcompose.serdegen.FontStretch import com.android.designcompose.serdegen.FontStyle import com.android.designcompose.serdegen.ItemSpacing +import com.android.designcompose.serdegen.ItemSpacingType import com.android.designcompose.serdegen.JustifyContent import com.android.designcompose.serdegen.Layout import com.android.designcompose.serdegen.LayoutSizing @@ -423,13 +433,13 @@ internal fun mergeStyles(base: ViewStyle, override: ViewStyle): ViewStyle { base.node_style.display_type } layoutStyle.position_type = - if (override.layout_style.position_type !is PositionType.Relative) { + if (positionTypeFromInt(override.layout_style.position_type) !is PositionType.Relative) { override.layout_style.position_type } else { base.layout_style.position_type } layoutStyle.flex_direction = - if (override.layout_style.flex_direction !is FlexDirection.Row) { + if (flexDirectionFromInt(override.layout_style.flex_direction) !is FlexDirection.Row) { override.layout_style.flex_direction } else { base.layout_style.flex_direction @@ -485,25 +495,28 @@ internal fun mergeStyles(base: ViewStyle, override: ViewStyle): ViewStyle { base.node_style.overflow_node_name } layoutStyle.align_items = - if (override.layout_style.align_items !is AlignItems.Stretch) { + if (alignItemsFromInt(override.layout_style.align_items) !is AlignItems.Stretch) { override.layout_style.align_items } else { base.layout_style.align_items } layoutStyle.align_self = - if (override.layout_style.align_self !is AlignSelf.Auto) { + if (alignSelfFromInt(override.layout_style.align_self) !is AlignSelf.Auto) { override.layout_style.align_self } else { base.layout_style.align_self } layoutStyle.align_content = - if (override.layout_style.align_content !is AlignContent.Stretch) { + if (alignContentFromInt(override.layout_style.align_content) !is AlignContent.Stretch) { override.layout_style.align_content } else { base.layout_style.align_content } layoutStyle.justify_content = - if (override.layout_style.justify_content !is JustifyContent.FlexStart) { + if ( + justifyContentFromInt(override.layout_style.justify_content) + !is JustifyContent.FlexStart + ) { override.layout_style.justify_content } else { base.layout_style.justify_content @@ -546,10 +559,10 @@ internal fun mergeStyles(base: ViewStyle, override: ViewStyle): ViewStyle { base.layout_style.padding } fun ItemSpacing.isDefault(): Boolean { - return this is ItemSpacing.Fixed && this.value == 0 + return (type() as? ItemSpacingType.Fixed)?.value == 0 } layoutStyle.item_spacing = - if (!override.layout_style.item_spacing.isDefault()) { + if (!override.layout_style.item_spacing.get().isDefault()) { override.layout_style.item_spacing } else { base.layout_style.item_spacing @@ -580,21 +593,21 @@ internal fun mergeStyles(base: ViewStyle, override: ViewStyle): ViewStyle { } layoutStyle.bounding_box = if ( - override.layout_style.bounding_box.width != 0.0f || - override.layout_style.bounding_box.height != 0.0f + override.layout_style.bounding_box.get().width != 0.0f || + override.layout_style.bounding_box.get().height != 0.0f ) { override.layout_style.bounding_box } else { base.layout_style.bounding_box } nodeStyle.horizontal_sizing = - if (override.node_style.horizontal_sizing !is LayoutSizing.FIXED) { + if (override.node_style.horizontal_sizing !is LayoutSizing.Fixed) { override.node_style.horizontal_sizing } else { base.node_style.horizontal_sizing } nodeStyle.vertical_sizing = - if (override.node_style.vertical_sizing !is LayoutSizing.FIXED) { + if (override.node_style.vertical_sizing !is LayoutSizing.Fixed) { override.node_style.vertical_sizing } else { base.node_style.vertical_sizing @@ -690,23 +703,23 @@ internal fun LayoutStyle.asBuilder(): LayoutStyle.Builder { internal fun defaultLayoutStyle(): LayoutStyle.Builder { val builder = LayoutStyle.Builder() - builder.position_type = PositionType.Relative() - builder.flex_direction = FlexDirection.Row() - builder.align_items = AlignItems.FlexStart() - builder.align_self = AlignSelf.Auto() - builder.align_content = AlignContent.FlexStart() - builder.justify_content = JustifyContent.FlexStart() + builder.position_type = PositionType.Relative().toInt() + builder.flex_direction = FlexDirection.Row().toInt() + builder.align_items = AlignItems.FlexStart().toInt() + builder.align_self = AlignSelf.Auto().toInt() + builder.align_content = AlignContent.FlexStart().toInt() + builder.justify_content = JustifyContent.FlexStart().toInt() builder.top = newDimensionProtoUndefined() builder.left = newDimensionProtoUndefined() builder.bottom = newDimensionProtoUndefined() builder.right = newDimensionProtoUndefined() builder.margin = newDimensionRectPointsZero() builder.padding = newDimensionRectPointsZero() - builder.item_spacing = ItemSpacing.Auto(0, 0) + builder.item_spacing = Optional.of(ItemSpacing(Optional.of(ItemSpacingType.Auto(Auto(0, 0))))) builder.flex_grow = 0.0f builder.flex_shrink = 0.0f builder.flex_basis = newDimensionProtoUndefined() - builder.bounding_box = com.android.designcompose.serdegen.Size(0f, 0f) + builder.bounding_box = Optional.of(com.android.designcompose.serdegen.Size(0f, 0f)) builder.width = newDimensionProtoUndefined() builder.height = newDimensionProtoUndefined() builder.min_width = newDimensionProtoUndefined() @@ -806,8 +819,8 @@ internal fun defaultNodeStyle(): NodeStyle.Builder { builder.overflow_node_id = Optional.empty() builder.overflow_node_name = Optional.empty() builder.cross_axis_item_spacing = 0f - builder.horizontal_sizing = LayoutSizing.HUG() - builder.vertical_sizing = LayoutSizing.HUG() + builder.horizontal_sizing = LayoutSizing.Hug() + builder.vertical_sizing = LayoutSizing.Hug() builder.aspect_ratio = com.android.designcompose.serdegen.Number.Undefined() builder.pointer_events = PointerEvents.Auto() builder.meter_data = Optional.empty() @@ -839,11 +852,11 @@ internal fun ViewStyle.externalLayoutData(): ExternalLayoutData { layout_style.max_width.getDim(), layout_style.max_height.getDim(), node_style.node_size, - layout_style.bounding_box, + layout_style.bounding_box.get(), layout_style.flex_grow, layout_style.flex_basis.getDim(), - layout_style.align_self, - layout_style.position_type, + alignSelfFromInt(layout_style.align_self), + positionTypeFromInt(layout_style.position_type), node_style.transform, node_style.relative_transform, ) @@ -860,7 +873,7 @@ internal fun ViewStyle.withExternalLayoutData(data: ExternalLayoutData): ViewSty layoutStyle.bottom = data.bottom.toOptDimProto() layoutStyle.right = data.right.toOptDimProto() nodeStyle.node_size = data.nodeSize - layoutStyle.bounding_box = data.boundingBox + layoutStyle.bounding_box = Optional.of(data.boundingBox) layoutStyle.width = data.width.toOptDimProto() layoutStyle.height = data.height.toOptDimProto() @@ -870,8 +883,8 @@ internal fun ViewStyle.withExternalLayoutData(data: ExternalLayoutData): ViewSty layoutStyle.max_height = data.maxHeight.toOptDimProto() layoutStyle.flex_grow = data.flexGrow layoutStyle.flex_basis = data.flexBasis.toOptDimProto() - layoutStyle.align_self = data.alignSelf - layoutStyle.position_type = data.positionType + layoutStyle.align_self = data.alignSelf.toInt() + layoutStyle.position_type = data.positionType.toInt() nodeStyle.transform = data.transform nodeStyle.relative_transform = data.relativeTransform @@ -953,7 +966,8 @@ internal fun View.isMask(): Boolean { // Second, the position_type is relative, which is only set if the widget layout parameters are set // to hug contents. internal fun View.useInfiniteConstraints(): Boolean { - if (style.layout_style.position_type !is PositionType.Relative) return false + if (positionTypeFromInt(style.layout_style.position_type) !is PositionType.Relative) + return false if (data !is ViewData.Container) return false @@ -1610,7 +1624,7 @@ internal fun com.android.designcompose.serdegen.Path.log() { // passed into it. internal fun ViewStyle.isAutoWidthText() = layout_style.width.getDim() is Dimension.Auto && - node_style.horizontal_sizing !is LayoutSizing.FILL + node_style.horizontal_sizing !is LayoutSizing.Fill // Return the size of a node used to render the node. internal fun getNodeRenderSize( diff --git a/designcompose/src/main/java/com/android/designcompose/proto/IntoProto.kt b/designcompose/src/main/java/com/android/designcompose/proto/IntoProto.kt index fa78ce4ee..f5d5406f3 100644 --- a/designcompose/src/main/java/com/android/designcompose/proto/IntoProto.kt +++ b/designcompose/src/main/java/com/android/designcompose/proto/IntoProto.kt @@ -34,8 +34,7 @@ import com.android.designcompose.serdegen.AlignItems import com.android.designcompose.serdegen.AlignSelf import com.android.designcompose.serdegen.FlexDirection import com.android.designcompose.serdegen.ItemSpacing -import com.android.designcompose.serdegen.ItemSpacing.Auto -import com.android.designcompose.serdegen.ItemSpacing.Fixed +import com.android.designcompose.serdegen.ItemSpacingType import com.android.designcompose.serdegen.JustifyContent import com.android.designcompose.serdegen.LayoutNode import com.android.designcompose.serdegen.LayoutNodeList @@ -68,11 +67,11 @@ internal fun LayoutNodeList.intoProto() = layoutNodeList { } internal fun ItemSpacing.intoProto() = itemSpacing { - when (val s = this@intoProto) { - is Fixed -> fixed = s.value - is Auto -> auto = auto { - width = s.field0 - height = s.field1 + when (val s = this@intoProto.type()) { + is ItemSpacingType.Fixed -> fixed = s.value + is ItemSpacingType.Auto -> auto = auto { + width = s.value.width + height = s.value.height } else -> throw IllegalArgumentException("Unknown ItemSpacing: $this") // Should never happen. } @@ -155,7 +154,7 @@ internal fun LayoutStyle.intoProto() = layoutStyle { s.margin.orElseThrow { NoSuchFieldException("Malformed data: margin unset") }.intoProto() padding = s.padding.orElseThrow { NoSuchFieldException("Malformed data: padding unset") }.intoProto() - itemSpacing = s.item_spacing.intoProto() + itemSpacing = s.item_spacing.get().intoProto() top = s.top.getDim().intoProto() left = s.left.getDim().intoProto() bottom = s.bottom.getDim().intoProto() @@ -166,14 +165,14 @@ internal fun LayoutStyle.intoProto() = layoutStyle { maxWidth = s.max_width.getDim().intoProto() minHeight = s.min_height.getDim().intoProto() maxHeight = s.max_height.getDim().intoProto() - boundingBox = s.bounding_box.intoProto() + boundingBox = s.bounding_box.get().intoProto() flexGrow = s.flex_grow flexShrink = s.flex_shrink flexBasis = s.flex_basis.getDim().intoProto() - alignSelf = s.align_self.intoProto() - alignContent = s.align_content.intoProto() - alignItems = s.align_items.intoProto() - flexDirection = s.flex_direction.intoProto() - justifyContent = s.justify_content.intoProto() - positionType = s.position_type.intoProto() + alignSelf = alignSelfFromInt(s.align_self).intoProto() + alignContent = alignContentFromInt(s.align_content).intoProto() + alignItems = alignItemsFromInt(s.align_items).intoProto() + flexDirection = flexDirectionFromInt(s.flex_direction).intoProto() + justifyContent = justifyContentFromInt(s.justify_content).intoProto() + positionType = positionTypeFromInt(s.position_type).intoProto() } diff --git a/designcompose/src/main/java/com/android/designcompose/proto/IntoSerde.kt b/designcompose/src/main/java/com/android/designcompose/proto/IntoSerde.kt index efeb9f1e7..0a6c917b2 100644 --- a/designcompose/src/main/java/com/android/designcompose/proto/IntoSerde.kt +++ b/designcompose/src/main/java/com/android/designcompose/proto/IntoSerde.kt @@ -23,19 +23,27 @@ import com.android.designcompose.definition.layout.AlignSelf import com.android.designcompose.definition.layout.FlexDirection import com.android.designcompose.definition.layout.ItemSpacing import com.android.designcompose.definition.layout.JustifyContent -import com.android.designcompose.definition.layout.LayoutStyle import com.android.designcompose.definition.layout.PositionType import com.android.designcompose.serdegen.Size -import java.util.* +import java.util.Optional internal fun LayoutChangedResponse.Layout.intoSerde() = com.android.designcompose.serdegen.Layout(order, width, height, left, top) internal fun ItemSpacing.intoSerde() = - when (typeCase) { - ItemSpacing.TypeCase.FIXED -> com.android.designcompose.serdegen.ItemSpacing.Fixed(fixed) - ItemSpacing.TypeCase.AUTO -> - com.android.designcompose.serdegen.ItemSpacing.Auto(auto.width, auto.height) + when (itemSpacingTypeCase) { + ItemSpacing.ItemSpacingTypeCase.FIXED -> + com.android.designcompose.serdegen.ItemSpacing( + Optional.of(com.android.designcompose.serdegen.ItemSpacingType.Fixed(fixed)) + ) + ItemSpacing.ItemSpacingTypeCase.AUTO -> + com.android.designcompose.serdegen.ItemSpacing( + Optional.of( + com.android.designcompose.serdegen.ItemSpacingType.Auto( + com.android.designcompose.serdegen.Auto(auto.width, auto.height) + ) + ) + ) else -> throw IllegalArgumentException("Unknown ItemSpacing: $this") // Should never happen. } @@ -119,31 +127,3 @@ internal fun PositionType.intoSerde() = com.android.designcompose.serdegen.PositionType.Absolute() else -> throw IllegalArgumentException("Unknown PositionType: $this") // Should never happen } - -/** Temporary (I hope) conversion from the Proto layout style to the Serde layout style. */ -internal fun LayoutStyle.intoSerde() = - com.android.designcompose.serdegen.LayoutStyle( - Optional.of(margin.intoSerde()), - Optional.of(padding.intoSerde()), - itemSpacing.intoSerde(), - Optional.of(top.into()), - Optional.of(left.into()), - Optional.of(bottom.into()), - Optional.of(right.into()), - Optional.of(width.into()), - Optional.of(height.into()), - Optional.of(minWidth.into()), - Optional.of(maxWidth.into()), - Optional.of(minHeight.into()), - Optional.of(maxHeight.into()), - boundingBox.intoSerde(), - flexGrow, - flexShrink, - Optional.of(flexBasis.into()), - alignSelf.intoSerde(), - alignContent.intoSerde(), - alignItems.intoSerde(), - flexDirection.intoSerde(), - justifyContent.intoSerde(), - positionType.intoSerde(), - ) diff --git a/designcompose/src/main/java/com/android/designcompose/proto/ProtoEnums.kt b/designcompose/src/main/java/com/android/designcompose/proto/ProtoEnums.kt index 5415bb5bc..2b6a1d606 100644 --- a/designcompose/src/main/java/com/android/designcompose/proto/ProtoEnums.kt +++ b/designcompose/src/main/java/com/android/designcompose/proto/ProtoEnums.kt @@ -16,6 +16,12 @@ package com.android.designcompose.proto +import com.android.designcompose.serdegen.AlignContent +import com.android.designcompose.serdegen.AlignItems +import com.android.designcompose.serdegen.AlignSelf +import com.android.designcompose.serdegen.FlexDirection +import com.android.designcompose.serdegen.JustifyContent +import com.android.designcompose.serdegen.PositionType import com.android.designcompose.serdegen.ScaleMode import com.android.designcompose.serdegen.StrokeCap import com.android.designcompose.serdegen.Trigger @@ -164,3 +170,140 @@ internal fun strokeCapFromInt(value: Int): StrokeCap { else -> StrokeCap.Unspecified() } } + +internal fun alignItemsFromInt(value: Int) = + when (value) { + 1 -> AlignItems.FlexStart() + 2 -> AlignItems.FlexEnd() + 3 -> AlignItems.Center() + 4 -> AlignItems.Baseline() + 5 -> AlignItems.Stretch() + else -> AlignItems.Unspecified() + } + +internal fun AlignItems.toInt() = + when (this) { + is AlignItems.FlexStart -> 1 + is AlignItems.FlexEnd -> 2 + is AlignItems.Center -> 3 + is AlignItems.Baseline -> 4 + is AlignItems.Stretch -> 5 + else -> 0 + } + +internal fun alignSelfFromInt(value: Int) = + when (value) { + 1 -> AlignSelf.Auto() + 2 -> AlignSelf.FlexStart() + 3 -> AlignSelf.FlexEnd() + 4 -> AlignSelf.Center() + 5 -> AlignSelf.Baseline() + 6 -> AlignSelf.Stretch() + else -> AlignSelf.Unspecified() + } + +internal fun AlignSelf.toInt() = + when (this) { + is AlignSelf.Auto -> 1 + is AlignSelf.FlexStart -> 2 + is AlignSelf.FlexEnd -> 3 + is AlignSelf.Center -> 4 + is AlignSelf.Baseline -> 5 + is AlignSelf.Stretch -> 6 + else -> 0 + } + +internal fun alignContentFromInt(value: Int) = + when (value) { + 1 -> AlignContent.FlexStart() + 2 -> AlignContent.FlexEnd() + 3 -> AlignContent.Center() + 4 -> AlignContent.Stretch() + 5 -> AlignContent.SpaceBetween() + 6 -> AlignContent.SpaceAround() + else -> AlignContent.Unspecified() + } + +internal fun AlignContent.toInt() = + when (this) { + is AlignContent.FlexStart -> 1 + is AlignContent.FlexEnd -> 2 + is AlignContent.Center -> 3 + is AlignContent.Stretch -> 4 + is AlignContent.SpaceBetween -> 5 + is AlignContent.SpaceAround -> 6 + else -> 0 + } + +internal fun flexDirectionFromInt(value: Int) = + when (value) { + 1 -> FlexDirection.Row() + 2 -> FlexDirection.Column() + 3 -> FlexDirection.RowReverse() + 4 -> FlexDirection.ColumnReverse() + 5 -> FlexDirection.None() + else -> FlexDirection.Unspecified() + } + +internal fun FlexDirection.toInt() = + when (this) { + is FlexDirection.Row -> 1 + is FlexDirection.Column -> 2 + is FlexDirection.RowReverse -> 3 + is FlexDirection.ColumnReverse -> 4 + is FlexDirection.None -> 5 + else -> 0 + } + +internal fun justifyContentFromInt(value: Int) = + when (value) { + 1 -> JustifyContent.FlexStart() + 2 -> JustifyContent.FlexEnd() + 3 -> JustifyContent.Center() + 4 -> JustifyContent.SpaceBetween() + 5 -> JustifyContent.SpaceAround() + 6 -> JustifyContent.SpaceEvenly() + else -> JustifyContent.Unspecified() + } + +internal fun JustifyContent.toInt() = + when (this) { + is JustifyContent.FlexStart -> 1 + is JustifyContent.FlexEnd -> 2 + is JustifyContent.Center -> 3 + is JustifyContent.SpaceBetween -> 4 + is JustifyContent.SpaceAround -> 5 + is JustifyContent.SpaceEvenly -> 6 + else -> 0 + } + +internal fun positionTypeFromInt(value: Int) = + when (value) { + 1 -> PositionType.Relative() + 2 -> PositionType.Absolute() + else -> PositionType.Unspecified() + } + +internal fun PositionType.toInt() = + when (this) { + is PositionType.Relative -> 1 + is PositionType.Absolute -> 2 + else -> 0 + } + +internal fun overflowDirectionFromInt(value: Int) = + when (value) { + 1 -> com.android.designcompose.serdegen.OverflowDirection.None() + 2 -> com.android.designcompose.serdegen.OverflowDirection.HorizontalScrolling() + 3 -> com.android.designcompose.serdegen.OverflowDirection.VerticalScrolling() + 4 -> com.android.designcompose.serdegen.OverflowDirection.HorizontalAndVerticalScrolling() + else -> com.android.designcompose.serdegen.OverflowDirection.Unspecified() + } + +internal fun layoutSizingFromInt(value: Int) = + when (value) { + 1 -> com.android.designcompose.serdegen.LayoutSizing.Fixed() + 2 -> com.android.designcompose.serdegen.LayoutSizing.Hug() + 3 -> com.android.designcompose.serdegen.LayoutSizing.Fill() + else -> com.android.designcompose.serdegen.LayoutSizing.Unspecified() + } diff --git a/designcompose/src/main/java/com/android/designcompose/proto/ProtoUtils.kt b/designcompose/src/main/java/com/android/designcompose/proto/ProtoUtils.kt index d0e66796a..f93473bf1 100644 --- a/designcompose/src/main/java/com/android/designcompose/proto/ProtoUtils.kt +++ b/designcompose/src/main/java/com/android/designcompose/proto/ProtoUtils.kt @@ -20,6 +20,7 @@ import com.android.designcompose.serdegen.Background import com.android.designcompose.serdegen.BackgroundType import com.android.designcompose.serdegen.Box import com.android.designcompose.serdegen.FontWeight +import com.android.designcompose.serdegen.ItemSpacing import com.android.designcompose.serdegen.NumOrVar import com.android.designcompose.serdegen.NumOrVarType import com.android.designcompose.serdegen.Shape @@ -148,3 +149,5 @@ internal fun newViewShapeRect(isMask: Boolean) = ViewShape(Optional.of(Shape.Rec internal fun newFontWeight(weight: Float) = FontWeight(Optional.of(NumOrVar(Optional.of(NumOrVarType.Num(weight))))) + +internal fun ItemSpacing.type() = item_spacing_type.getOrNull() diff --git a/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshRoot.kt b/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshRoot.kt index 4e08aef99..2b7da18fd 100644 --- a/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshRoot.kt +++ b/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshRoot.kt @@ -29,7 +29,6 @@ import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.compositionLocalOf -import androidx.compose.runtime.getValue import androidx.compose.runtime.key import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -93,6 +92,7 @@ import com.android.designcompose.squooshCompleteAnimatedAction import com.android.designcompose.squooshFailedAnimatedAction import com.android.designcompose.squooshVariantMemory import com.android.designcompose.stateForDoc +import java.util.Optional import kotlin.collections.component1 import kotlin.collections.component2 import kotlin.collections.set @@ -146,7 +146,12 @@ private fun SquooshResolvedNode.applyLayoutConstraints(constraints: Constraints, layoutStyleBuilder.width = newDimensionProtoPoints(constraints.minWidth.toFloat() / density) // Layout implementation looks for width/height being set and then uses bounding box. layoutStyleBuilder.bounding_box = - Size(constraints.minWidth.toFloat() / density, layoutStyleBuilder.bounding_box.height) + Optional.of( + Size( + constraints.minWidth.toFloat() / density, + layoutStyleBuilder.bounding_box.get().height, + ) + ) } if (constraints.minHeight != 0) @@ -162,7 +167,12 @@ private fun SquooshResolvedNode.applyLayoutConstraints(constraints: Constraints, newDimensionProtoPoints(constraints.minHeight.toFloat() / density) // Layout implementation looks for width/height being set and then uses bounding box. layoutStyleBuilder.bounding_box = - Size(layoutStyleBuilder.bounding_box.width, constraints.minHeight.toFloat() / density) + Optional.of( + Size( + layoutStyleBuilder.bounding_box.get().width, + constraints.minHeight.toFloat() / density, + ) + ) } rootStyleBuilder.layout_style = layoutStyleBuilder.build() diff --git a/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshTreeBuilder.kt b/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshTreeBuilder.kt index 9b7bfdbde..7253454af 100644 --- a/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshTreeBuilder.kt +++ b/designcompose/src/main/java/com/android/designcompose/squoosh/SquooshTreeBuilder.kt @@ -45,6 +45,7 @@ import com.android.designcompose.proto.newDimensionProtoPercent import com.android.designcompose.proto.newViewShapeRect import com.android.designcompose.proto.overlayBackgroundInteractionFromInt import com.android.designcompose.proto.overlayPositionEnumFromInt +import com.android.designcompose.proto.toInt import com.android.designcompose.proto.type import com.android.designcompose.serdegen.Action import com.android.designcompose.serdegen.ActionType @@ -462,7 +463,7 @@ private fun generateReplacementListChildNode( val listChildScrollInfo = ScrollInfo.Builder() listChildScrollInfo.paged_scrolling = false - listChildScrollInfo.overflow = OverflowDirection.NONE() + listChildScrollInfo.overflow = OverflowDirection.None() val listChildView = View.Builder() listChildView.unique_id = 0 // This is unused. @@ -511,44 +512,44 @@ private fun generateOverlayNode( val layoutStyle = node.style.layout_style.asBuilder() val nodeStyle = node.style.node_style.asBuilder() nodeStyle.overflow = Overflow.Visible() - layoutStyle.position_type = PositionType.Absolute() + layoutStyle.position_type = PositionType.Absolute().toInt() layoutStyle.top = newDimensionProtoPercent(0.0f) layoutStyle.left = newDimensionProtoPercent(0.0f) layoutStyle.right = newDimensionProtoPercent(0.0f) layoutStyle.bottom = newDimensionProtoPercent(0.0f) layoutStyle.width = newDimensionProtoPercent(1.0f) layoutStyle.height = newDimensionProtoPercent(1.0f) - layoutStyle.flex_direction = FlexDirection.Column() + layoutStyle.flex_direction = FlexDirection.Column().toInt() when (overlayPositionEnumFromInt(overlay.overlay_position_type)) { OverlayPositionEnum.TOP_LEFT -> { - layoutStyle.justify_content = JustifyContent.FlexStart() // Y - layoutStyle.align_items = AlignItems.FlexStart() // X + layoutStyle.justify_content = JustifyContent.FlexStart().toInt() // Y + layoutStyle.align_items = AlignItems.FlexStart().toInt() // X } OverlayPositionEnum.TOP_CENTER -> { - layoutStyle.justify_content = JustifyContent.FlexStart() // Y - layoutStyle.align_items = AlignItems.Center() // X + layoutStyle.justify_content = JustifyContent.FlexStart().toInt() // Y + layoutStyle.align_items = AlignItems.Center().toInt() // X } OverlayPositionEnum.TOP_RIGHT -> { - layoutStyle.justify_content = JustifyContent.FlexStart() // Y - layoutStyle.align_items = AlignItems.FlexEnd() // X + layoutStyle.justify_content = JustifyContent.FlexStart().toInt() // Y + layoutStyle.align_items = AlignItems.FlexEnd().toInt() // X } OverlayPositionEnum.BOTTOM_LEFT -> { - layoutStyle.justify_content = JustifyContent.FlexEnd() // Y - layoutStyle.align_items = AlignItems.FlexStart() // X + layoutStyle.justify_content = JustifyContent.FlexEnd().toInt() // Y + layoutStyle.align_items = AlignItems.FlexStart().toInt() // X } OverlayPositionEnum.BOTTOM_CENTER -> { - layoutStyle.justify_content = JustifyContent.FlexEnd() // Y - layoutStyle.align_items = AlignItems.Center() // X + layoutStyle.justify_content = JustifyContent.FlexEnd().toInt() // Y + layoutStyle.align_items = AlignItems.Center().toInt() // X } OverlayPositionEnum.BOTTOM_RIGHT -> { - layoutStyle.justify_content = JustifyContent.FlexEnd() // Y - layoutStyle.align_items = AlignItems.FlexEnd() // X + layoutStyle.justify_content = JustifyContent.FlexEnd().toInt() // Y + layoutStyle.align_items = AlignItems.FlexEnd().toInt() // X } // Center and Manual both are centered; not clear how to implement manual positioning // without making a layout-dependent query. else -> { - layoutStyle.justify_content = JustifyContent.Center() - layoutStyle.align_items = AlignItems.Center() + layoutStyle.justify_content = JustifyContent.Center().toInt() + layoutStyle.align_items = AlignItems.Center().toInt() } } nodeStyle.background = listOf() @@ -581,7 +582,7 @@ private fun generateOverlayNode( val overlayScrollInfo = ScrollInfo.Builder() overlayScrollInfo.paged_scrolling = false - overlayScrollInfo.overflow = OverflowDirection.NONE() + overlayScrollInfo.overflow = OverflowDirection.None() val overlayView = View.Builder() overlayView.unique_id = (node.view.unique_id + 0x2000).toShort() diff --git a/designcompose/src/testDebug/res/raw/raw_resource_test_hello_world_doc b/designcompose/src/testDebug/res/raw/raw_resource_test_hello_world_doc index d9f32c662..39e89bc8a 100644 Binary files a/designcompose/src/testDebug/res/raw/raw_resource_test_hello_world_doc and b/designcompose/src/testDebug/res/raw/raw_resource_test_hello_world_doc differ diff --git a/integration-tests/validation/src/main/assets/figma/AlignmentTestDoc_JIjE9oKQbq8ipi66ab5UaK.dcf b/integration-tests/validation/src/main/assets/figma/AlignmentTestDoc_JIjE9oKQbq8ipi66ab5UaK.dcf index 57ba8a700..d7e117e2e 100644 Binary files a/integration-tests/validation/src/main/assets/figma/AlignmentTestDoc_JIjE9oKQbq8ipi66ab5UaK.dcf and b/integration-tests/validation/src/main/assets/figma/AlignmentTestDoc_JIjE9oKQbq8ipi66ab5UaK.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/BattleshipDoc_RfGl9SWnBEvdg8T1Ex6ZAR.dcf b/integration-tests/validation/src/main/assets/figma/BattleshipDoc_RfGl9SWnBEvdg8T1Ex6ZAR.dcf index 709bd74ad..ce1186db9 100644 Binary files a/integration-tests/validation/src/main/assets/figma/BattleshipDoc_RfGl9SWnBEvdg8T1Ex6ZAR.dcf and b/integration-tests/validation/src/main/assets/figma/BattleshipDoc_RfGl9SWnBEvdg8T1Ex6ZAR.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/BlendModeTestDoc_ZqX5i5g6inv9tANIwMMXUV.dcf b/integration-tests/validation/src/main/assets/figma/BlendModeTestDoc_ZqX5i5g6inv9tANIwMMXUV.dcf index c946a4113..dd6b79acc 100644 Binary files a/integration-tests/validation/src/main/assets/figma/BlendModeTestDoc_ZqX5i5g6inv9tANIwMMXUV.dcf and b/integration-tests/validation/src/main/assets/figma/BlendModeTestDoc_ZqX5i5g6inv9tANIwMMXUV.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/ColorTintTestDoc_MCtUD3yjONxK6rQm65yqM5.dcf b/integration-tests/validation/src/main/assets/figma/ColorTintTestDoc_MCtUD3yjONxK6rQm65yqM5.dcf index b11775293..731f7f549 100644 Binary files a/integration-tests/validation/src/main/assets/figma/ColorTintTestDoc_MCtUD3yjONxK6rQm65yqM5.dcf and b/integration-tests/validation/src/main/assets/figma/ColorTintTestDoc_MCtUD3yjONxK6rQm65yqM5.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/ComponentReplaceDoc_bQVVy2GSZJ8veYaJUrG6Ni.dcf b/integration-tests/validation/src/main/assets/figma/ComponentReplaceDoc_bQVVy2GSZJ8veYaJUrG6Ni.dcf index 2ac586df5..832198f9b 100644 Binary files a/integration-tests/validation/src/main/assets/figma/ComponentReplaceDoc_bQVVy2GSZJ8veYaJUrG6Ni.dcf and b/integration-tests/validation/src/main/assets/figma/ComponentReplaceDoc_bQVVy2GSZJ8veYaJUrG6Ni.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/ComponentReplaceRelayoutDoc_qIh0IOQTCtgeAWZFF5gYSk.dcf b/integration-tests/validation/src/main/assets/figma/ComponentReplaceRelayoutDoc_qIh0IOQTCtgeAWZFF5gYSk.dcf index 5d5735451..d43b50ca5 100644 Binary files a/integration-tests/validation/src/main/assets/figma/ComponentReplaceRelayoutDoc_qIh0IOQTCtgeAWZFF5gYSk.dcf and b/integration-tests/validation/src/main/assets/figma/ComponentReplaceRelayoutDoc_qIh0IOQTCtgeAWZFF5gYSk.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/ComponentTapCallbackDoc_1jeKYynjk1nqYblZ66QDDK.dcf b/integration-tests/validation/src/main/assets/figma/ComponentTapCallbackDoc_1jeKYynjk1nqYblZ66QDDK.dcf index 7e3545a9d..de1ab4a3b 100644 Binary files a/integration-tests/validation/src/main/assets/figma/ComponentTapCallbackDoc_1jeKYynjk1nqYblZ66QDDK.dcf and b/integration-tests/validation/src/main/assets/figma/ComponentTapCallbackDoc_1jeKYynjk1nqYblZ66QDDK.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/ConstraintsDoc_KuHLbsKA23DjZPhhgHqt71.dcf b/integration-tests/validation/src/main/assets/figma/ConstraintsDoc_KuHLbsKA23DjZPhhgHqt71.dcf index cb571eaec..9ba37fa96 100644 Binary files a/integration-tests/validation/src/main/assets/figma/ConstraintsDoc_KuHLbsKA23DjZPhhgHqt71.dcf and b/integration-tests/validation/src/main/assets/figma/ConstraintsDoc_KuHLbsKA23DjZPhhgHqt71.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/CrossAxisFillTestDoc_GPr1cx4n3zBPwLhqlSL1ba.dcf b/integration-tests/validation/src/main/assets/figma/CrossAxisFillTestDoc_GPr1cx4n3zBPwLhqlSL1ba.dcf index 5b8c1601e..01d2d98a6 100644 Binary files a/integration-tests/validation/src/main/assets/figma/CrossAxisFillTestDoc_GPr1cx4n3zBPwLhqlSL1ba.dcf and b/integration-tests/validation/src/main/assets/figma/CrossAxisFillTestDoc_GPr1cx4n3zBPwLhqlSL1ba.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/CustomBrushTestDoc_oetCBVw8gCAxmCNllXx7zO.dcf b/integration-tests/validation/src/main/assets/figma/CustomBrushTestDoc_oetCBVw8gCAxmCNllXx7zO.dcf index 76b76dbbf..a5d3d258f 100644 Binary files a/integration-tests/validation/src/main/assets/figma/CustomBrushTestDoc_oetCBVw8gCAxmCNllXx7zO.dcf and b/integration-tests/validation/src/main/assets/figma/CustomBrushTestDoc_oetCBVw8gCAxmCNllXx7zO.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/DialsGaugesTestDoc_lZj6E9GtIQQE4HNLpzgETw.dcf b/integration-tests/validation/src/main/assets/figma/DialsGaugesTestDoc_lZj6E9GtIQQE4HNLpzgETw.dcf index 8b40dfcb5..db96c42bb 100644 Binary files a/integration-tests/validation/src/main/assets/figma/DialsGaugesTestDoc_lZj6E9GtIQQE4HNLpzgETw.dcf and b/integration-tests/validation/src/main/assets/figma/DialsGaugesTestDoc_lZj6E9GtIQQE4HNLpzgETw.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/FancyFillTestDoc_xQ9cunHt8VUm6xqJJ2Pjb2.dcf b/integration-tests/validation/src/main/assets/figma/FancyFillTestDoc_xQ9cunHt8VUm6xqJJ2Pjb2.dcf index 95669cfa0..ecc7b2caf 100644 Binary files a/integration-tests/validation/src/main/assets/figma/FancyFillTestDoc_xQ9cunHt8VUm6xqJJ2Pjb2.dcf and b/integration-tests/validation/src/main/assets/figma/FancyFillTestDoc_xQ9cunHt8VUm6xqJJ2Pjb2.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/FillTestDoc_dB3q96FkxkTO4czn5NqnxV.dcf b/integration-tests/validation/src/main/assets/figma/FillTestDoc_dB3q96FkxkTO4czn5NqnxV.dcf index d67dfc423..2018dffcb 100644 Binary files a/integration-tests/validation/src/main/assets/figma/FillTestDoc_dB3q96FkxkTO4czn5NqnxV.dcf and b/integration-tests/validation/src/main/assets/figma/FillTestDoc_dB3q96FkxkTO4czn5NqnxV.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/GridLayoutDoc_MBNjjSbzzKeN7nBjVoewsl.dcf b/integration-tests/validation/src/main/assets/figma/GridLayoutDoc_MBNjjSbzzKeN7nBjVoewsl.dcf index eb405382e..eadf5ea5d 100644 Binary files a/integration-tests/validation/src/main/assets/figma/GridLayoutDoc_MBNjjSbzzKeN7nBjVoewsl.dcf and b/integration-tests/validation/src/main/assets/figma/GridLayoutDoc_MBNjjSbzzKeN7nBjVoewsl.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/GridLayoutTestDoc_JOSOEvsrjvMqanyQa5OpNR.dcf b/integration-tests/validation/src/main/assets/figma/GridLayoutTestDoc_JOSOEvsrjvMqanyQa5OpNR.dcf index bf24891d6..f923a59e2 100644 Binary files a/integration-tests/validation/src/main/assets/figma/GridLayoutTestDoc_JOSOEvsrjvMqanyQa5OpNR.dcf and b/integration-tests/validation/src/main/assets/figma/GridLayoutTestDoc_JOSOEvsrjvMqanyQa5OpNR.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/GridWidgetTestDoc_OBhNItd9i9J2LwVYuLxEIx.dcf b/integration-tests/validation/src/main/assets/figma/GridWidgetTestDoc_OBhNItd9i9J2LwVYuLxEIx.dcf index 8a2ce4e47..5838ef5bc 100644 Binary files a/integration-tests/validation/src/main/assets/figma/GridWidgetTestDoc_OBhNItd9i9J2LwVYuLxEIx.dcf and b/integration-tests/validation/src/main/assets/figma/GridWidgetTestDoc_OBhNItd9i9J2LwVYuLxEIx.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/HelloByeDoc_MCHaMYcIEnRpbvU9Ms7a0o.dcf b/integration-tests/validation/src/main/assets/figma/HelloByeDoc_MCHaMYcIEnRpbvU9Ms7a0o.dcf index ccdf12258..ed1e6afd0 100644 Binary files a/integration-tests/validation/src/main/assets/figma/HelloByeDoc_MCHaMYcIEnRpbvU9Ms7a0o.dcf and b/integration-tests/validation/src/main/assets/figma/HelloByeDoc_MCHaMYcIEnRpbvU9Ms7a0o.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/HelloVersionDoc_v62Vwlxa4Bb6nopJiAxQAQ_5668177823.dcf b/integration-tests/validation/src/main/assets/figma/HelloVersionDoc_v62Vwlxa4Bb6nopJiAxQAQ_5668177823.dcf index 15ca7808b..b67d73887 100644 Binary files a/integration-tests/validation/src/main/assets/figma/HelloVersionDoc_v62Vwlxa4Bb6nopJiAxQAQ_5668177823.dcf and b/integration-tests/validation/src/main/assets/figma/HelloVersionDoc_v62Vwlxa4Bb6nopJiAxQAQ_5668177823.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/HelloWorldDoc_pxVlixodJqZL95zo2RzTHl.dcf b/integration-tests/validation/src/main/assets/figma/HelloWorldDoc_pxVlixodJqZL95zo2RzTHl.dcf index 5e67f350f..8f907a450 100644 Binary files a/integration-tests/validation/src/main/assets/figma/HelloWorldDoc_pxVlixodJqZL95zo2RzTHl.dcf and b/integration-tests/validation/src/main/assets/figma/HelloWorldDoc_pxVlixodJqZL95zo2RzTHl.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/HyperlinkValidationDoc_uBExbEg4lcRa0xN2yaLTX8.dcf b/integration-tests/validation/src/main/assets/figma/HyperlinkValidationDoc_uBExbEg4lcRa0xN2yaLTX8.dcf index 9b70993c6..7e9d514c6 100644 Binary files a/integration-tests/validation/src/main/assets/figma/HyperlinkValidationDoc_uBExbEg4lcRa0xN2yaLTX8.dcf and b/integration-tests/validation/src/main/assets/figma/HyperlinkValidationDoc_uBExbEg4lcRa0xN2yaLTX8.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/IgnoreAutoLayoutTestDoc_vPNR6N02HfdcpC8wR5yBYP.dcf b/integration-tests/validation/src/main/assets/figma/IgnoreAutoLayoutTestDoc_vPNR6N02HfdcpC8wR5yBYP.dcf index 393b34e3e..75e7cc2d9 100644 Binary files a/integration-tests/validation/src/main/assets/figma/IgnoreAutoLayoutTestDoc_vPNR6N02HfdcpC8wR5yBYP.dcf and b/integration-tests/validation/src/main/assets/figma/IgnoreAutoLayoutTestDoc_vPNR6N02HfdcpC8wR5yBYP.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/ImageUpdateTestDoc_oQw7kiy94fvdVouCYBC9T0.dcf b/integration-tests/validation/src/main/assets/figma/ImageUpdateTestDoc_oQw7kiy94fvdVouCYBC9T0.dcf index 5f1fa8445..b4708bd75 100644 Binary files a/integration-tests/validation/src/main/assets/figma/ImageUpdateTestDoc_oQw7kiy94fvdVouCYBC9T0.dcf and b/integration-tests/validation/src/main/assets/figma/ImageUpdateTestDoc_oQw7kiy94fvdVouCYBC9T0.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/InteractionTestDoc_8Zg9viyjYTnyN29pbkR1CE.dcf b/integration-tests/validation/src/main/assets/figma/InteractionTestDoc_8Zg9viyjYTnyN29pbkR1CE.dcf index 85efc058e..98d7c345b 100644 Binary files a/integration-tests/validation/src/main/assets/figma/InteractionTestDoc_8Zg9viyjYTnyN29pbkR1CE.dcf and b/integration-tests/validation/src/main/assets/figma/InteractionTestDoc_8Zg9viyjYTnyN29pbkR1CE.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/ItemSpacingTestDoc_YXrHBp6C6OaW5ShcCYeGJc.dcf b/integration-tests/validation/src/main/assets/figma/ItemSpacingTestDoc_YXrHBp6C6OaW5ShcCYeGJc.dcf index a52b0f68a..3f078398a 100644 Binary files a/integration-tests/validation/src/main/assets/figma/ItemSpacingTestDoc_YXrHBp6C6OaW5ShcCYeGJc.dcf and b/integration-tests/validation/src/main/assets/figma/ItemSpacingTestDoc_YXrHBp6C6OaW5ShcCYeGJc.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/LayoutReplacementTestDoc_dwk2GF7RiNvlbbAKPjqldx.dcf b/integration-tests/validation/src/main/assets/figma/LayoutReplacementTestDoc_dwk2GF7RiNvlbbAKPjqldx.dcf index a52f378d6..9f4cf8572 100644 Binary files a/integration-tests/validation/src/main/assets/figma/LayoutReplacementTestDoc_dwk2GF7RiNvlbbAKPjqldx.dcf and b/integration-tests/validation/src/main/assets/figma/LayoutReplacementTestDoc_dwk2GF7RiNvlbbAKPjqldx.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/LayoutTestsDoc_Gv63fYTzpeH2ZtxP4go31E.dcf b/integration-tests/validation/src/main/assets/figma/LayoutTestsDoc_Gv63fYTzpeH2ZtxP4go31E.dcf index 2172f45e3..c3961590a 100644 Binary files a/integration-tests/validation/src/main/assets/figma/LayoutTestsDoc_Gv63fYTzpeH2ZtxP4go31E.dcf and b/integration-tests/validation/src/main/assets/figma/LayoutTestsDoc_Gv63fYTzpeH2ZtxP4go31E.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/ListWidgetTestDoc_9ev0MBNHFrgTqJOrAGcEpV.dcf b/integration-tests/validation/src/main/assets/figma/ListWidgetTestDoc_9ev0MBNHFrgTqJOrAGcEpV.dcf index aa6882318..04f9864fd 100644 Binary files a/integration-tests/validation/src/main/assets/figma/ListWidgetTestDoc_9ev0MBNHFrgTqJOrAGcEpV.dcf and b/integration-tests/validation/src/main/assets/figma/ListWidgetTestDoc_9ev0MBNHFrgTqJOrAGcEpV.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/MaskTestDoc_mEmdUVEIjvBBbV0kELPy37.dcf b/integration-tests/validation/src/main/assets/figma/MaskTestDoc_mEmdUVEIjvBBbV0kELPy37.dcf index 4f7f49709..ff233c347 100644 Binary files a/integration-tests/validation/src/main/assets/figma/MaskTestDoc_mEmdUVEIjvBBbV0kELPy37.dcf and b/integration-tests/validation/src/main/assets/figma/MaskTestDoc_mEmdUVEIjvBBbV0kELPy37.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/ModuleExampleDoc_hPEGkrF0LUqNYEZObXqjXZ.dcf b/integration-tests/validation/src/main/assets/figma/ModuleExampleDoc_hPEGkrF0LUqNYEZObXqjXZ.dcf index 6a32ff326..b7a39b63c 100644 Binary files a/integration-tests/validation/src/main/assets/figma/ModuleExampleDoc_hPEGkrF0LUqNYEZObXqjXZ.dcf and b/integration-tests/validation/src/main/assets/figma/ModuleExampleDoc_hPEGkrF0LUqNYEZObXqjXZ.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/OnePxSeparatorDoc_EXjTHxfMNBtXDrz8hr6MFB.dcf b/integration-tests/validation/src/main/assets/figma/OnePxSeparatorDoc_EXjTHxfMNBtXDrz8hr6MFB.dcf index fa414949a..4e789eb56 100644 Binary files a/integration-tests/validation/src/main/assets/figma/OnePxSeparatorDoc_EXjTHxfMNBtXDrz8hr6MFB.dcf and b/integration-tests/validation/src/main/assets/figma/OnePxSeparatorDoc_EXjTHxfMNBtXDrz8hr6MFB.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/OpenLinkTestDoc_r7m4tqyKv6y9DWcg7QBEDf.dcf b/integration-tests/validation/src/main/assets/figma/OpenLinkTestDoc_r7m4tqyKv6y9DWcg7QBEDf.dcf index 73cc970d9..ab506c049 100644 Binary files a/integration-tests/validation/src/main/assets/figma/OpenLinkTestDoc_r7m4tqyKv6y9DWcg7QBEDf.dcf and b/integration-tests/validation/src/main/assets/figma/OpenLinkTestDoc_r7m4tqyKv6y9DWcg7QBEDf.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/RecursiveCustomizationsDoc_o0GWzcqdOWEgzj4kIeIlAu.dcf b/integration-tests/validation/src/main/assets/figma/RecursiveCustomizationsDoc_o0GWzcqdOWEgzj4kIeIlAu.dcf index ed76321a9..dd87b2707 100644 Binary files a/integration-tests/validation/src/main/assets/figma/RecursiveCustomizationsDoc_o0GWzcqdOWEgzj4kIeIlAu.dcf and b/integration-tests/validation/src/main/assets/figma/RecursiveCustomizationsDoc_o0GWzcqdOWEgzj4kIeIlAu.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/ShadowsTestDoc_OqK58Y46IqP4wIgKCWys48.dcf b/integration-tests/validation/src/main/assets/figma/ShadowsTestDoc_OqK58Y46IqP4wIgKCWys48.dcf index 554d2e9f6..621fd352c 100644 Binary files a/integration-tests/validation/src/main/assets/figma/ShadowsTestDoc_OqK58Y46IqP4wIgKCWys48.dcf and b/integration-tests/validation/src/main/assets/figma/ShadowsTestDoc_OqK58Y46IqP4wIgKCWys48.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/SmartAnimateTestDoc_RW3lFurXCoVDeqY2Y7bf4v.dcf b/integration-tests/validation/src/main/assets/figma/SmartAnimateTestDoc_RW3lFurXCoVDeqY2Y7bf4v.dcf index 46192f986..84f8699c1 100644 Binary files a/integration-tests/validation/src/main/assets/figma/SmartAnimateTestDoc_RW3lFurXCoVDeqY2Y7bf4v.dcf and b/integration-tests/validation/src/main/assets/figma/SmartAnimateTestDoc_RW3lFurXCoVDeqY2Y7bf4v.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/StateCustomizationsDoc_POWyniB6moGRmhZTJyejwa.dcf b/integration-tests/validation/src/main/assets/figma/StateCustomizationsDoc_POWyniB6moGRmhZTJyejwa.dcf index d1806948c..959381f4f 100644 Binary files a/integration-tests/validation/src/main/assets/figma/StateCustomizationsDoc_POWyniB6moGRmhZTJyejwa.dcf and b/integration-tests/validation/src/main/assets/figma/StateCustomizationsDoc_POWyniB6moGRmhZTJyejwa.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/StyledTextRunsDoc_mIYV4YsYYaMTsBMCVskA4N.dcf b/integration-tests/validation/src/main/assets/figma/StyledTextRunsDoc_mIYV4YsYYaMTsBMCVskA4N.dcf index 2d5935a95..cfc3f1836 100644 Binary files a/integration-tests/validation/src/main/assets/figma/StyledTextRunsDoc_mIYV4YsYYaMTsBMCVskA4N.dcf and b/integration-tests/validation/src/main/assets/figma/StyledTextRunsDoc_mIYV4YsYYaMTsBMCVskA4N.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/TelltaleTestDoc_TZgHrKWx8wvQM7UPTyEpmz.dcf b/integration-tests/validation/src/main/assets/figma/TelltaleTestDoc_TZgHrKWx8wvQM7UPTyEpmz.dcf index 6c119e798..d3f8736ec 100644 Binary files a/integration-tests/validation/src/main/assets/figma/TelltaleTestDoc_TZgHrKWx8wvQM7UPTyEpmz.dcf and b/integration-tests/validation/src/main/assets/figma/TelltaleTestDoc_TZgHrKWx8wvQM7UPTyEpmz.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/TextElideTestDoc_oQ7nK49Ya5PJ3GpjI5iy8d.dcf b/integration-tests/validation/src/main/assets/figma/TextElideTestDoc_oQ7nK49Ya5PJ3GpjI5iy8d.dcf index 32a2e6eed..7c32de4ae 100644 Binary files a/integration-tests/validation/src/main/assets/figma/TextElideTestDoc_oQ7nK49Ya5PJ3GpjI5iy8d.dcf and b/integration-tests/validation/src/main/assets/figma/TextElideTestDoc_oQ7nK49Ya5PJ3GpjI5iy8d.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/TextResizingTestDoc_kAoYvgHkPzA4J4pALZ3Xhg.dcf b/integration-tests/validation/src/main/assets/figma/TextResizingTestDoc_kAoYvgHkPzA4J4pALZ3Xhg.dcf index 1e1b1ed13..098daf1f8 100644 Binary files a/integration-tests/validation/src/main/assets/figma/TextResizingTestDoc_kAoYvgHkPzA4J4pALZ3Xhg.dcf and b/integration-tests/validation/src/main/assets/figma/TextResizingTestDoc_kAoYvgHkPzA4J4pALZ3Xhg.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/VariableBorderTestDoc_MWnVAfW3FupV4VMLNR1m67.dcf b/integration-tests/validation/src/main/assets/figma/VariableBorderTestDoc_MWnVAfW3FupV4VMLNR1m67.dcf index 614958c42..fbc1fd56e 100644 Binary files a/integration-tests/validation/src/main/assets/figma/VariableBorderTestDoc_MWnVAfW3FupV4VMLNR1m67.dcf and b/integration-tests/validation/src/main/assets/figma/VariableBorderTestDoc_MWnVAfW3FupV4VMLNR1m67.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/VariablesTestDoc_HhGxvL4aHhP8ALsLNz56TP.dcf b/integration-tests/validation/src/main/assets/figma/VariablesTestDoc_HhGxvL4aHhP8ALsLNz56TP.dcf index 4841c44e9..3793efd9f 100644 Binary files a/integration-tests/validation/src/main/assets/figma/VariablesTestDoc_HhGxvL4aHhP8ALsLNz56TP.dcf and b/integration-tests/validation/src/main/assets/figma/VariablesTestDoc_HhGxvL4aHhP8ALsLNz56TP.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/VariantAnimationTestDoc_pghyUUhlzJNoxxSK86ngiw.dcf b/integration-tests/validation/src/main/assets/figma/VariantAnimationTestDoc_pghyUUhlzJNoxxSK86ngiw.dcf index d43aaf3a1..7aeeb5c99 100644 Binary files a/integration-tests/validation/src/main/assets/figma/VariantAnimationTestDoc_pghyUUhlzJNoxxSK86ngiw.dcf and b/integration-tests/validation/src/main/assets/figma/VariantAnimationTestDoc_pghyUUhlzJNoxxSK86ngiw.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/VariantAnimationTimelineTestDoc_vJRf4zxY4QX4zzSSUd1nJ5.dcf b/integration-tests/validation/src/main/assets/figma/VariantAnimationTimelineTestDoc_vJRf4zxY4QX4zzSSUd1nJ5.dcf index 4bdfddafa..4862e098e 100644 Binary files a/integration-tests/validation/src/main/assets/figma/VariantAnimationTimelineTestDoc_vJRf4zxY4QX4zzSSUd1nJ5.dcf and b/integration-tests/validation/src/main/assets/figma/VariantAnimationTimelineTestDoc_vJRf4zxY4QX4zzSSUd1nJ5.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/VariantAsteriskTestDoc_gQeYHGCSaBE4zYSFpBrhre.dcf b/integration-tests/validation/src/main/assets/figma/VariantAsteriskTestDoc_gQeYHGCSaBE4zYSFpBrhre.dcf index 324d561e0..ae6d6a177 100644 Binary files a/integration-tests/validation/src/main/assets/figma/VariantAsteriskTestDoc_gQeYHGCSaBE4zYSFpBrhre.dcf and b/integration-tests/validation/src/main/assets/figma/VariantAsteriskTestDoc_gQeYHGCSaBE4zYSFpBrhre.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/VariantInteractionsTestDoc_WcsgoLR4aDRSkZHY29Qdhq.dcf b/integration-tests/validation/src/main/assets/figma/VariantInteractionsTestDoc_WcsgoLR4aDRSkZHY29Qdhq.dcf index cf952c6d4..99807033f 100644 Binary files a/integration-tests/validation/src/main/assets/figma/VariantInteractionsTestDoc_WcsgoLR4aDRSkZHY29Qdhq.dcf and b/integration-tests/validation/src/main/assets/figma/VariantInteractionsTestDoc_WcsgoLR4aDRSkZHY29Qdhq.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/VariantPropertiesTestDoc_4P7zDdrQxj7FZsKJoIQcx1.dcf b/integration-tests/validation/src/main/assets/figma/VariantPropertiesTestDoc_4P7zDdrQxj7FZsKJoIQcx1.dcf index d37dd5f79..b7d2dabe2 100644 Binary files a/integration-tests/validation/src/main/assets/figma/VariantPropertiesTestDoc_4P7zDdrQxj7FZsKJoIQcx1.dcf and b/integration-tests/validation/src/main/assets/figma/VariantPropertiesTestDoc_4P7zDdrQxj7FZsKJoIQcx1.dcf differ diff --git a/integration-tests/validation/src/main/assets/figma/VectorRenderingTestDoc_Z3ucY0wMAbIwZIa6mLEWIK.dcf b/integration-tests/validation/src/main/assets/figma/VectorRenderingTestDoc_Z3ucY0wMAbIwZIa6mLEWIK.dcf index 3a9f140fd..03e9f85b6 100644 Binary files a/integration-tests/validation/src/main/assets/figma/VectorRenderingTestDoc_Z3ucY0wMAbIwZIa6mLEWIK.dcf and b/integration-tests/validation/src/main/assets/figma/VectorRenderingTestDoc_Z3ucY0wMAbIwZIa6mLEWIK.dcf differ diff --git a/proto/definition/layout/positioning.proto b/proto/definition/layout/positioning.proto index 3298d03fb..11ce34f76 100644 --- a/proto/definition/layout/positioning.proto +++ b/proto/definition/layout/positioning.proto @@ -121,7 +121,7 @@ message ItemSpacing { int32 width = 1; int32 height = 2; } - oneof type { + oneof ItemSpacingType { int32 fixed = 1; Auto auto = 2; } diff --git a/reference-apps/helloworld/helloworld-app/src/main/assets/figma/HelloWorldDoc_pxVlixodJqZL95zo2RzTHl.dcf b/reference-apps/helloworld/helloworld-app/src/main/assets/figma/HelloWorldDoc_pxVlixodJqZL95zo2RzTHl.dcf index d9f32c662..39e89bc8a 100644 Binary files a/reference-apps/helloworld/helloworld-app/src/main/assets/figma/HelloWorldDoc_pxVlixodJqZL95zo2RzTHl.dcf and b/reference-apps/helloworld/helloworld-app/src/main/assets/figma/HelloWorldDoc_pxVlixodJqZL95zo2RzTHl.dcf differ diff --git a/reference-apps/tutorial/app/src/main/assets/figma/TutorialDoc_3z4xExq0INrL9vxPhj9tl7.dcf b/reference-apps/tutorial/app/src/main/assets/figma/TutorialDoc_3z4xExq0INrL9vxPhj9tl7.dcf index 73aef7a3a..e7a446eab 100644 Binary files a/reference-apps/tutorial/app/src/main/assets/figma/TutorialDoc_3z4xExq0INrL9vxPhj9tl7.dcf and b/reference-apps/tutorial/app/src/main/assets/figma/TutorialDoc_3z4xExq0INrL9vxPhj9tl7.dcf differ