diff --git a/pages/main.xml b/pages/main.xml index b4a58eb..1ec8acf 100644 --- a/pages/main.xml +++ b/pages/main.xml @@ -1,2 +1,28 @@ - - + + + + + + + + + + + + + diff --git a/src/app/mod.rs b/src/app/mod.rs index cb21fb3..f7f33ba 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -5,9 +5,10 @@ pub use cursors::{Cursor, set_cursor}; use wasm_bindgen::prelude::wasm_bindgen; use crate::{ + log, parser::{self, TEST_XML}, render::Renderer, - views::{View, default_view}, + views::View, }; #[wasm_bindgen] @@ -38,6 +39,7 @@ impl App { let (width, height) = (renderer.actual_width, renderer.actual_height); let root_view = parser::parse(TEST_XML); + log!("root: {:?}", root_view); let mut this = App { root_view: Some(root_view), diff --git a/src/parser/interpreter.rs b/src/parser/interpreter.rs deleted file mode 100644 index b073eab..0000000 --- a/src/parser/interpreter.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::{ - parser::Tag, - views::{ColorRectView, ConstraintLayout, View}, -}; - -pub fn interpret_tag(tag: Tag) -> Box { - match tag.name.as_str() { - "ColoredRectView" => Box::new(ColorRectView::from_tag(&tag.attributes)), - "ConstraintLayout" => Box::new(ConstraintLayout::from_tag(&tag.attributes)), - - _ => panic!("Unknown tag: {}", tag.name), - } -} diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 100a2cd..401e9a6 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,20 +1,63 @@ use std::collections::HashMap; -use crate::views::View; +use crate::{ + log, + views::{Bounds, BoxView, ColorRectView, ConstraintLayout, View}, +}; -mod interpreter; mod parser; pub const TEST_XML: &'static str = include_str!("../../pages/main.xml"); #[derive(Debug)] -struct Tag { - name: String, - children: Vec, - attributes: HashMap, +pub struct Tag { + pub name: String, + pub children: Vec, + pub attributes: HashMap, +} + +impl Tag { + pub fn parse(&self) -> Box { + match self.name.as_str() { + "ColoredRectView" => ColorRectView::from_tag(&self.attributes, &self.children), + "ConstraintLayout" => ConstraintLayout::from_tag(&self.attributes, &self.children), + "BoxView" => BoxView::from_tag(&self.attributes, &self.children), + + _ => panic!("Unknown tag: {}", self.name), + } + } + pub fn parse_bounds(attributes: &HashMap) -> (Option, Option) { + let (mut width, mut height) = (None, None); + + let parse_bound = |str: &str| -> Bounds { + match str { + "parent" => Bounds::MatchParent, + _ => { + let bound = if let Ok(int) = str.parse::() { + int as f32 + } else if let Ok(float) = str.parse::() { + float + } else { + panic!("Invalid String"); + }; + + Bounds::Pixels(bound) + } + } + }; + + for (key, value) in attributes { + match key.as_str() { + "width" => width = Some(parse_bound(value)), + "height" => height = Some(parse_bound(value)), + _ => {} + } + } + + (width, height) + } } pub fn parse(xml: &str) -> Box { - let tag = parser::parse_xml(xml); - interpreter::interpret_tag(tag) + parser::parse_xml(xml).parse() } diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 6006a3b..eee52b9 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -51,9 +51,15 @@ fn parse_tag(event: BytesStart<'_>, reader: &mut Reader<&[u8]>) -> Tag { loop { match reader.read_event_into(&mut buf) { - Err(e) => panic!("Error at position {}: {:?}", reader.error_position(), e), + Err(e) => { + log!("Error at position {}: {:?}", reader.error_position(), e); + panic!() + } // exits the loop when reaching end of file - Ok(Event::Eof) => panic!("Unexpected end of file"), + Ok(Event::Eof) => { + log!("Unexpected end of file"); + panic!() + } Ok(Event::Start(e)) => { children.push(parse_tag(e, reader)); diff --git a/src/render/renderer.rs b/src/render/renderer.rs index c4c8882..cea6c79 100644 --- a/src/render/renderer.rs +++ b/src/render/renderer.rs @@ -1,13 +1,7 @@ -use fontdue::layout::{CoordinateSystem, Layout, LayoutSettings, TextStyle}; use wasm_bindgen::{Clamped, prelude::*}; use web_sys::ImageData; -use crate::render::{ - RESOLUTION, - buffer::{Bitmap, ImgBuffer}, - calc_resolution, - rand::Rnd, -}; +use crate::render::{RESOLUTION, buffer::ImgBuffer, calc_resolution, rand::Rnd}; #[wasm_bindgen] pub struct Renderer { diff --git a/src/views/box_view.rs b/src/views/box_view.rs new file mode 100644 index 0000000..729fcc5 --- /dev/null +++ b/src/views/box_view.rs @@ -0,0 +1,207 @@ +use std::any::TypeId; + +use crate::{ + log, + parser::Tag, + render::Renderer, + views::{Bounds, Constraint, View}, +}; + +#[derive(Debug)] +pub struct BoxView { + view: Box, + bounds: (Option, Option), + constraints: ( + Option, + Option, + Option, + Option, + ), +} + +impl BoxView { + pub fn new(view: Box) -> Self { + Self { + view, + bounds: (None, None), + constraints: (None, None, None, None), + } + } + pub fn set_bounds(&mut self, width: Option, height: Option) { + self.bounds = (width, height); + } + pub fn set_constraints( + &mut self, + top: Option, + left: Option, + right: Option, + bottom: Option, + ) { + self.constraints = (top, left, right, bottom) + } + pub fn bounds(&self, _ph: f32, _pw: f32) -> (Bounds, Bounds) { + ( + *self.bounds.0.as_ref().unwrap_or(&Bounds::Pixels(100.)), + *self.bounds.1.as_ref().unwrap_or(&Bounds::Pixels(100.)), + ) + } + pub fn get_constraints( + &self, + ) -> ( + &Option, + &Option, + &Option, + &Option, + ) { + ( + &self.constraints.0, + &self.constraints.1, + &self.constraints.2, + &self.constraints.3, + ) + } +} + +impl View for BoxView { + fn draw(&mut self, renderer: &mut Renderer, x: f32, y: f32, w: f32, h: f32) { + self.view.draw(renderer, x, y, w, h); + } + + fn resize(&mut self, x: f32, y: f32, w: f32, h: f32) { + self.view.resize(x, y, w, h); + } + + fn from_tag( + attributes: &std::collections::HashMap, + children: &Vec, + ) -> Box { + assert!(children.len() == 1, "BoxView must have exactly one child"); + + let (mut margin_top, mut margin_left, mut margin_right, mut margin_bottom) = + (None, None, None, None); + + let (mut align_top, mut align_left, mut align_right, mut align_bottom) = + (None, None, None, None); + + let parse_float = |var: &mut Option, value: &str| { + if let Ok(float) = value.parse::() { + *var = Some(float); + } else if let Ok(int) = value.parse::() { + let float = int as f32; + *var = Some(float); + } else { + panic!("Could not parse margin!") + } + }; + + let parse_align_refrence = |value: &String| -> usize { + match value.as_str() { + "parent" => 0, + _ => { + if let Ok(parent) = value.parse::() { + if parent >= children.len() { + // panic!("Child {} does not exist!", parent); + } + parent + } else { + panic!("Could not parse refrence"); + } + } + } + }; + + for (key, value) in attributes { + match key.as_str() { + // Set margin on all sides + "margin" => { + if let Ok(float) = value.parse::() { + (margin_top, margin_left, margin_right, margin_bottom) = + (Some(float), Some(float), Some(float), Some(float)); + } else if let Ok(int) = value.parse::() { + let float = int as f32; + (margin_top, margin_left, margin_right, margin_bottom) = + (Some(float), Some(float), Some(float), Some(float)); + } else { + panic!("Could not parse margin!") + } + } + + // Margin for specific directions + "margin_top" => parse_float(&mut margin_top, value), + "margin_left" => parse_float(&mut margin_left, value), + "margin_right" => parse_float(&mut margin_right, value), + "margin_bottom" => parse_float(&mut margin_bottom, value), + _ => {} + } + } + + for (key, value) in attributes { + match key.as_str() { + // Alignment + "align_top_to_top" => { + align_top = Some(match parse_align_refrence(value) { + 0 => Constraint::TopParent(margin_top.unwrap_or(0.)), + n => Constraint::Top(margin_top.unwrap_or(0.), n - 1), + }) + } + "align_top_to_bottom" => { + align_top = Some(match parse_align_refrence(value) { + 0 => Constraint::BottomParent(margin_top.unwrap_or(0.)), + n => Constraint::Bottom(margin_top.unwrap_or(0.), n - 1), + }) + } + + "align_left_to_left" => { + align_left = Some(match parse_align_refrence(value) { + 0 => Constraint::LeftParent(margin_left.unwrap_or(0.)), + n => Constraint::Left(margin_left.unwrap_or(0.), n - 1), + }) + } + "align_left_to_right" => { + align_left = Some(match parse_align_refrence(value) { + 0 => Constraint::RightParent(margin_left.unwrap_or(0.)), + n => Constraint::Right(margin_left.unwrap_or(0.), n - 1), + }) + } + + "align_right_to_right" => { + align_right = Some(match parse_align_refrence(value) { + 0 => Constraint::RightParent(margin_right.unwrap_or(0.)), + n => Constraint::Right(margin_right.unwrap_or(0.), n - 1), + }) + } + "align_right_to_left" => { + align_right = Some(match parse_align_refrence(value) { + 0 => Constraint::LeftParent(margin_right.unwrap_or(0.)), + n => Constraint::Left(margin_right.unwrap_or(0.), n - 1), + }) + } + + "align_bottom_to_bottom" => { + align_bottom = Some(match parse_align_refrence(value) { + 0 => Constraint::BottomParent(margin_bottom.unwrap_or(0.)), + n => Constraint::Bottom(margin_bottom.unwrap_or(0.), n - 1), + }) + } + "align_bottom_to_top" => { + align_bottom = Some(match parse_align_refrence(value) { + 0 => Constraint::TopParent(margin_bottom.unwrap_or(0.)), + n => Constraint::Top(margin_bottom.unwrap_or(0.), n - 1), + }) + } + _ => {} + } + } + + let mut b = Self::new(children[0].parse()); + + b.constraints = (align_top, align_left, align_right, align_bottom); + b.bounds = Tag::parse_bounds(attributes); + + Box::new(b) + } + + fn as_any(self: Box) -> Box { + self + } +} diff --git a/src/views/color_rect_view.rs b/src/views/color_rect_view.rs index 54e9344..2e93958 100644 --- a/src/views/color_rect_view.rs +++ b/src/views/color_rect_view.rs @@ -1,41 +1,17 @@ use crate::{ + parser::Tag, render::Renderer, - views::{ - Bounds, LayoutView, View, - constraint_layout::{Constraint, ConstraintView}, - }, + views::{Bounds, Constraint, View}, }; +#[derive(Debug)] pub struct ColorRectView { color: (u8, u8, u8), - bounds: (Option, Option), - constraints: ( - Option, - Option, - Option, - Option, - ), } impl ColorRectView { pub fn new(r: u8, g: u8, b: u8) -> Self { - Self { - color: (r, g, b), - bounds: (None, None), - constraints: (None, None, None, None), - } - } - pub fn set_bounds(&mut self, width: Option, height: Option) { - self.bounds = (width, height); - } - pub fn set_constraints( - &mut self, - top: Option, - left: Option, - right: Option, - bottom: Option, - ) { - self.constraints = (top, left, right, bottom) + Self { color: (r, g, b) } } } @@ -47,10 +23,18 @@ impl View for ColorRectView { fn resize(&mut self, _x: f32, _y: f32, _w: f32, _h: f32) {} - fn from_tag(attributes: &std::collections::HashMap) -> Self + fn from_tag( + attributes: &std::collections::HashMap, + children: &Vec, + ) -> Box where Self: Sized, { + assert!( + children.is_empty(), + "ColorRectView does not support children" + ); + let r = attributes .get("r") .unwrap_or(&"0".to_string()) @@ -67,33 +51,10 @@ impl View for ColorRectView { .parse() .unwrap(); - Self::new(r, g, b) + Box::new(Self::new(r, g, b)) } -} -impl LayoutView for ColorRectView { - fn bounds(&self, _ph: f32, _pw: f32) -> (Bounds, Bounds) { - ( - *self.bounds.0.as_ref().unwrap_or(&Bounds::Pixels(100.)), - *self.bounds.1.as_ref().unwrap_or(&Bounds::Pixels(100.)), - ) - } -} - -impl ConstraintView for ColorRectView { - fn get_constraints( - &self, - ) -> ( - &Option, - &Option, - &Option, - &Option, - ) { - ( - &self.constraints.0, - &self.constraints.1, - &self.constraints.2, - &self.constraints.3, - ) + fn as_any(self: Box) -> Box { + self } } diff --git a/src/views/constraint_layout.rs b/src/views/constraint_layout.rs index 903016d..9a4dc47 100644 --- a/src/views/constraint_layout.rs +++ b/src/views/constraint_layout.rs @@ -1,38 +1,23 @@ -use std::collections::HashMap; - -use crate::{ - render::Renderer, - views::{LayoutView, View}, +use std::{ + any::{Any, TypeId}, + collections::HashMap, }; -pub enum Constraint { - Left(f32, usize), - Right(f32, usize), - Top(f32, usize), - Bottom(f32, usize), - - LeftParent(f32), - RightParent(f32), - TopParent(f32), - BottomParent(f32), -} - -pub trait ConstraintView: LayoutView { - fn get_constraints( - &self, - ) -> ( - &Option, - &Option, - &Option, - &Option, - ); -} +use crate::{ + log, + parser::Tag, + render::Renderer, + views::{Constraint, View, box_view::BoxView}, +}; +#[derive(Debug)] pub struct ConstraintLayout { - pub children: Vec>, + pub children: Vec, child_positions: Option>, + child_order: Option>, } +#[derive(Debug)] struct Rect { x: f32, y: f32, @@ -41,7 +26,7 @@ struct Rect { } impl ConstraintLayout { - pub fn new(children: Vec>) -> Self { + pub fn new(children: Vec) -> Self { for child in &children { let (top, left, right, bottom) = child.get_constraints(); @@ -55,10 +40,15 @@ impl ConstraintLayout { ); } - ConstraintLayout { + let mut this = ConstraintLayout { children, child_positions: None, - } + child_order: None, + }; + + this.recalculate_child_render_order(); + + this } pub fn recalculate_positions(&mut self, x: f32, y: f32, self_w: f32, self_h: f32) { @@ -69,19 +59,11 @@ impl ConstraintLayout { let mut calculated_positions: HashMap = HashMap::new(); - let dependencies = self - .children - .iter() - .map(|c| { - let constraints = c.get_constraints(); - [constraints.0, constraints.1, constraints.2, constraints.3] - }) - .collect::>(); + let child_order = self.child_order.as_ref().unwrap(); + for idx in child_order { + let child: &mut BoxView = &mut self.children[*idx]; - let sorted = topological_sort(&dependencies); - - for idx in sorted { - let child = &mut self.children[idx]; + log!("{:?}", child.get_constraints()); let (c_top, c_left, c_right, c_bottom) = child.get_constraints(); let (c_width, c_height) = child.bounds(self_w, self_h); @@ -152,7 +134,7 @@ impl ConstraintLayout { }; calculated_positions.insert( - idx, + *idx, Rect { x: x, y: y, @@ -164,6 +146,19 @@ impl ConstraintLayout { self.child_positions = Some(calculated_positions); } + + pub fn recalculate_child_render_order(&mut self) { + let dependencies = self + .children + .iter() + .map(|c| { + let constraints = c.get_constraints(); + [constraints.0, constraints.1, constraints.2, constraints.3] + }) + .collect::>(); + + self.child_order = Some(topological_sort(&dependencies)); + } } impl View for ConstraintLayout { @@ -180,11 +175,30 @@ impl View for ConstraintLayout { self.recalculate_positions(x, y, w, h); } - fn from_tag(attributes: &std::collections::HashMap) -> Self + fn from_tag( + attributes: &std::collections::HashMap, + children: &Vec, + ) -> Box where Self: Sized, { - todo!() + let mut parsed_children = Vec::new(); + + for child in children { + let child = child.parse(); + + if let Ok(b) = child.as_any().downcast::() { + parsed_children.push(*b); + } else { + panic!("Constraint Layout must contain only BoxView!") + } + } + + Box::new(Self::new(parsed_children)) + } + + fn as_any(self: Box) -> Box { + self } } @@ -219,7 +233,8 @@ fn dfs( result: &mut Vec, ) { if states[node] == VisitState::Visiting { - panic!("Cycle detected in constraint graph at node {}", node); + log!("Cycle detected in constraint graph at node {}", node); + panic!(); } if states[node] == VisitState::Visited { diff --git a/src/views/mod.rs b/src/views/mod.rs index f04d57e..a7df1ac 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -1,27 +1,30 @@ -use std::collections::HashMap; - -use crate::{ - render::Renderer, - views::constraint_layout::{Constraint, ConstraintView}, +use std::{ + any::{Any, TypeId}, + collections::HashMap, + fmt::Debug, }; +use crate::{parser::Tag, render::Renderer}; + +mod box_view; mod color_rect_view; mod constraint_layout; mod text_view; mod vertical_layout; +pub use box_view::BoxView; pub use color_rect_view::ColorRectView; pub use constraint_layout::ConstraintLayout; -pub use text_view::TextView; -pub use vertical_layout::VerticalLayout; -pub trait View { +pub trait View: Debug { fn draw(&mut self, renderer: &mut Renderer, x: f32, y: f32, w: f32, h: f32); fn resize(&mut self, x: f32, y: f32, w: f32, h: f32); - fn from_tag(attributes: &HashMap) -> Self + fn from_tag(attributes: &HashMap, children: &Vec) -> Box where Self: Sized; + + fn as_any(self: Box) -> Box; } #[derive(Debug, Clone, Copy, PartialEq)] @@ -30,17 +33,32 @@ pub enum Bounds { Pixels(f32), } -pub trait LayoutView: View { - // fn set_bounds(&mut self, width: Option, height: Option); - fn bounds(&self, pw: f32, ph: f32) -> (Bounds, Bounds); +#[derive(Debug)] +pub enum Constraint { + Left(f32, usize), + Right(f32, usize), + Top(f32, usize), + Bottom(f32, usize), + + LeftParent(f32), + RightParent(f32), + TopParent(f32), + BottomParent(f32), } -// pub trait ViewPosition: Drawable { -// // fn draw(&self) +// pub trait ConstraintView: View { +// fn get_constraints( +// &self, +// ) -> ( +// &Option, +// &Option, +// &Option, +// &Option, +// ); // } pub fn default_view() -> Box { - let mut a = ColorRectView::new(127, 0, 0); + let mut a = BoxView::new(Box::new(ColorRectView::new(127, 0, 0))); let temp_margin = 10.0; @@ -53,7 +71,7 @@ pub fn default_view() -> Box { ); a.set_bounds(Some(Bounds::Pixels(200.)), Some(Bounds::Pixels(100.))); - let mut b = ColorRectView::new(0, 127, 0); + let mut b = BoxView::new(Box::new(ColorRectView::new(0, 127, 0))); b.set_constraints( Some(Constraint::TopParent(temp_margin)), @@ -62,7 +80,7 @@ pub fn default_view() -> Box { None, ); - let mut c = ColorRectView::new(0, 0, 127); + let mut c = BoxView::new(Box::new(ColorRectView::new(0, 0, 127))); c.set_constraints( None, @@ -71,7 +89,7 @@ pub fn default_view() -> Box { Some(Constraint::BottomParent(temp_margin)), ); - let mut d = ColorRectView::new(127, 127, 0); + let mut d = BoxView::new(Box::new(ColorRectView::new(127, 127, 0))); d.set_constraints( None, @@ -80,7 +98,7 @@ pub fn default_view() -> Box { Some(Constraint::BottomParent(temp_margin)), ); - let mut center = ColorRectView::new(127, 127, 0); + let mut center = BoxView::new(Box::new(ColorRectView::new(127, 127, 0))); center.set_constraints( Some(Constraint::TopParent(temp_margin)), @@ -91,7 +109,7 @@ pub fn default_view() -> Box { center.set_bounds(Some(Bounds::Pixels(350.)), Some(Bounds::Pixels(350.))); - let mut center_top = ColorRectView::new(127, 0, 127); + let mut center_top = BoxView::new(Box::new(ColorRectView::new(127, 0, 127))); center_top.set_constraints( Some(Constraint::Bottom(0., 4)), @@ -103,7 +121,7 @@ pub fn default_view() -> Box { Some(Constraint::Top(0., 4)), ); - let mut inside_top = ColorRectView::new(127, 0, 127); + let mut inside_top = BoxView::new(Box::new(ColorRectView::new(127, 0, 127))); inside_top.set_constraints( Some(Constraint::Bottom(0., 4)), @@ -116,13 +134,7 @@ pub fn default_view() -> Box { ); Box::new(ConstraintLayout::new(vec![ - Box::new(a), - Box::new(b), - Box::new(c), - Box::new(d), - Box::new(center), - Box::new(center_top), - Box::new(inside_top), + a, b, c, d, center, center_top, inside_top, ])) // Box::new(VerticalLayout::new(vec![ diff --git a/src/views/text_view.rs b/src/views/text_view.rs index d872259..40e0cb9 100644 --- a/src/views/text_view.rs +++ b/src/views/text_view.rs @@ -1,9 +1,12 @@ use fontdue::layout::{CoordinateSystem, Layout, LayoutSettings, TextStyle}; +use std::fmt::Debug; + use crate::{ fonts::{FONTS, FontHandle}, + parser::Tag, render::{Renderer, buffer::Bitmap}, - views::{Bounds, LayoutView, View}, + views::{Bounds, View}, }; pub struct TextView { @@ -11,7 +14,6 @@ pub struct TextView { text: String, scale: f32, font: FontHandle, - bounds: (Option, Option), } impl TextView { @@ -27,7 +29,6 @@ impl TextView { text, scale: 20., font: FontHandle::AtiksonHyperlegibleRegular, - bounds: (None, None), }; let font = (s.font as usize).clone(); @@ -39,9 +40,6 @@ impl TextView { s } - pub fn set_bounds(&mut self, width: Option, height: Option) { - self.bounds = (width, height); - } } impl View for TextView { @@ -79,24 +77,44 @@ impl View for TextView { // todo!() } - fn from_tag(attributes: &std::collections::HashMap) -> Self + fn from_tag( + attributes: &std::collections::HashMap, + children: &Vec, + ) -> Box where Self: Sized, { + assert!(children.is_empty(), "TextView does not support children"); todo!() + // Self::new(attributes) + } + + fn as_any(self: Box) -> Box { + self } } -impl LayoutView for TextView { - fn bounds(&self, _ph: f32, _pw: f32) -> (Bounds, Bounds) { - // let (x, y) = renderer.undistort(x as f32, y as f32); +// impl LayoutView for TextView { +// fn bounds(&self, _ph: f32, _pw: f32) -> (Bounds, Bounds) { +// // let (x, y) = renderer.undistort(x as f32, y as f32); - let (mut width, mut height): (usize, usize) = (0, 0); - for glyph in self.layout.glyphs() { - width = width.max(glyph.x as usize + glyph.width); - height = height.max(glyph.y as usize + glyph.height); - } +// let (mut width, mut height): (usize, usize) = (0, 0); +// for glyph in self.layout.glyphs() { +// width = width.max(glyph.x as usize + glyph.width); +// height = height.max(glyph.y as usize + glyph.height); +// } - (Bounds::Pixels(width as f32), Bounds::Pixels(height as f32)) +// (Bounds::Pixels(width as f32), Bounds::Pixels(height as f32)) +// } +// } + +impl Debug for TextView { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("TextView") + // .field("layout", &self.layout) + .field("text", &self.text) + .field("scale", &self.scale) + .field("font", &self.font) + .finish() } } diff --git a/src/views/vertical_layout.rs b/src/views/vertical_layout.rs index e788404..fae9f79 100644 --- a/src/views/vertical_layout.rs +++ b/src/views/vertical_layout.rs @@ -1,12 +1,18 @@ -use crate::views::{Bounds, LayoutView, View}; +use std::collections::HashMap; +use crate::{ + parser::Tag, + views::{Bounds, View, box_view::BoxView}, +}; + +#[derive(Debug)] pub struct VerticalLayout { - pub views: Vec>, + pub views: Vec, pub bounds: (Option, Option), } impl VerticalLayout { - pub fn new(views: Vec>) -> Self { + pub fn new(views: Vec) -> Self { Self { views, bounds: (None, None), @@ -42,34 +48,43 @@ impl View for VerticalLayout { } } fn resize(&mut self, x: f32, y: f32, w: f32, h: f32) {} - fn from_tag(attributes: &std::collections::HashMap) -> Self + + fn from_tag(attributes: &HashMap, children: &Vec) -> Box where Self: Sized, { - todo!() + todo!(""); + // Box::new(Self { + // views: children.iter().map(|tag| tag.parse()).collect(), + // bounds: (None, None), + // }) + } + + fn as_any(self: Box) -> Box { + self } } -impl LayoutView for VerticalLayout { - fn bounds(&self, pw: f32, ph: f32) -> (Bounds, Bounds) { - let (mut maxx, mut totaly): (f32, f32) = (0., 0.); - for view in &self.views { - let (vx, vy) = view.bounds(pw, ph); +// impl LayoutView for VerticalLayout { +// fn bounds(&self, pw: f32, ph: f32) -> (Bounds, Bounds) { +// let (mut maxx, mut totaly): (f32, f32) = (0., 0.); +// for view in &self.views { +// let (vx, vy) = view.bounds(pw, ph); - let vx = match vx { - super::Bounds::MatchParent => pw, - super::Bounds::Pixels(x) => x, - }; +// let vx = match vx { +// super::Bounds::MatchParent => pw, +// super::Bounds::Pixels(x) => x, +// }; - let vy = match vy { - super::Bounds::MatchParent => ph, - super::Bounds::Pixels(x) => x, - }; +// let vy = match vy { +// super::Bounds::MatchParent => ph, +// super::Bounds::Pixels(x) => x, +// }; - maxx = maxx.max(vx); - totaly += vy; - } +// maxx = maxx.max(vx); +// totaly += vy; +// } - (Bounds::Pixels(maxx), Bounds::Pixels(totaly)) - } -} +// (Bounds::Pixels(maxx), Bounds::Pixels(totaly)) +// } +// }