diff --git a/Cargo.lock b/Cargo.lock index 2f10e670..4a1d6d8b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,6 +15,15 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" +[[package]] +name = "aho-corasick" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" +dependencies = [ + "memchr", +] + [[package]] name = "andrew" version = "0.2.1" @@ -334,7 +343,7 @@ dependencies = [ "autocfg 1.0.0", "cfg-if", "crossbeam-utils", - "lazy_static", + "lazy_static 1.4.0", "maybe-uninit", "memoffset", "scopeguard", @@ -358,7 +367,16 @@ checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ "autocfg 1.0.0", "cfg-if", - "lazy_static", + "lazy_static 1.4.0", +] + +[[package]] +name = "css-color-parser" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ccb6ce7ef97e6dc6e575e51b596c9889a5cc88a307b5ef177d215c61fd7581d" +dependencies = [ + "lazy_static 0.1.16", ] [[package]] @@ -436,7 +454,7 @@ checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ "proc-macro2 1.0.17", "quote 1.0.6", - "syn 1.0.24", + "syn 1.0.27", "synstructure", ] @@ -540,7 +558,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2 1.0.17", "quote 1.0.6", - "syn 1.0.24", + "syn 1.0.27", ] [[package]] @@ -681,7 +699,7 @@ dependencies = [ "foreign-types", "gfx-auxil", "gfx-hal", - "lazy_static", + "lazy_static 1.4.0", "log", "metal", "objc", @@ -704,7 +722,7 @@ dependencies = [ "byteorder", "core-graphics 0.19.0", "gfx-hal", - "lazy_static", + "lazy_static 1.4.0", "log", "objc", "raw-window-handle", @@ -780,12 +798,14 @@ version = "0.1.0" dependencies = [ "bytemuck", "cgmath", + "css-color-parser", "failure", "futures", "glsl-to-spirv", "image", "palette", "rctree", + "regex", "wgpu", "winit", "xmlparser", @@ -879,6 +899,12 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "lazy_static" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417" + [[package]] name = "lazy_static" version = "1.4.0" @@ -893,9 +919,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" -version = "0.2.70" +version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" +checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" [[package]] name = "libloading" @@ -1185,7 +1211,7 @@ checksum = "0b4b5f600e60dd3a147fb57b4547033d382d1979eb087af310e91cb45a63b1f4" dependencies = [ "proc-macro2 1.0.17", "quote 1.0.6", - "syn 1.0.24", + "syn 1.0.27", ] [[package]] @@ -1229,7 +1255,7 @@ checksum = "6fb44a25c5bba983be0fc8592dfaf3e6d0935ce8be0c6b15b2a39507af34a926" dependencies = [ "proc-macro2 1.0.17", "quote 1.0.6", - "syn 1.0.24", + "syn 1.0.27", "synstructure", "unicode-xid 0.2.0", ] @@ -1295,7 +1321,7 @@ checksum = "e58db2081ba5b4c93bd6be09c40fd36cb9193a8336c384f3b40012e531aa7e40" dependencies = [ "proc-macro2 1.0.17", "quote 1.0.6", - "syn 1.0.24", + "syn 1.0.27", ] [[package]] @@ -1568,7 +1594,7 @@ dependencies = [ "crossbeam-deque", "crossbeam-queue", "crossbeam-utils", - "lazy_static", + "lazy_static 1.4.0", "num_cpus", ] @@ -1593,6 +1619,24 @@ version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +[[package]] +name = "regex" +version = "1.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", + "thread_local", +] + +[[package]] +name = "regex-syntax" +version = "0.6.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" + [[package]] name = "remove_dir_all" version = "0.5.2" @@ -1688,7 +1732,7 @@ dependencies = [ "andrew", "bitflags", "dlib", - "lazy_static", + "lazy_static 1.4.0", "memmap", "nix", "wayland-client", @@ -1737,9 +1781,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.24" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87bc5b2815ebb664de0392fdf1b95b6d10e160f86d9f64ff65e5679841ca06a" +checksum = "ef781e621ee763a2a40721a8861ec519cb76966aee03bb5d00adb6a31dc1c1de" dependencies = [ "proc-macro2 1.0.17", "quote 1.0.6", @@ -1754,7 +1798,7 @@ checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ "proc-macro2 1.0.17", "quote 1.0.6", - "syn 1.0.24", + "syn 1.0.27", "unicode-xid 0.2.0", ] @@ -1772,6 +1816,15 @@ dependencies = [ "winapi 0.3.8", ] +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static 1.4.0", +] + [[package]] name = "tiff" version = "0.3.1" @@ -1848,11 +1901,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3972e137ebf830900db522d6c8fd74d1900dcfc733462e9a12e942b00b4ac94" dependencies = [ "bumpalo", - "lazy_static", + "lazy_static 1.4.0", "log", "proc-macro2 1.0.17", "quote 1.0.6", - "syn 1.0.24", + "syn 1.0.27", "wasm-bindgen-shared", ] @@ -1874,7 +1927,7 @@ checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a" dependencies = [ "proc-macro2 1.0.17", "quote 1.0.6", - "syn 1.0.24", + "syn 1.0.27", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1942,7 +1995,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4" dependencies = [ "dlib", - "lazy_static", + "lazy_static 1.4.0", ] [[package]] @@ -1993,7 +2046,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19a5051a357d071fd69c24671e0ea6d644a83c7418e47eac3511427379007403" dependencies = [ "arrayvec", - "lazy_static", + "lazy_static 1.4.0", "libc", "objc", "parking_lot", @@ -2069,7 +2122,7 @@ dependencies = [ "core-video-sys", "dispatch", "instant", - "lazy_static", + "lazy_static 1.4.0", "libc", "log", "mio", @@ -2119,7 +2172,7 @@ version = "2.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" dependencies = [ - "lazy_static", + "lazy_static 1.4.0", "libc", "maybe-uninit", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 91d5bf99..909bd470 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,5 @@ futures = "0.3.4" bytemuck = "1.2.0" rctree = "0.3.3" xmlparser = "0.13.1" +regex = "1.3.7" +css-color-parser = "0.1.2" \ No newline at end of file diff --git a/gui/box.xml b/gui/box.xml index 91a13435..c788c674 100644 --- a/gui/box.xml +++ b/gui/box.xml @@ -1,3 +1,3 @@ - + {{INNER_XML}} \ No newline at end of file diff --git a/gui/col.xml b/gui/col.xml index f99c4e8b..abdf5037 100644 --- a/gui/col.xml +++ b/gui/col.xml @@ -1,3 +1,3 @@ - + {{INNER_XML}} \ No newline at end of file diff --git a/gui/header/file-menu.xml b/gui/header/file-menu.xml index abf0c966..6f122ab1 100644 --- a/gui/header/file-menu.xml +++ b/gui/header/file-menu.xml @@ -1,20 +1,20 @@ - + - File + File - Edit + Edit - Comp + Comp - View + View - Help + Help diff --git a/gui/header/window-buttons.xml b/gui/header/window-buttons.xml index 250199e3..1838d2d5 100644 --- a/gui/header/window-buttons.xml +++ b/gui/header/window-buttons.xml @@ -1,8 +1,8 @@ - - + + - + @@ -10,7 +10,7 @@ - + \ No newline at end of file diff --git a/gui/icon.xml b/gui/icon.xml index 77ec8b6f..d4dc814d 100644 --- a/gui/icon.xml +++ b/gui/icon.xml @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/gui/input/checkbox-with-dropdown.xml b/gui/input/checkbox-with-dropdown.xml index cc5f0ee3..cd10d885 100644 --- a/gui/input/checkbox-with-dropdown.xml +++ b/gui/input/checkbox-with-dropdown.xml @@ -1,12 +1,12 @@ - + - + - {{OPTION_LIST}} + {{OPTION_LIST}} diff --git a/gui/input/checkbox.xml b/gui/input/checkbox.xml index 4f61fb2c..9fcb4850 100644 --- a/gui/input/checkbox.xml +++ b/gui/input/checkbox.xml @@ -1,4 +1,4 @@ - + diff --git a/gui/input/dropdown.xml b/gui/input/dropdown.xml index 96be7900..862c9992 100644 --- a/gui/input/dropdown.xml +++ b/gui/input/dropdown.xml @@ -1,12 +1,12 @@ - + - {{CURRENT_TEXT}} + {{CURRENT_TEXT}} - + diff --git a/gui/row.xml b/gui/row.xml index f88a6a8f..02eb8574 100644 --- a/gui/row.xml +++ b/gui/row.xml @@ -1,3 +1,3 @@ - + {{INNER_XML}} \ No newline at end of file diff --git a/gui/text.xml b/gui/text.xml index 92b459f4..5e4464ce 100644 --- a/gui/text.xml +++ b/gui/text.xml @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/gui/viewport/panels.xml b/gui/viewport/panels.xml index ca08807e..e9276036 100644 --- a/gui/viewport/panels.xml +++ b/gui/viewport/panels.xml @@ -1,7 +1,7 @@ - - Option A - Option B - Option C + + Option A + Option B + Option C \ No newline at end of file diff --git a/gui/window/main.xml b/gui/window/main.xml index c527b3ac..0a272677 100644 --- a/gui/window/main.xml +++ b/gui/window/main.xml @@ -2,17 +2,17 @@ - - Document 1* - Graphite - + + Document 1* - Graphite + - + - File: 1.8 MB | Memory: 137 MB | Scratch: 0.7/12.3 GB - 🖰 Box Select Objects | [⇧G] Move Selection | [⇧R] Rotate Selection | [⇧S] Scale Selection + File: 1.8 MB | Memory: 137 MB | Scratch: 0.7/12.3 GB + 🖰 Box Select Objects | [⇧G] Move Selection | [⇧R] Rotate Selection | [⇧S] Scale Selection diff --git a/src/application.rs b/src/application.rs index 728818f8..fc667a43 100644 --- a/src/application.rs +++ b/src/application.rs @@ -72,7 +72,7 @@ impl Application { let gui_rect_pipeline = Pipeline::new(&device, swap_chain_descriptor.format, vec![], &mut shader_cache, ("shaders/shader.vert", "shaders/shader.frag")); pipeline_cache.set("gui_rect", gui_rect_pipeline); - let gui_root_data = GuiNode::new(swap_chain_descriptor.width, swap_chain_descriptor.height, ColorPalette::get_color_srgb(ColorPalette::Accent)); + let gui_root_data = GuiNode::new(swap_chain_descriptor.width, swap_chain_descriptor.height, ColorPalette::Accent.into_color_srgb()); let gui_root = rctree::Node::new(gui_root_data); GuiLayout::new(); diff --git a/src/color_palette.rs b/src/color_palette.rs index a771c1db..67cd1dc2 100644 --- a/src/color_palette.rs +++ b/src/color_palette.rs @@ -23,7 +23,7 @@ pub enum ColorPalette { impl ColorPalette { #[allow(dead_code)] - pub fn get_color_srgb(self) -> Color { + pub fn into_color_srgb(&self) -> Color { let grayscale = match self { ColorPalette::Black => 0 * 17, // #000000 ColorPalette::NearBlack => 1 * 17, // #111111 @@ -58,11 +58,34 @@ impl ColorPalette { } #[allow(dead_code)] - pub fn get_color_linear(self) -> Color { - let standard_rgb = ColorPalette::get_color_srgb(self); + pub fn into_color_linear(&self) -> Color { + let standard_rgb = ColorPalette::into_color_srgb(self); let linear = palette::Srgb::new(standard_rgb.r, standard_rgb.g, standard_rgb.b).into_linear(); Color::new(linear.red, linear.green, linear.blue, standard_rgb.a) } + + pub fn lookup_palette_color(name_in_palette: &str) -> ColorPalette { + match &name_in_palette.to_ascii_lowercase()[..] { + "black" => ColorPalette::Black, + "nearblack" => ColorPalette::NearBlack, + "mildblack" => ColorPalette::MildBlack, + "darkgray" => ColorPalette::DarkGray, + "dimgray" => ColorPalette::DimGray, + "dullgray" => ColorPalette::DullGray, + "lowergray" => ColorPalette::LowerGray, + "middlegray" => ColorPalette::MiddleGray, + "uppergray" => ColorPalette::UpperGray, + "palegray" => ColorPalette::PaleGray, + "softgray" => ColorPalette::SoftGray, + "lightgray" => ColorPalette::LightGray, + "brightgray" => ColorPalette::BrightGray, + "mildwhite" => ColorPalette::MildWhite, + "nearwhite" => ColorPalette::NearWhite, + "white" => ColorPalette::White, + "accent" => ColorPalette::Accent, + _ => panic!("Invalid color lookup of `{}` from the color palette", name_in_palette), + } + } } \ No newline at end of file diff --git a/src/gui_layout.rs b/src/gui_layout.rs index 45c249f6..e5fd057e 100644 --- a/src/gui_layout.rs +++ b/src/gui_layout.rs @@ -1,6 +1,7 @@ use std::fs; use std::io; use crate::layout_parsed_node::*; +use crate::layout_abstract_syntax::*; pub struct GuiLayout { @@ -10,6 +11,7 @@ impl GuiLayout { pub fn new() -> GuiLayout { let parsed_layout_tree = Self::parse_xml_file("gui/window/main.xml").unwrap(); Self::interpret_abstract_syntax_tree(parsed_layout_tree); + Self {} } @@ -115,6 +117,15 @@ impl GuiLayout { pub fn interpret_abstract_syntax_tree(root: rctree::Node) { for node in root.descendants() { println!("{:?}", node); + + match & *node.borrow() { + LayoutParsedNode::Tag(tag) => { + LayoutAbstractSyntaxNode::new(tag.namespace.clone(), tag.name.clone(), &tag.attributes); + } + LayoutParsedNode::Text(_) => {} + }; + + println!(); } } } \ No newline at end of file diff --git a/src/layout_abstract_attributes.rs b/src/layout_abstract_attributes.rs new file mode 100644 index 00000000..eab3a5a7 --- /dev/null +++ b/src/layout_abstract_attributes.rs @@ -0,0 +1,150 @@ +use crate::layout_abstract_types::*; +use crate::color_palette::ColorPalette; +use crate::color::Color; + +#[derive(Debug)] +pub enum Attribute { + VariableValue(VariableValue), + TypeValue(TypeValue), +} + +pub fn parse_attribute(input: &str) -> Attribute { + // Match variables and typed values that can be in an attribute + let regex = regex::Regex::new( + r#"(?x) + ^\s*(\w*)\s*(:)\s*(\()\s*(\w*\s*(?:\|\s*\w*\s*?)*)\s*(\))\s*(=)\s*(\w*)\s*$ | # Parameter ?: (? | ... | ?) = ? + ^\s*(\{\{)\s*(\w*)\s*(\}\})\s*$ | # Argument {{?}} + ^\s*(-?\d+)\s*$ | # Integer ? + ^\s*(-?(?:(?:\d+\.\d*)|(?:\d*\.\d+)))\s*$ | # Decimal ? + ^\s*(-?(?:(?:\d+(?:\.\d*)?)|(?:\d*(?:\.\d+))))([Pp][Xx])\s*$ | # AbsolutePx ?px + ^\s*(-?(?:(?:\d+(?:\.\d*)?)|(?:\d*(?:\.\d+))))(%)\s*$ | # Percent ?% + ^\s*(-?(?:(?:\d+(?:\.\d*)?)|(?:\d*(?:\.\d+))))(@)\s*$ | # PercentRemainder ?@ + ^\s*([Ii][Nn][Nn][Ee][Rr])\s*$ | # Inner inner + ^\s*([Ww][Ii][Dd][Tt][Hh])\s*$ | # Width width + ^\s*([Hh][Ee][Ii][Gg][Hh][Tt])\s*$ | # Height height + ^\s*`(.*)`\s*$ | # TemplateString `? ... {{?}} ...` + ^\s*(\[)(.*)(\])\s*$ | # Color [?] + ^\s*([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])\s*$ | # Bool true/false + ^\s*([Nn][Oo][Nn][Ee])\s*$ # None none + "# + ).unwrap(); + + // Match with the regular expression + let captures = regex.captures(input).map(|captures| + captures + .iter() + .skip(1) + .flat_map(|c| c) + .map(|c| c.as_str()) + .collect::>() + ); + + // Match against the captured values as a slice + let slices = captures.as_ref().map(|c| c.as_slice()); + match slices { + Some([name, ":", "(", types, ")", "=", default_value]) => { + // TODO: Extend to support a list of N types (like (AbsolutePx) (AbsolutePx) (AbsolutePx) (AbsolutePx)) + let name = String::from(*name); + + let split_types = types.split("|").map(|piece| piece.trim()); + let valid_types = split_types.map(|type_name| + match &type_name.to_ascii_lowercase()[..] { + "xml" => TypeName::Xml, + "integer" => TypeName::Integer, + "decimal" => TypeName::Decimal, + "absolutepx" => TypeName::AbsolutePx, + "percent" => TypeName::Percent, + "percentremainder" => TypeName::PercentRemainder, + "inner" => TypeName::Inner, + "width" => TypeName::Width, + "height" => TypeName::Height, + "templatestring" => TypeName::TemplateString, + "color" => TypeName::Color, + "bool" => TypeName::Bool, + "none" => TypeName::None, + invalid => panic!("Invalid type `{}` specified in the attribute `{}` when parsing XML layout", invalid, input), + } + ).collect::>(); + + let default = match parse_attribute(default_value) { + Attribute::TypeValue(type_value) => type_value, + Attribute::VariableValue(variable_value) => panic!("Found the variable value `{:?}` in the attribute `{}` which only allows typed values, when parsing XML layout", variable_value, input), + }; + + Attribute::VariableValue(VariableValue::Parameter(VariableParameter {name, valid_types, default})) + } + Some(["{{", name, "}}"]) => { + let name = String::from(*name); + Attribute::VariableValue(VariableValue::Argument(name)) + } + Some([value]) if regex::Regex::new(r"^\s*(-?\d+)\s*$").unwrap().is_match(value) => { + let integer = value.parse::().expect(&format!("Invalid value `{}` specified in the attribute `{}` when parsing XML layout", value, input)[..]); + Attribute::TypeValue(TypeValue::Integer(integer)) + } + Some([value]) if regex::Regex::new(r"^\s*(-?(?:(?:\d+\.\d*)|(?:\d*\.\d+)))\s*$").unwrap().is_match(value) => { + let decimal = value.parse::().expect(&format!("Invalid value `{}` specified in the attribute `{}` when parsing XML layout", value, input)[..]); + Attribute::TypeValue(TypeValue::Decimal(decimal)) + } + Some([value, px]) if px.eq_ignore_ascii_case("px") => { + let pixels = value.parse::().expect(&format!("Invalid value `{}` specified in the attribute `{}` when parsing XML layout", value, input)[..]); + Attribute::TypeValue(TypeValue::AbsolutePx(pixels)) + } + Some([value, "%"]) => { + let percent = value.parse::().expect(&format!("Invalid value `{}` specified in the attribute `{}` when parsing XML layout", value, input)[..]); + Attribute::TypeValue(TypeValue::Percent(percent)) + } + Some([value, "@"]) => { + let percent_remainder = value.parse::().expect(&format!("Invalid value `{}` specified in the attribute `{}` when parsing XML layout", value, input)[..]); + Attribute::TypeValue(TypeValue::PercentRemainder(percent_remainder)) + } + Some([inner]) if inner.eq_ignore_ascii_case("inner") => { + Attribute::TypeValue(TypeValue::Inner) + } + Some([width]) if width.eq_ignore_ascii_case("width") => { + Attribute::TypeValue(TypeValue::Width) + } + Some([height]) if height.eq_ignore_ascii_case("height") => { + Attribute::TypeValue(TypeValue::Height) + } + Some(["`", string, "`"]) => { + let mut segments = Vec::::new(); + let mut is_template = false; + + let regex = regex::Regex::new(r"\{\{|\}\}").unwrap(); + for part in regex.split(string) { + let segment = match is_template { + true => TemplateStringSegment::String(String::from(part)), + false => TemplateStringSegment::Argument(VariableArgument { name: String::from(part) }), + }; + segments.push(segment); + is_template = !is_template; + } + + Attribute::TypeValue(TypeValue::TemplateString(segments)) + } + Some(["[", color_name, "]"]) => { + let regex = regex::Regex::new(r"\s*'(.*)'\s*").unwrap(); + let color = match regex.captures(color_name) { + Some(captures) => { + let palette_color = captures.get(1).expect(&format!("Invalid palette color name `{}` specified in the attribute `{}` when parsing XML layout", color_name, input)[..]).as_str(); + ColorPalette::lookup_palette_color(palette_color).into_color_srgb() + } + None => { + let parsed = color_name.parse::(); + let css_color = parsed.expect(&format!("Invalid CSS color name `{}` specified in the attribute `{}` when parsing XML layout", color_name, input)[..]); + Color::new(css_color.r as f32 / 255.0, css_color.g as f32 / 255.0, css_color.b as f32 / 255.0, css_color.a as f32 / 255.0) + } + }; + + Attribute::TypeValue(TypeValue::Color(color)) + } + Some([true_or_false]) if true_or_false.eq_ignore_ascii_case("true") || true_or_false.eq_ignore_ascii_case("false") => { + let boolean = true_or_false.eq_ignore_ascii_case("true"); + Attribute::TypeValue(TypeValue::Bool(boolean)) + } + Some([none]) if none.eq_ignore_ascii_case("none") => { + Attribute::TypeValue(TypeValue::None) + } + _ => panic!("Invalid attribute value `{}` when parsing XML layout", input), + } +} diff --git a/src/layout_abstract_syntax.rs b/src/layout_abstract_syntax.rs index e69de29b..41520641 100644 --- a/src/layout_abstract_syntax.rs +++ b/src/layout_abstract_syntax.rs @@ -0,0 +1,23 @@ +use crate::layout_abstract_attributes::*; + +#[derive(Debug)] +pub struct LayoutAbstractSyntaxNode { + pub namespace: Option, + pub name: String, + pub attributes: Vec, +} + +impl LayoutAbstractSyntaxNode { + pub fn new(namespace: Option, tag: String, attributes: &Vec<(String, String)>) -> Self { + for attribute in attributes { + let parsed = parse_attribute(&attribute.1[..]); + println!("{} : {:?} -> {:?}", attribute.0, attribute.1, parsed); + } + + Self { + namespace, + name: tag, + attributes: Vec::new(), + } + } +} \ No newline at end of file diff --git a/src/layout_abstract_types.rs b/src/layout_abstract_types.rs new file mode 100644 index 00000000..d1625143 --- /dev/null +++ b/src/layout_abstract_types.rs @@ -0,0 +1,64 @@ +use crate::color::Color; + +// Variable types + +#[derive(Debug)] +pub enum VariableValue { + Parameter(VariableParameter), + Argument(String), +} + +#[derive(Debug)] +pub struct VariableParameter { + pub name: String, + pub valid_types: Vec, + pub default: TypeValue, + // pub value: TypeValue, +} + +#[derive(Debug)] +pub struct VariableArgument { + pub name: String, +} + +// Value types + +#[derive(Debug)] +pub enum TypeName { + Xml, + Integer, + Decimal, + AbsolutePx, + Percent, + PercentRemainder, + Inner, + Width, + Height, + TemplateString, + Color, + Bool, + None, +} + +#[derive(Debug)] +pub enum TypeValue { + Xml(()), // TODO + Integer(i64), + Decimal(f64), + AbsolutePx(f32), + Percent(f32), + PercentRemainder(f32), + Inner, + Width, + Height, + TemplateString(Vec), + Color(Color), + Bool(bool), + None, +} + +#[derive(Debug)] +pub enum TemplateStringSegment { + String(String), + Argument(VariableArgument), +} diff --git a/src/layout_parsed_node.rs b/src/layout_parsed_node.rs index 0db4fa51..2bd251fe 100644 --- a/src/layout_parsed_node.rs +++ b/src/layout_parsed_node.rs @@ -17,17 +17,17 @@ impl LayoutParsedNode { #[derive(Debug)] pub struct LayoutParsedTag { pub namespace: Option, - pub tag: String, + pub name: String, pub attributes: Vec<(String, String)>, } impl LayoutParsedTag { - pub fn new(namespace: String, tag: String) -> Self { + pub fn new(namespace: String, name: String) -> Self { let namespace = if namespace.is_empty() { None } else { Some(namespace) }; Self { namespace, - tag, + name, attributes: Vec::new(), } } diff --git a/src/main.rs b/src/main.rs index 7ca97d08..eab7994e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,9 @@ mod gui_attributes; mod window_events; mod gui_layout; mod layout_parsed_node; +mod layout_abstract_types; +mod layout_abstract_attributes; +mod layout_abstract_syntax; use application::Application; use winit::event_loop::EventLoop;