diff --git a/Cargo.lock b/Cargo.lock
index 15f66aec..2f10e670 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -434,9 +434,9 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
- "proc-macro2 1.0.15",
+ "proc-macro2 1.0.17",
"quote 1.0.6",
- "syn 1.0.23",
+ "syn 1.0.24",
"synstructure",
]
@@ -538,9 +538,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
dependencies = [
"proc-macro-hack",
- "proc-macro2 1.0.15",
+ "proc-macro2 1.0.17",
"quote 1.0.6",
- "syn 1.0.23",
+ "syn 1.0.24",
]
[[package]]
@@ -788,6 +788,7 @@ dependencies = [
"rctree",
"wgpu",
"winit",
+ "xmlparser",
]
[[package]]
@@ -1182,9 +1183,9 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b4b5f600e60dd3a147fb57b4547033d382d1979eb087af310e91cb45a63b1f4"
dependencies = [
- "proc-macro2 1.0.15",
+ "proc-macro2 1.0.17",
"quote 1.0.6",
- "syn 1.0.23",
+ "syn 1.0.24",
]
[[package]]
@@ -1226,9 +1227,9 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb44a25c5bba983be0fc8592dfaf3e6d0935ce8be0c6b15b2a39507af34a926"
dependencies = [
- "proc-macro2 1.0.15",
+ "proc-macro2 1.0.17",
"quote 1.0.6",
- "syn 1.0.23",
+ "syn 1.0.24",
"synstructure",
"unicode-xid 0.2.0",
]
@@ -1292,9 +1293,9 @@ version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e58db2081ba5b4c93bd6be09c40fd36cb9193a8336c384f3b40012e531aa7e40"
dependencies = [
- "proc-macro2 1.0.15",
+ "proc-macro2 1.0.17",
"quote 1.0.6",
- "syn 1.0.23",
+ "syn 1.0.24",
]
[[package]]
@@ -1329,9 +1330,9 @@ checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
[[package]]
name = "proc-macro-hack"
-version = "0.5.15"
+version = "0.5.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63"
+checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
[[package]]
name = "proc-macro-nested"
@@ -1350,9 +1351,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.15"
+version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70a50b9351bfa8d65a7d93ce712dc63d2fd15ddbf2c36990fc7cac344859c04f"
+checksum = "1502d12e458c49a4c9cbff560d0fe0060c252bc29799ed94ca2ed4bb665a0101"
dependencies = [
"unicode-xid 0.2.0",
]
@@ -1372,7 +1373,7 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
dependencies = [
- "proc-macro2 1.0.15",
+ "proc-macro2 1.0.17",
]
[[package]]
@@ -1736,11 +1737,11 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.23"
+version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95b5f192649e48a5302a13f2feb224df883b98933222369e4b3b0fe2a5447269"
+checksum = "f87bc5b2815ebb664de0392fdf1b95b6d10e160f86d9f64ff65e5679841ca06a"
dependencies = [
- "proc-macro2 1.0.15",
+ "proc-macro2 1.0.17",
"quote 1.0.6",
"unicode-xid 0.2.0",
]
@@ -1751,9 +1752,9 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
dependencies = [
- "proc-macro2 1.0.15",
+ "proc-macro2 1.0.17",
"quote 1.0.6",
- "syn 1.0.23",
+ "syn 1.0.24",
"unicode-xid 0.2.0",
]
@@ -1849,9 +1850,9 @@ dependencies = [
"bumpalo",
"lazy_static",
"log",
- "proc-macro2 1.0.15",
+ "proc-macro2 1.0.17",
"quote 1.0.6",
- "syn 1.0.23",
+ "syn 1.0.24",
"wasm-bindgen-shared",
]
@@ -1871,9 +1872,9 @@ version = "0.2.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a"
dependencies = [
- "proc-macro2 1.0.15",
+ "proc-macro2 1.0.17",
"quote 1.0.6",
- "syn 1.0.23",
+ "syn 1.0.24",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -2135,3 +2136,9 @@ name = "xml-rs"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a"
+
+[[package]]
+name = "xmlparser"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccb4240203dadf40be2de9369e5c6dec1bf427528115b030baca3334c18362d7"
diff --git a/Cargo.toml b/Cargo.toml
index e4ee7130..91d5bf99 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,3 +17,4 @@ palette = "0.5"
futures = "0.3.4"
bytemuck = "1.2.0"
rctree = "0.3.3"
+xmlparser = "0.13.1"
diff --git a/gui/header/file-menu.xml b/gui/header/file-menu.xml
index 722142f2..abf0c966 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 50c91929..250199e3 100644
--- a/gui/header/window-buttons.xml
+++ b/gui/header/window-buttons.xml
@@ -1,4 +1,4 @@
-
+
@@ -13,4 +13,4 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/gui/input/checkbox-with-dropdown.xml b/gui/input/checkbox-with-dropdown.xml
index 03e811bd..cc5f0ee3 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 5033548c..4f61fb2c 100644
--- a/gui/input/checkbox.xml
+++ b/gui/input/checkbox.xml
@@ -1,4 +1,4 @@
-
+
@@ -17,4 +17,4 @@
-
+
diff --git a/gui/input/dropdown.xml b/gui/input/dropdown.xml
index a95913f8..96be7900 100644
--- a/gui/input/dropdown.xml
+++ b/gui/input/dropdown.xml
@@ -1,8 +1,8 @@
-
+
- {{CURRENT_TEXT}}
+ {{CURRENT_TEXT}}
@@ -13,4 +13,4 @@
-
+
diff --git a/gui/viewport/panels.xml b/gui/viewport/panels.xml
index 7934780b..ca08807e 100644
--- a/gui/viewport/panels.xml
+++ b/gui/viewport/panels.xml
@@ -1,7 +1,7 @@
-
+
Option A
Option B
Option C
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/gui/window/main.xml b/gui/window/main.xml
index 21e45378..c527b3ac 100644
--- a/gui/window/main.xml
+++ b/gui/window/main.xml
@@ -1,18 +1,18 @@
-
-
+
+
-
- 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 d1a1ad70..ab886b39 100644
--- a/src/application.rs
+++ b/src/application.rs
@@ -3,7 +3,7 @@ use crate::window_events;
use crate::pipeline::Pipeline;
use crate::texture::Texture;
use crate::resource_cache::ResourceCache;
-use crate::draw_command::DrawCommand;
+use crate::component_layout::ComponentLayout;
use crate::gui_node::GuiNode;
use winit::event::*;
use winit::event_loop::*;
@@ -75,6 +75,8 @@ impl Application {
let gui_root_data = GuiNode::new(swap_chain_descriptor.width, swap_chain_descriptor.height, ColorPalette::get_color_srgb(ColorPalette::Accent));
let gui_root = rctree::Node::new(gui_root_data);
+ ComponentLayout::new();
+
Self {
surface,
adapter,
diff --git a/src/component_layout.rs b/src/component_layout.rs
new file mode 100644
index 00000000..7d18d07a
--- /dev/null
+++ b/src/component_layout.rs
@@ -0,0 +1,116 @@
+use std::fs;
+use std::io;
+use crate::parsed_layout_node::*;
+
+pub struct ComponentLayout {
+
+}
+
+impl ComponentLayout {
+ pub fn new() -> ComponentLayout {
+ let parsed_layout_tree = Self::parse_xml_file("gui/window/main.xml").unwrap();
+ for node in parsed_layout_tree.descendants() {
+ println!("{:?}", node);
+ }
+ Self {}
+ }
+
+ pub fn parse_xml_file(path: &str) -> io::Result> {
+ let source = fs::read_to_string(path)?;
+ let parsed = xmlparser::Tokenizer::from(&source[..]);
+
+ let mut stack: Vec> = Vec::new();
+ let mut current: Option> = None;
+ let mut result: Option> = None;
+
+ for token in parsed {
+ match token.unwrap() {
+ xmlparser::Token::ElementStart { prefix, local, .. } => {
+ let namespace = String::from(prefix.as_str());
+ let tag_name = String::from(local.as_str());
+
+ let new_parsed_layout_node = ParsedLayoutNode::new_tag(namespace, tag_name);
+
+ let new_node = rctree::Node::new(new_parsed_layout_node);
+ current = Some(new_node);
+ }
+ xmlparser::Token::Attribute { prefix, local, value, .. } => {
+ let colon_prefixed = prefix.start() > 0 && (prefix.start() == prefix.end());
+ let key = if colon_prefixed {
+ let slice = local.as_str();
+ let mut string = String::with_capacity(slice.len() + 1);
+ string.push(':');
+ string.push_str(slice);
+ string
+ } else { String::from(local.as_str()) };
+ let value = String::from(value.as_str());
+ let attribute = (key, value);
+
+ match &mut current {
+ Some(current_node) => {
+ match &mut *current_node.borrow_mut() {
+ ParsedLayoutNode::Tag(tag) => {
+ // Add this attribute to the current node that has not yet reached its closing angle bracket
+ tag.add_attribute(attribute);
+ }
+ ParsedLayoutNode::Text(_) => {
+ panic!("Error adding attribute to tag when parsing XML layout in file: {}", path);
+ }
+ }
+ }
+ None => {
+ panic!("Error adding attribute to tag when parsing XML layout in file: {}", path);
+ }
+ }
+ }
+ xmlparser::Token::ElementEnd { end, .. } => {
+ match end {
+ // After adding any attributes, the opening tag ends
+ xmlparser::ElementEnd::Open => {
+ // After adding any attributes, we are now a layer deeper which the stack keeps track of
+ let node_to_push = current.take().expect(&format!("Invalid syntax when parsing XML layout in file {}", path)[..]);
+ stack.push(node_to_push);
+ }
+ // After adding any attributes, the self-closing tag ends
+ xmlparser::ElementEnd::Empty => {
+ let parent_node = stack.last_mut().expect(&format!("Invalid syntax when parsing XML layout in file: {}", path)[..]);
+ let new_child = current.take().expect(&format!("Invalid syntax when parsing XML layout in file: {}", path)[..]);
+ parent_node.append(new_child);
+ }
+ // The closing tag is reached
+ xmlparser::ElementEnd::Close(..) => {
+ let popped_node = stack.pop().expect(&format!("Encountered extra closing tag when parsing XML layout in file: {}", path)[..]);
+ match stack.last_mut() {
+ Some(parent_node) => {
+ parent_node.append(popped_node);
+ }
+ None => {
+ match result {
+ None => result = Some(popped_node),
+ Some(_) => panic!("Encountered multiple root-level tags when parsing XML layout in file: {}", path),
+ }
+ }
+ }
+ }
+ }
+ }
+ xmlparser::Token::Text { text } => {
+ let parent_node = stack.last_mut().expect(&format!("Encountered text outside the root tag when parsing XML layout in file: {}", path)[..]);
+ let text_string = String::from(text.as_str());
+
+ if !text_string.trim().is_empty() {
+ let text_node = ParsedLayoutNode::new_text(text_string);
+ let new_node = rctree::Node::new(text_node);
+ parent_node.append(new_node);
+ }
+ }
+ _ => {}
+ }
+ }
+
+ match result {
+ None => panic!("Invalid syntax when parsing XML layout in file: {}", path),
+ Some(tree) => Ok(tree)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index 6d692dff..b5e53000 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,6 +9,8 @@ mod draw_command;
mod gui_node;
mod gui_attributes;
mod window_events;
+mod component_layout;
+mod parsed_layout_node;
use application::Application;
use winit::event_loop::EventLoop;
diff --git a/src/parsed_layout_node.rs b/src/parsed_layout_node.rs
new file mode 100644
index 00000000..6110f36e
--- /dev/null
+++ b/src/parsed_layout_node.rs
@@ -0,0 +1,38 @@
+#[derive(Debug)]
+pub enum ParsedLayoutNode {
+ Tag(ParsedLayoutTag),
+ Text(String),
+}
+
+impl ParsedLayoutNode {
+ pub fn new_tag(namespace: String, tag: String) -> Self {
+ Self::Tag(ParsedLayoutTag::new(namespace, tag))
+ }
+
+ pub fn new_text(text: String) -> Self {
+ Self::Text(text)
+ }
+}
+
+#[derive(Debug)]
+pub struct ParsedLayoutTag {
+ pub namespace: Option,
+ pub tag: String,
+ pub attributes: Vec<(String, String)>,
+}
+
+impl ParsedLayoutTag {
+ pub fn new(namespace: String, tag: String) -> Self {
+ let namespace = if namespace.is_empty() { None } else { Some(namespace) };
+
+ Self {
+ namespace,
+ tag,
+ attributes: Vec::new(),
+ }
+ }
+
+ pub fn add_attribute(&mut self, attribute: (String, String)) {
+ self.attributes.push(attribute);
+ }
+}
\ No newline at end of file