diff --git a/pest/qml.pest b/pest/qml.pest index d2382a3..de84f13 100644 --- a/pest/qml.pest +++ b/pest/qml.pest @@ -20,7 +20,7 @@ digit = { '0'..'9' } ident = { (alpha | digit | ".")+} version = {digit* ~ "." ~ digit*} -import = {"import" ~ WHITE_SPACE ~ ident ~ WHITE_SPACE ~ version ~ NEWLINE*} +import = {"import" ~ WHITE_SPACE ~ ident ~ WHITE_SPACE ~ NEWLINE*} function_code = { !( // if the following text is not diff --git a/res/RedRectangle.qml b/res/RedRectangle.qml new file mode 100644 index 0000000..c8280cb --- /dev/null +++ b/res/RedRectangle.qml @@ -0,0 +1,16 @@ +Grid { + rows:2 + cols:2 + Rectangle { + color: "blue" + } + Rectangle { + color: "red" + } + Rectangle { + color: "red" + } + Rectangle { + color: "blue" + } +} \ No newline at end of file diff --git a/res/example.qml b/res/example.qml index 86f5dd8..f094772 100644 --- a/res/example.qml +++ b/res/example.qml @@ -2,13 +2,10 @@ Grid { rows: 2 columns: 2 - Rectangle { - color: "red" - Text { - anchors.centerIn: parent - text: "Hello, World!" - } + RedRectangle { + null:null } + Rectangle { color: "blue" Text { diff --git a/res/rectangle.qml b/res/rectangle.qml deleted file mode 100644 index 5517c32..0000000 --- a/res/rectangle.qml +++ /dev/null @@ -1,9 +0,0 @@ -Rectangle { - color: "blue" - Rectangle { - color: "blue" - } - Rectangle { - color: "red" - } -} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index fc1d1b4..8e73737 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,8 +6,8 @@ use std::sync::mpsc::{Receiver, Sender}; use std::time::Duration; pub mod parser; pub mod widget_builders; -use crate::parser::Value; use crate::parser::QML; +use crate::parser::{parse_qml, Value}; use crate::widget_builders::QmlWidgetBuilder; use evmap::{ReadHandle, WriteHandle}; @@ -20,6 +20,7 @@ extern crate pest_derive; #[derive(AsAny)] pub struct MainViewState { + pub imports: Vec, pub qml: Vec<(String, QML)>, pub rx: Option>, } diff --git a/src/main.rs b/src/main.rs index bdf92b9..89fac54 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,6 @@ use rqml::MainViewState; fn main() { Application::new() .window(|ctx| { - let _app_context: HashMap = HashMap::new(); let qml_doc = parse_qml("./res/example.qml"); let top_level = qml_doc.children.clone(); println!("{:?}", qml_doc); @@ -16,7 +15,14 @@ fn main() { .position((100.0, 100.0)) .resizeable(true) .size(600.0, 600.0) - .child(MainViewState { qml: top_level.clone(), rx: None }.build(ctx)) + .child( + MainViewState { + imports: qml_doc.imports, + qml: top_level.clone(), + rx: None, + } + .build(ctx), + ) .build(ctx); w }) diff --git a/src/parser.rs b/src/parser.rs index 6230c0d..913e3c4 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -19,6 +19,7 @@ pub enum Value { #[derive(Debug, Clone)] pub struct QML { + pub imports: Vec, pub properties: HashMap, pub children: Vec<(String, QML)>, } @@ -31,6 +32,7 @@ pub fn parse_qml(path: &str) -> QML { fn parse(qml: Pairs) -> QML { let mut qmldoc = QML { + imports: vec![], properties: Default::default(), children: vec![], }; @@ -40,7 +42,9 @@ fn parse(qml: Pairs) -> QML { match pair.as_rule() { Rule::import => { let mut tokens = pair.into_inner(); - println!("Found new Import {} ", tokens.next().unwrap().as_str()); + let import = tokens.next().unwrap().as_str(); + println!("Found new Import {} ", import); + qmldoc.imports.push(String::from(import)); } Rule::body => { let mut tokens = pair.into_inner(); diff --git a/src/widget_builders/import.rs b/src/widget_builders/import.rs new file mode 100644 index 0000000..df059a3 --- /dev/null +++ b/src/widget_builders/import.rs @@ -0,0 +1,22 @@ +use crate::parser::Value::QmlString; +use crate::parser::{parse_qml, Value, QML}; +use crate::widget_builders::{parse_number, QmlWidgetBuilder, WidgetBuilder}; +use orbtk::prelude::HashMap; +use orbtk::prelude::*; +use orbtk::Entity; +use std::borrow::BorrowMut; + +pub struct ImportBuilder { + pub(crate) source: String, +} + +impl WidgetBuilder for ImportBuilder { + fn build(&self, properties: HashMap, children: Vec<(String, QML)>) -> Box) -> Entity> { + let import_source = self.source.clone(); + return Box::new(move |id, ctx, row, col, ids| -> Entity { + let qml_doc = parse_qml(format!("./res/{}.qml", import_source).as_str()); + let top_level = qml_doc.children.clone(); + QmlWidgetBuilder::new().build(id, 0, 0, top_level[0].0.clone(), top_level[0].1.clone(), ctx, ids.borrow_mut()) + }); + } +} diff --git a/src/widget_builders/mod.rs b/src/widget_builders/mod.rs index 4a4aa71..1578b34 100644 --- a/src/widget_builders/mod.rs +++ b/src/widget_builders/mod.rs @@ -8,10 +8,12 @@ use crate::widget_builders::textfield::TextBuilder; use orbtk::prelude::*; use orbtk::Entity; +use crate::widget_builders::import::ImportBuilder; use std::collections::HashMap; pub mod button; pub mod grid; +pub mod import; pub mod rectangle; pub mod textedit; pub mod textfield; @@ -50,7 +52,12 @@ impl QmlWidgetBuilder { return widget; } - _ => {} + _ => { + let builder = ImportBuilder { source: widget_type }; + let wfn = builder.build(qml.properties, qml.children); + let widget = wfn(id, ctx, row, col, ids); + return widget; + } } return ctx.create_entity(); }