diff --git a/crates/components/src/gesture_area.rs b/crates/components/src/gesture_area.rs index 6c69c7b0c..8be23dabb 100644 --- a/crates/components/src/gesture_area.rs +++ b/crates/components/src/gesture_area.rs @@ -197,8 +197,13 @@ mod test { rsx!( GestureArea { ongesture, - "{value}" + rect { + width: "100%", + height: "100%", + + } } + "{value}" ) } @@ -207,7 +212,7 @@ mod test { // Initial state utils.wait_for_update().await; - assert_eq!(utils.root().get(0).get(0).text(), Some("EMPTY")); + assert_eq!(utils.root().get(1).text(), Some("EMPTY")); utils.push_event(FreyaEvent::Touch { name: "touchstart".to_string(), @@ -241,7 +246,7 @@ mod test { utils.wait_for_update().await; utils.wait_for_update().await; - assert_eq!(utils.root().get(0).get(0).text(), Some("DoubleTap")); + assert_eq!(utils.root().get(1).text(), Some("DoubleTap")); } /// Simulates `TapUp` and `TapDown` gestures. @@ -257,8 +262,13 @@ mod test { rsx!( GestureArea { ongesture, - "{value}" + rect { + width: "100%", + height: "100%", + + } } + "{value}" ) } @@ -267,7 +277,7 @@ mod test { // Initial state utils.wait_for_update().await; - assert_eq!(utils.root().get(0).get(0).text(), Some("EMPTY")); + assert_eq!(utils.root().get(1).text(), Some("EMPTY")); utils.push_event(FreyaEvent::Touch { name: "touchstart".to_string(), @@ -280,7 +290,7 @@ mod test { utils.wait_for_update().await; utils.wait_for_update().await; - assert_eq!(utils.root().get(0).get(0).text(), Some("TapDown")); + assert_eq!(utils.root().get(1).text(), Some("TapDown")); utils.push_event(FreyaEvent::Touch { name: "touchend".to_string(), @@ -293,6 +303,6 @@ mod test { utils.wait_for_update().await; utils.wait_for_update().await; - assert_eq!(utils.root().get(0).get(0).text(), Some("TapUp")); + assert_eq!(utils.root().get(1).text(), Some("TapUp")); } } diff --git a/crates/core/src/layout/skia_measurer.rs b/crates/core/src/layout/skia_measurer.rs index 7d167e5a1..fb3a6b620 100644 --- a/crates/core/src/layout/skia_measurer.rs +++ b/crates/core/src/layout/skia_measurer.rs @@ -35,70 +35,30 @@ impl<'a> LayoutMeasurer for SkiaMeasurer<'a> { &mut self, node_id: NodeId, _node: &Node, - area: &Area, _parent_area: &Area, available_parent_area: &Area, - ) -> Option { + ) -> Option { let node = self.rdom.get(node_id).unwrap(); let node_type = node.node_type(); match &*node_type { - NodeType::Text(TextNode { text, .. }) => { - let text_paragraph = - create_text(&node, available_parent_area, self.font_collection, text); - - Some(Area::new( - area.origin, - Size2D::new(text_paragraph.longest_line(), text_paragraph.height()), - )) + NodeType::Element(ElementNode { tag, .. }) if tag == "label" => { + let label = create_label(&node, available_parent_area, self.font_collection); + + Some(Size2D::new(label.longest_line(), label.height())) } NodeType::Element(ElementNode { tag, .. }) if tag == "paragraph" => { let paragraph = create_paragraph(&node, available_parent_area, self.font_collection, false); - Some(Area::new( - available_parent_area.origin, - Size2D::new(paragraph.longest_line(), paragraph.height()), - )) + Some(Size2D::new(paragraph.longest_line(), paragraph.height())) } _ => None, } } } -/// Collect all the texts and FontStyles from all the given Node's children -pub fn get_inner_texts(node: &DioxusNode) -> Vec<(FontStyleState, String)> { - node.children() - .iter() - .filter_map(|child| { - if let NodeType::Element(ElementNode { tag, .. }) = &*child.node_type() { - if tag != "text" { - return None; - } - - let children = child.children(); - let child_text = *children.first().unwrap(); - let child_text_type = &*child_text.node_type(); - - if let NodeType::Text(TextNode { text, .. }) = child_text_type { - let font_style = child.get::().unwrap(); - Some((font_style.clone(), text.to_owned())) - } else { - None - } - } else { - None - } - }) - .collect() -} - -pub fn create_text( - node: &DioxusNode, - area: &Area, - font_collection: &FontCollection, - text: &str, -) -> Paragraph { +pub fn create_label(node: &DioxusNode, area: &Area, font_collection: &FontCollection) -> Paragraph { let font_style = &*node.get::().unwrap(); let mut paragraph_style = ParagraphStyle::default(); @@ -112,7 +72,12 @@ pub fn create_text( } let mut paragraph_builder = ParagraphBuilder::new(¶graph_style, font_collection); - paragraph_builder.add_text(text); + + for child in node.children() { + if let NodeType::Text(TextNode { text, .. }) = &*child.node_type() { + paragraph_builder.add_text(text); + } + } let mut paragraph = paragraph_builder.build(); paragraph.layout(area.width() + 1.0); @@ -142,11 +107,21 @@ pub fn create_paragraph( paragraph_builder.push_style(&font_style.into()); - let texts = get_inner_texts(node); - - for (font_style, text) in texts.into_iter() { - paragraph_builder.push_style(&TextStyle::from(&font_style)); - paragraph_builder.add_text(text); + for text_span in node.children() { + match &*text_span.node_type() { + NodeType::Element(ElementNode { tag, .. }) if tag == "text" => { + let text_nodes = text_span.children(); + let text_node = *text_nodes.first().unwrap(); + let text_node_type = &*text_node.node_type(); + + if let NodeType::Text(TextNode { text, .. }) = text_node_type { + let font_style = text_node.get::().unwrap(); + paragraph_builder.push_style(&TextStyle::from(&*font_style)); + paragraph_builder.add_text(text); + } + } + _ => {} + } } if node_cursor_settings.position.is_some() && is_rendering { diff --git a/crates/renderer/src/elements/label.rs b/crates/renderer/src/elements/label.rs index 00e971043..9b7759423 100644 --- a/crates/renderer/src/elements/label.rs +++ b/crates/renderer/src/elements/label.rs @@ -1,7 +1,4 @@ -use dioxus_native_core::node::NodeType; -use dioxus_native_core::prelude::TextNode; -use dioxus_native_core::real_dom::NodeImmutable; -use freya_core::layout::create_text; +use freya_core::layout::create_label; use freya_dom::prelude::DioxusNode; use freya_engine::prelude::*; use torin::geometry::Area; @@ -13,26 +10,10 @@ pub fn render_label( canvas: &Canvas, font_collection: &mut FontCollection, ) { - let node_children = node_ref.children(); + let paragraph = create_label(node_ref, area, font_collection); - let child = node_children.first(); + let x = area.min_x(); + let y = area.min_y(); - let text = if let Some(child) = child { - if let NodeType::Text(TextNode { text, .. }) = &*child.node_type() { - Some(text.clone()) - } else { - None - } - } else { - None - }; - - if let Some(text) = text { - let paragraph = create_text(node_ref, area, font_collection, &text); - - let x = area.min_x(); - let y = area.min_y(); - - paragraph.paint(canvas, (x, y)); - } + paragraph.paint(canvas, (x, y)); } diff --git a/crates/torin/benches/bench.rs b/crates/torin/benches/bench.rs index a4b01c2ae..11fa95a7e 100644 --- a/crates/torin/benches/bench.rs +++ b/crates/torin/benches/bench.rs @@ -10,10 +10,9 @@ impl LayoutMeasurer for TestingMeasurer { &mut self, _node_id: usize, _node: &Node, - _area: &Area, _parent_size: &Area, _available_parent_area: &Area, - ) -> Option { + ) -> Option { None } } diff --git a/crates/torin/examples/demo.rs b/crates/torin/examples/demo.rs index 1aef339ae..82e0f7e7e 100644 --- a/crates/torin/examples/demo.rs +++ b/crates/torin/examples/demo.rs @@ -10,10 +10,9 @@ impl LayoutMeasurer for CustomMeasurer { &mut self, _node_id: usize, _node: &Node, - _area: &Area, _parent_size: &Area, _available_parent_area: &Area, - ) -> Option { + ) -> Option { None } } diff --git a/crates/torin/src/custom_measurer.rs b/crates/torin/src/custom_measurer.rs index f32d49cad..cb7f32dd7 100644 --- a/crates/torin/src/custom_measurer.rs +++ b/crates/torin/src/custom_measurer.rs @@ -1,12 +1,15 @@ -use crate::{dom_adapter::NodeKey, geometry::Area, node::Node}; +use crate::{ + dom_adapter::NodeKey, + geometry::{Area, Size2D}, + node::Node, +}; pub trait LayoutMeasurer { fn measure( &mut self, node_id: Key, node: &Node, - area: &Area, parent_area: &Area, available_parent_area: &Area, - ) -> Option; + ) -> Option; } diff --git a/crates/torin/src/measure.rs b/crates/torin/src/measure.rs index 2dd946f9b..f61c7babd 100644 --- a/crates/torin/src/measure.rs +++ b/crates/torin/src/measure.rs @@ -60,25 +60,17 @@ pub fn measure_node( layout_metadata.root_area.height(), ); - // 3. Compute the origin of the area - let area_origin = node - .position - .get_origin(available_parent_area, parent_area, &area_size); - - let mut area = Rect::new(area_origin, area_size); - - // 4. If available, run a custom layout measure function + // 3. If available, run a custom layout measure function // This is useful when you use third-party libraries (e.g. rust-skia, cosmic-text) to measure text layouts // When a Node is measured by a custom measurer function the inner children will be skipped let measure_inner_children = if let Some(measurer) = measurer { - let custom_area = - measurer.measure(node_id, node, &area, parent_area, available_parent_area); + let custom_size = measurer.measure(node_id, node, parent_area, available_parent_area); - // 4.1. Compute the width and height again using the new custom area sizes - if let Some(custom_area) = custom_area { + // 3.1. Compute the width and height again using the new custom area sizes + if let Some(custom_size) = custom_size { if Size::Inner == node.width { - area.size.width = node.width.min_max( - custom_area.width(), + area_size.width = node.width.min_max( + custom_size.width, parent_area.size.width, available_parent_area.size.width, node.margin.left(), @@ -89,8 +81,8 @@ pub fn measure_node( ); } if Size::Inner == node.height { - area.size.height = node.height.min_max( - custom_area.height(), + area_size.height = node.height.min_max( + custom_size.height, parent_area.size.height, available_parent_area.size.height, node.margin.top(), @@ -103,18 +95,18 @@ pub fn measure_node( } // Do not measure inner children - custom_area.is_none() + custom_size.is_none() } else { true }; - // 5. Compute the inner area of the Node, which is basically the area inside the margins and paddings - let mut inner_area = { - let mut inner_area = area; + // 4. Compute the inner size of the Node, which is basically the size inside the margins and paddings + let inner_size = { + let mut inner_size = area_size; - // 5.1. When having an unsized bound we set it to whatever is still available in the parent's area + // 4.1. When having an unsized bound we set it to whatever is still available in the parent's area if Size::Inner == node.width { - inner_area.size.width = node.width.min_max( + inner_size.width = node.width.min_max( available_parent_area.width(), parent_area.size.width, available_parent_area.width(), @@ -126,7 +118,7 @@ pub fn measure_node( ); } if Size::Inner == node.height { - inner_area.size.height = node.height.min_max( + inner_size.height = node.height.min_max( available_parent_area.height(), parent_area.size.height, available_parent_area.height(), @@ -137,12 +129,18 @@ pub fn measure_node( layout_metadata.root_area.height(), ); } - - inner_area - .after_gaps(&node.padding) - .after_gaps(&node.margin) + inner_size }; + // 5. Create the areas + let area_origin = node + .position + .get_origin(available_parent_area, parent_area, &area_size); + let mut area = Rect::new(area_origin, area_size); + let mut inner_area = Rect::new(area_origin, inner_size) + .after_gaps(&node.padding) + .after_gaps(&node.margin); + let mut inner_sizes = Size2D::default(); if measure_inner_children { diff --git a/crates/torin/src/test_utils.rs b/crates/torin/src/test_utils.rs index c7063ae93..54e565344 100644 --- a/crates/torin/src/test_utils.rs +++ b/crates/torin/src/test_utils.rs @@ -8,10 +8,9 @@ impl LayoutMeasurer for TestingMeasurer { &mut self, _node_id: usize, _node: &Node, - _area: &Area, _parent_size: &Area, _available_parent_area: &Area, - ) -> Option { + ) -> Option { None } }