diff --git a/Cargo.lock b/Cargo.lock index ed9a27a..b40f9b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -122,6 +122,12 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +[[package]] +name = "case" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6c0e7b807d60291f42f33f58480c0bfafe28ed08286446f45e463728cf9c1c" + [[package]] name = "cast" version = "0.2.3" @@ -252,7 +258,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bb1c84e87c717666564ec056105052331431803d606bd45529b28547b611eef" dependencies = [ "phf_codegen", - "proc-macro2 1.0.18", + "proc-macro2", "procedural-masquerade", "quote 1.0.7", "syn 1.0.33", @@ -260,9 +266,8 @@ dependencies = [ [[package]] name = "dces" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4698c248ce1f7c061c16a1ff4e4df4f030eb953ef3d98e4a467d83ede255d806" +version = "0.3.0" +source = "git+https://gitlab.redox-os.org/redox-os/dces-rust.git?branch=develop#58f66adc80a32f28cf915ef07113db07941343bb" [[package]] name = "deflate" @@ -290,7 +295,7 @@ version = "0.99.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "298998b1cf6b5b2c8a7b023dfd45821825ce3ba8a8af55c921a0e734e4653f76" dependencies = [ - "proc-macro2 1.0.18", + "proc-macro2", "quote 1.0.7", "syn 1.0.33", ] @@ -361,6 +366,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "evmap" +version = "11.0.0-alpha.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59d154215aff4902974f10c21e9319f7308e249183b31375f23a7e4999793bd0" +dependencies = [ + "hashbag", + "slab", + "smallvec", +] + [[package]] name = "fake-simd" version = "0.1.2" @@ -403,6 +419,12 @@ dependencies = [ "lzw", ] +[[package]] +name = "hashbag" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "452b31b3ffe7cf13de531eefae493301c85995a953c808d7c79a8f45abae0706" + [[package]] name = "hermit-abi" version = "0.1.14" @@ -412,23 +434,6 @@ dependencies = [ "libc", ] -[[package]] -name = "image" -version = "0.22.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08ed2ada878397b045454ac7cfb011d73132c59f31a955d230bd1f1c2e68eb4a" -dependencies = [ - "byteorder", - "gif", - "jpeg-decoder", - "num-iter", - "num-rational 0.2.4", - "num-traits", - "png 0.15.3", - "scoped_threadpool", - "tiff 0.3.1", -] - [[package]] name = "image" version = "0.23.6" @@ -440,11 +445,11 @@ dependencies = [ "gif", "jpeg-decoder", "num-iter", - "num-rational 0.3.0", + "num-rational", "num-traits", "png 0.16.6", "scoped_threadpool", - "tiff 0.5.0", + "tiff", ] [[package]] @@ -569,15 +574,13 @@ dependencies = [ [[package]] name = "minifb" version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b18d2987dac6afdd7f6d81101a3b422b7da3e6799d7f11863ad006d8ccd562b2" +source = "git+https://github.com/FloVanGH/rust_minifb?branch=redox_unix#729a68c2e40c620dc1cbb9c9b116de21385a10a0" dependencies = [ "cast", "cc", "orbclient", "raw-window-handle", "tempfile", - "time", "wayland-client", "wayland-cursor", "wayland-protocols", @@ -620,17 +623,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-derive" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "syn 0.15.44", -] - [[package]] name = "num-integer" version = "0.1.43" @@ -652,17 +644,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-rational" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" -dependencies = [ - "autocfg 1.0.0", - "num-integer", - "num-traits", -] - [[package]] name = "num-rational" version = "0.3.0" @@ -717,9 +698,8 @@ dependencies = [ [[package]] name = "orbtk" -version = "0.3.1-alpha2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b9414ddae4c9ea12901c9ac0a0f5fd2f50f726bb0e1a7b675df618c1ddb066" +version = "0.3.1-alpha3" +source = "git+https://github.com/redox-os/orbtk.git?branch=develop#e8b0f9a3f8dc322414f1ea64de57f72979e17496" dependencies = [ "dces", "orbtk-api", @@ -735,9 +715,8 @@ dependencies = [ [[package]] name = "orbtk-api" -version = "0.3.1-alpha2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "151a18102182fa410d04b36c17296eb234f0d99960a48d2f7a3cd2b93d73fa0b" +version = "0.3.1-alpha3" +source = "git+https://github.com/redox-os/orbtk.git?branch=develop#e8b0f9a3f8dc322414f1ea64de57f72979e17496" dependencies = [ "dces", "derive_more", @@ -758,9 +737,8 @@ dependencies = [ [[package]] name = "orbtk-css-engine" -version = "0.3.1-alpha2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd2446ad3bbb269b5d34474aa66556adc24149411be5a94b5423331229f2e19" +version = "0.3.1-alpha3" +source = "git+https://github.com/redox-os/orbtk.git?branch=develop#e8b0f9a3f8dc322414f1ea64de57f72979e17496" dependencies = [ "cssparser", "orbtk-utils", @@ -768,21 +746,21 @@ dependencies = [ [[package]] name = "orbtk-proc-macros" -version = "0.3.1-alpha2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfabbd9601d69bcfed57916b51bd8b45cd067f6d4078f83d1dc65641c32fcb0a" +version = "0.3.1-alpha3" +source = "git+https://github.com/redox-os/orbtk.git?branch=develop#e8b0f9a3f8dc322414f1ea64de57f72979e17496" dependencies = [ + "case", + "proc-macro2", "quote 1.0.7", "syn 1.0.33", ] [[package]] name = "orbtk-render" -version = "0.3.1-alpha2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca77684bfc332efa7188cc1f264691e0826a182262ccb0670b3def0f6199bd0e" +version = "0.3.1-alpha3" +source = "git+https://github.com/redox-os/orbtk.git?branch=develop#e8b0f9a3f8dc322414f1ea64de57f72979e17496" dependencies = [ - "image 0.23.6", + "image", "orbtk-utils", "raqote", "rusttype", @@ -791,12 +769,12 @@ dependencies = [ [[package]] name = "orbtk-shell" -version = "0.3.1-alpha2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49d8f44e28aa9fe3a5a721176d3ce4b829f709f8a041dc3c5b923f4c4a0afb2f" +version = "0.3.1-alpha3" +source = "git+https://github.com/redox-os/orbtk.git?branch=develop#e8b0f9a3f8dc322414f1ea64de57f72979e17496" dependencies = [ "console_error_panic_hook", - "image 0.22.5", + "derive_more", + "image", "lazy_static", "minifb", "orbtk-render", @@ -808,9 +786,8 @@ dependencies = [ [[package]] name = "orbtk-theme" -version = "0.3.1-alpha2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aba87783f8a9cca78b8d8f4e919c78712492efbe27da0ef7a477efc5dd257a41" +version = "0.3.1-alpha3" +source = "git+https://github.com/redox-os/orbtk.git?branch=develop#e8b0f9a3f8dc322414f1ea64de57f72979e17496" dependencies = [ "lazy_static", "orbtk-css-engine", @@ -818,32 +795,31 @@ dependencies = [ [[package]] name = "orbtk-tree" -version = "0.3.1-alpha2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "083e46cdf2db24dcc2ffb65d6a1feddc1a484159c56f5032e668972a344ccb9c" +version = "0.3.1-alpha3" +source = "git+https://github.com/redox-os/orbtk.git?branch=develop#e8b0f9a3f8dc322414f1ea64de57f72979e17496" dependencies = [ "dces", ] [[package]] name = "orbtk-utils" -version = "0.3.1-alpha2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2e34dee0cf7e0d5675908a7e890c798f36357de3f9f69941e8319545ada1bde" +version = "0.3.1-alpha3" +source = "git+https://github.com/redox-os/orbtk.git?branch=develop#e8b0f9a3f8dc322414f1ea64de57f72979e17496" [[package]] name = "orbtk-widgets" -version = "0.3.1-alpha2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9b48215fac8030c2e4e0bf38dccf648e36b1d6826d31e2cf965f5c51ceb5e86" +version = "0.3.1-alpha3" +source = "git+https://github.com/redox-os/orbtk.git?branch=develop#e8b0f9a3f8dc322414f1ea64de57f72979e17496" dependencies = [ "dces", + "lazy_static", "orbtk-api", "orbtk-proc-macros", "orbtk-render", "orbtk-shell", "orbtk-theme", "orbtk-utils", + "rust_decimal", ] [[package]] @@ -882,7 +858,7 @@ checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.18", + "proc-macro2", "quote 1.0.7", "syn 1.0.33", ] @@ -972,15 +948,6 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" -[[package]] -name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] - [[package]] name = "proc-macro2" version = "1.0.18" @@ -1002,22 +969,13 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -[[package]] -name = "quote" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" -dependencies = [ - "proc-macro2 0.4.30", -] - [[package]] name = "quote" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ - "proc-macro2 1.0.18", + "proc-macro2", ] [[package]] @@ -1169,9 +1127,9 @@ dependencies = [ [[package]] name = "raqote" -version = "0.7.14" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e8400fa875bc4d584d9145cef72074df4d51d106dcc52678d4bf4214ba52eae" +checksum = "501c19caa439857ed7bea975fa4c3c10ee9a24e33c2640030c3ac14b58f39f77" dependencies = [ "euclid", "lyon_geom", @@ -1274,6 +1232,7 @@ dependencies = [ name = "rqml" version = "0.1.0" dependencies = [ + "evmap", "orbtk", "pest", "pest_derive", @@ -1292,6 +1251,16 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rust_decimal" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b5f52edf35045e96b07aa29822bf4ce8495295fd5610270f85ab1f26df7ba5" +dependencies = [ + "num-traits", + "serde", +] + [[package]] name = "rustc_version" version = "0.2.3" @@ -1390,7 +1359,7 @@ version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0be94b04690fbaed37cddffc5c134bf537c8e3329d53e982fe04c374978f8e" dependencies = [ - "proc-macro2 1.0.18", + "proc-macro2", "quote 1.0.7", "syn 1.0.33", ] @@ -1430,6 +1399,12 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" +[[package]] +name = "slab" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" + [[package]] name = "smallvec" version = "1.4.0" @@ -1438,11 +1413,11 @@ checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" [[package]] name = "spin_sleep" -version = "0.3.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891836ef5f8a5b9678938d34d75391a3794267806482105ffcd363271980c10c" +checksum = "2a98101bdc3833e192713c2af0b0dd2614f50d1cf1f7a97c5221b7aac052acc7" dependencies = [ - "lazy_static", + "once_cell", "winapi", ] @@ -1477,7 +1452,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" dependencies = [ - "proc-macro2 1.0.18", + "proc-macro2", "quote 1.0.7", "serde", "serde_derive", @@ -1491,7 +1466,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" dependencies = [ "base-x", - "proc-macro2 1.0.18", + "proc-macro2", "quote 1.0.7", "serde", "serde_derive", @@ -1523,24 +1498,13 @@ dependencies = [ "unicode-xid 0.0.4", ] -[[package]] -name = "syn" -version = "0.15.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "unicode-xid 0.1.0", -] - [[package]] name = "syn" version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" dependencies = [ - "proc-macro2 1.0.18", + "proc-macro2", "quote 1.0.7", "unicode-xid 0.2.1", ] @@ -1568,18 +1532,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "tiff" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b7c2cfc4742bd8a32f2e614339dd8ce30dbcf676bb262bd63a2327bc5df57d" -dependencies = [ - "byteorder", - "lzw", - "num-derive", - "num-traits", -] - [[package]] name = "tiff" version = "0.5.0" @@ -1591,16 +1543,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "typed-arena" version = "2.0.1" @@ -1625,12 +1567,6 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - [[package]] name = "unicode-xid" version = "0.2.1" @@ -1668,7 +1604,7 @@ dependencies = [ "bumpalo", "lazy_static", "log", - "proc-macro2 1.0.18", + "proc-macro2", "quote 1.0.7", "syn 1.0.33", "wasm-bindgen-shared", @@ -1690,7 +1626,7 @@ version = "0.2.64" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75" dependencies = [ - "proc-macro2 1.0.18", + "proc-macro2", "quote 1.0.7", "syn 1.0.33", "wasm-bindgen-backend", @@ -1759,7 +1695,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f45ddc08a8078f3efa96b5f413268cc9c53b30712891de081fbc1d5846fbc736" dependencies = [ - "proc-macro2 1.0.18", + "proc-macro2", "quote 1.0.7", "xml-rs", ] diff --git a/Cargo.toml b/Cargo.toml index ada20de..8891890 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,5 +9,6 @@ edition = "2018" [dependencies] pest = "2.1.3" pest_derive = "2.1.0" -orbtk = "0.3.1-alpha2" -rhai = "0.16.1" \ No newline at end of file +orbtk = { git = "https://github.com/redox-os/orbtk.git", branch = "develop" } +rhai = "0.16.1" +evmap = "11.0.0-alpha.1" \ No newline at end of file diff --git a/res/example.qml b/res/example.qml index 9e6b3ac..86f5dd8 100644 --- a/res/example.qml +++ b/res/example.qml @@ -30,16 +30,23 @@ Grid { Rectangle { color: "red" - Text { + TextField { + id: tf1 anchors.centerIn: parent - text: "Hello, World!" + text: "Test" + onchange = [[ + ]] } } Rectangle { color: "blue" - Text { + Button { anchors.centerIn: parent text: "Hello, World!" + onclick = [[ + print("Hello World!"); + update_property("target", "text", get_property("tf1","text")); + ]] } } Rectangle { diff --git a/res/rectangle.qml b/res/rectangle.qml new file mode 100644 index 0000000..5517c32 --- /dev/null +++ b/res/rectangle.qml @@ -0,0 +1,9 @@ +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 c71f384..9293c58 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,20 @@ use orbtk::prelude::*; + +use rhai::Engine; use rhai::RegisterFn; -use rhai::{Engine}; 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 parser::Value::{QmlIdent, QmlNumber, QmlString}; +use crate::widget_builders::QmlWidgetBuilder; +use evmap::{ReadHandle, WriteHandle}; + +use std::borrow::{BorrowMut}; +use std::collections::VecDeque; +use std::sync::mpsc; + #[macro_use] extern crate pest_derive; @@ -15,21 +23,64 @@ extern crate pest_derive; pub struct MainViewState { pub qml: Vec<(String, QML)>, pub rx: Option>, - pub state1: Option, - pub state2: Option, } impl Widget for MainViewState { - fn create() -> Self { + fn new() -> Self { unimplemented!() } fn build(self, ctx: &mut BuildContext) -> Entity { let top_level = self.qml.clone(); let widget = ctx.create_entity(); - let this = render_ctx(widget, ctx, &top_level, 0, 0).unwrap(); - ctx.register_state(this, Box::new(self.state2.unwrap())); - ctx.register_state(widget, Box::new(self.state1.unwrap())); + + let (tx, rx): ( + Sender<(String, String, String)>, + Receiver<(String, String, String)>, + ) = mpsc::channel(); + let (txf, rxf): ( + Sender<(String, String, String)>, + Receiver<(String, String, String)>, + ) = mpsc::channel(); + + let (r, w) = evmap::new(); + + let mut ids = vec![]; + let this = QmlWidgetBuilder::new().build( + widget, + 0, + 0, + top_level[0].0.clone(), + top_level[0].1.clone(), + ctx, + ids.borrow_mut(), + ); //render_ctx(widget, ctx, &top_level, 0, 0, ids.borrow_mut()).unwrap(); + ctx.register_state( + this, + Box::new(MVState { + tx: Some(tx.clone()), + rx: Some(rxf), + engine: Engine::new(), + codes: VecDeque::new(), + ids: ids.clone(), + value_map: (None, Some(w)), + }), + ); + let mut codes = VecDeque::new(); + codes.push_back(String::new()); + codes.push_back(String::new()); + codes.push_back(String::new()); + ctx.register_state( + widget, + Box::new(MVState { + rx: Some(rx), + tx: Some(txf), + engine: Engine::new(), + codes: codes, + ids: ids.clone(), + value_map: (Some(r), None), + }), + ); this } @@ -47,17 +98,35 @@ pub struct MVState { pub engine: Engine, pub tx: Option>, pub rx: Option>, + pub codes: VecDeque, + pub ids: Vec, + pub value_map: ( + Option>, + Option>, + ), } impl MVState { - fn action(&mut self, action: String) { + fn action(&mut self, code: String) { match self.tx.clone() { Some(tx) => { + let _ftx = tx.clone(); self.engine .register_fn("update_property", move |x: &str, y: &str, z: &str| { tx.send((String::from(x), String::from(y), String::from(z))); }); - let _result = self.engine.eval::<()>(action.as_str()); + + let r = self.value_map.0.as_ref().unwrap().clone(); + self.engine + .register_fn("get_property", move |x: &str, y: &str| -> String { + let key = format!("{}.{}", x, y); + if r.contains_key(key.as_str()) { + return String::from(r.get_one(key.as_str()).unwrap().as_str()); + } + String::new() + }); + let result = self.engine.eval::<()>(code.as_str()); + println!("{:?}", result); } _ => {} } @@ -70,6 +139,22 @@ impl State for MVState { } fn update(&mut self, _registry: &mut Registry, ctx: &mut Context) { + match self.value_map.1.borrow_mut() { + Some(w) => { + for id in self.ids.iter() { + let res = ctx.child(id.as_str()).get::("text").clone(); + let key = format!("{}.text", id); + if w.contains_value(&key, &res.as_string()) == false { + println!("Updating to {}", res.as_string()); + } + w.update(id.clone() + ".text", res.as_string()); + } + w.refresh(); + } + _ => {} + } + + let _tx = self.tx.clone().unwrap().clone(); match &self.rx { Some(rx) => match rx.recv_timeout(Duration::from_millis(1)) { Ok((x, y, z)) => { @@ -85,160 +170,8 @@ impl State for MVState { impl Template for MainViewState {} -fn parse_number(val: Option<&Value>) -> f64 { - match val { - Some(QmlNumber(num)) => num.clone(), - _ => 0.0, - } -} -fn render_ctx( - id: Entity, - ctx: &mut BuildContext, - qml: &Vec<(String, QML)>, - row: u32, - col: u32, -) -> Option { - for (ident, child) in qml.iter() { - match ident.as_str() { - "Grid" => { - let mut grid = Grid::create(); - grid = grid.attach(Grid::row(row as usize)); - grid = grid.attach(Grid::column(col as usize)); - let rows = parse_number(child.properties.get("rows")) as u32; - let _cols = parse_number(child.properties.get("cols")) as u32; - let mut grid_rows = Rows::create(); - for _i in 0..rows { - grid_rows = grid_rows.row("stretch"); - } - grid = grid.rows(grid_rows.build()); - - let mut grid_cols = Columns::create(); - for _i in 0..rows { - grid_cols = grid_cols.column("stretch"); - } - grid = grid.columns(grid_cols.build()); - - let mut grow = 0u32; - let mut gcol = 0u32; - //rect = rect.attach(Grid::column(gcol as usize)); - for (i, s) in child.children.iter() { - match render_ctx(id, ctx, &vec![(i.clone(), s.clone())], grow, gcol) { - Some(entity) => { - grid = grid.child(entity); - grow += 1; - if grow as u32 == rows { - grow = 0; - gcol += 1; - } - } - _ => {} - } - } - - return Some(grid.build(ctx)); - } - "Rectangle" => { - let _width = parse_number(child.properties.get("width")); - let _height = parse_number(child.properties.get("height")); - - let color = match child.properties.get("color") { - Some(QmlString(col)) => match col.as_str() { - "red" => Color::rgb(0xff, 00, 00), - "blue" => Color::rgb(0x00, 00, 0xff), - _ => Color::rgb(0xff, 0xff, 0xff), - }, - _ => Color::rgb(0xff, 0xff, 0xff), - }; - let mut rect = Container::create() - // .width(width) - // .height(height) - .background(color); - - rect = rect.attach(Grid::row(row as usize)); - rect = rect.attach(Grid::column(col as usize)); - - for (i, s) in child.children.iter() { - match render_ctx(id, ctx, &vec![(i.clone(), s.clone())], 0, 0) { - Some(entity) => { - rect = rect.child(entity); - } - _ => {} - } - } - - return Some(rect.build(ctx)); - } - "Button" => { - let mut button = Button::create(); - button = button.attach(Grid::row(row as usize)); - button = button.attach(Grid::column(col as usize)); - - let code = match child.properties.get("onclick").unwrap() { - QmlString(code) => code.clone(), - _ => String::new(), - }; - - button = button.on_click(move |states, _| -> bool { - state(id, states).action(code.clone()); - return true; - }); - - let text = match child.properties.get("text").unwrap() { - QmlString(text) => text.clone(), - _ => String::new(), - }; - - match child.properties.get("anchors.centerIn") { - Some(QmlIdent(str)) => { - if str.eq("parent") { - button = button.vertical_alignment(Alignment::Center); - button = button.horizontal_alignment(Alignment::Center); - } - } - _ => {} - } - button = button.text(text); - - return Some(button.build(ctx)); - } - "Text" => { - let text = match child.properties.get("text") { - Some(QmlString(text)) => text.clone(), - _ => String::new(), - }; - - let mut tt = TextBlock::create(); - tt = tt.text(text); - tt = tt.attach(Grid::row(row as usize)); - tt = tt.attach(Grid::column(col as usize)); - - match child.properties.get("id") { - Some(QmlIdent(text)) => { - tt = tt.id(text.clone()); - } - _ => {} - }; - - match child.properties.get("anchors.centerIn") { - Some(QmlIdent(str)) => { - if str.eq("parent") { - tt = tt.vertical_alignment(Alignment::Center); - tt = tt.horizontal_alignment(Alignment::Center); - } - } - _ => {} - } - let entity = tt.build(ctx); - return Some(entity); - } - _ => println!("unknown ident {}", ident), - } - } - None -} - -fn state<'a>(id: Entity, states: &'a mut StatesContext) -> &'a mut MVState { +pub fn state<'a>(id: Entity, states: &'a mut StatesContext) -> &'a mut MVState { states.get_mut(id) } diff --git a/src/main.rs b/src/main.rs index 30ec6bd..072f96c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,8 @@ use orbtk::prelude::*; + use rqml::parser::parse_qml; -use rqml::{MVState, MainViewState}; -use std::sync::mpsc; -use std::sync::mpsc::{Receiver, Sender}; -use rhai::Engine; +use rqml::{MainViewState}; + fn main() { @@ -13,11 +12,8 @@ fn main() { let qml_doc = parse_qml("./res/example.qml"); let top_level = qml_doc.children.clone(); println!("{:?}", qml_doc); - let (tx, rx): ( - Sender<(String, String, String)>, - Receiver<(String, String, String)>, - ) = mpsc::channel(); - let w = Window::create() + + let w = Window::new() .title("QML") .position((100.0, 100.0)) .resizeable(true) @@ -26,16 +22,6 @@ fn main() { MainViewState { qml: top_level.clone(), rx: None, - state1: Some(MVState { - tx: Some(tx.clone()), - rx: None, - engine: Engine::new(), - }), - state2: Some(MVState { - rx: Some(rx), - tx: None, - engine: Engine::new(), - }), } .build(ctx), ) diff --git a/src/parser.rs b/src/parser.rs index a93637d..5cc07f1 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,7 +1,7 @@ extern crate pest; use crate::Value::{QmlIdent, QmlNumber, QmlString}; -use pest::iterators::{Pairs}; +use pest::iterators::Pairs; use pest::Parser; use std::collections::HashMap; use std::fs::read_to_string; diff --git a/src/widget_builders/button.rs b/src/widget_builders/button.rs new file mode 100644 index 0000000..4206b9c --- /dev/null +++ b/src/widget_builders/button.rs @@ -0,0 +1,51 @@ +use crate::parser::Value::{QmlIdent, QmlString}; +use crate::parser::{Value, QML}; +use crate::state; +use crate::widget_builders::{WidgetBuilder}; +use orbtk::prelude::HashMap; +use orbtk::prelude::*; +use orbtk::Entity; + + +pub struct ButtonBuilder {} + +impl WidgetBuilder for ButtonBuilder { + fn build( + &self, + properties: HashMap, + _children: Vec<(String, QML)>, + ) -> Box) -> Entity> { + return Box::new(move |id, ctx, row, col, _ids| -> Entity { + let mut button = Button::new(); + button = button.attach(Grid::row(row as usize)); + button = button.attach(Grid::column(col as usize)); + + let code = match properties.get("onclick").unwrap() { + QmlString(code) => code.clone(), + _ => String::new(), + }; + + button = button.on_click(move |states, _| -> bool { + state(id, states).action(code.clone()); + return true; + }); + + let text = match properties.get("text").unwrap() { + QmlString(text) => text.clone(), + _ => String::new(), + }; + + match properties.get("anchors.centerIn") { + Some(QmlIdent(str)) => { + if str.eq("parent") { + button = button.v_align(Alignment::Center); + button = button.h_align(Alignment::Center); + } + } + _ => {} + } + button = button.text(text); + return button.build(ctx); + }); + } +} diff --git a/src/widget_builders/grid.rs b/src/widget_builders/grid.rs new file mode 100644 index 0000000..1ce5de9 --- /dev/null +++ b/src/widget_builders/grid.rs @@ -0,0 +1,59 @@ + +use crate::parser::{Value, QML}; +use crate::widget_builders::{parse_number, QmlWidgetBuilder, WidgetBuilder}; +use orbtk::prelude::HashMap; +use orbtk::prelude::*; +use orbtk::Entity; + + +pub struct GridBuilder {} + +impl WidgetBuilder for GridBuilder { + fn build( + &self, + properties: HashMap, + children: Vec<(String, QML)>, + ) -> Box) -> Entity> { + return Box::new(move |id, ctx, row, col, ids| -> Entity { + let mut grid = Grid::new(); + grid = grid.attach(Grid::row(row as usize)); + grid = grid.attach(Grid::column(col as usize)); + let rows = parse_number(properties.get("rows")) as u32; + let _cols = parse_number(properties.get("cols")) as u32; + + let mut grid_rows = Rows::new(); + for _i in 0..rows { + grid_rows = grid_rows.add("stretch"); + } + grid = grid.rows(grid_rows.build()); + + let mut grid_cols = Columns::new(); + for _i in 0..rows { + grid_cols = grid_cols.add("stretch"); + } + grid = grid.columns(grid_cols.build()); + + let mut grow = 0u32; + let mut gcol = 0u32; + //rect = rect.attach(Grid::column(gcol as usize)); + let qwb = QmlWidgetBuilder::new(); + for (child_type, child_qml) in children.iter() { + grid = grid.child(qwb.build( + id, + grow as usize, + gcol as usize, + child_type.clone(), + child_qml.clone(), + ctx, + ids, + )); + grow += 1; + if grow as u32 == rows { + grow = 0; + gcol += 1; + } + } + return grid.build(ctx); + }); + } +} diff --git a/src/widget_builders/mod.rs b/src/widget_builders/mod.rs new file mode 100644 index 0000000..3588f83 --- /dev/null +++ b/src/widget_builders/mod.rs @@ -0,0 +1,77 @@ +use crate::parser::Value::QmlNumber; +use crate::parser::{Value, QML}; +use crate::widget_builders::button::ButtonBuilder; +use crate::widget_builders::grid::GridBuilder; +use crate::widget_builders::rectangle::RectangleBuilder; +use crate::widget_builders::textedit::TextEditBuilder; +use crate::widget_builders::textfield::TextBuilder; +use orbtk::prelude::*; +use orbtk::Entity; + +use std::collections::HashMap; + +pub mod button; +pub mod grid; +pub mod rectangle; +pub mod textedit; +pub mod textfield; + +fn parse_number(val: Option<&Value>) -> f64 { + match val { + Some(QmlNumber(num)) => num.clone(), + _ => 0.0, + } +} + +pub trait WidgetBuilder { + fn build( + &self, + properties: HashMap, + children: Vec<(String, QML)>, + ) -> Box) -> Entity>; +} + +pub struct QmlWidgetBuilder { + widgets: HashMap>, +} + +impl QmlWidgetBuilder { + pub fn new() -> QmlWidgetBuilder { + let mut qwb = QmlWidgetBuilder { + widgets: Default::default(), + }; + qwb.widgets + .insert(String::from("Rectangle"), Box::new(RectangleBuilder {})); + qwb.widgets + .insert(String::from("Grid"), Box::new(GridBuilder {})); + qwb.widgets + .insert(String::from("Text"), Box::new(TextBuilder {})); + qwb.widgets + .insert(String::from("TextField"), Box::new(TextEditBuilder {})); + qwb.widgets + .insert(String::from("Button"), Box::new(ButtonBuilder {})); + qwb + } + + pub fn build( + &self, + id: Entity, + row: usize, + col: usize, + widget_type: String, + qml: QML, + ctx: &mut BuildContext, + ids: &mut Vec, + ) -> Entity { + match self.widgets.get(&widget_type) { + Some(builder) => { + let wfn = builder.build(qml.properties, qml.children); + let widget = wfn(id, ctx, row, col, ids); + + return widget; + } + _ => {} + } + return ctx.create_entity(); + } +} diff --git a/src/widget_builders/rectangle.rs b/src/widget_builders/rectangle.rs new file mode 100644 index 0000000..ef04e4b --- /dev/null +++ b/src/widget_builders/rectangle.rs @@ -0,0 +1,51 @@ +use crate::parser::Value::QmlString; +use crate::parser::{Value, QML}; +use crate::widget_builders::{parse_number, QmlWidgetBuilder, WidgetBuilder}; +use orbtk::prelude::HashMap; +use orbtk::prelude::*; +use orbtk::Entity; + + +pub struct RectangleBuilder {} + +impl WidgetBuilder for RectangleBuilder { + fn build( + &self, + properties: HashMap, + children: Vec<(String, QML)>, + ) -> Box) -> Entity> { + return Box::new(move |id, ctx, row, col, ids| -> Entity { + let _width = parse_number(properties.get("width")); + let _height = parse_number(properties.get("height")); + + let color = match properties.get("color") { + Some(QmlString(col)) => match col.as_str() { + "red" => Color::rgb(0xff, 00, 00), + "blue" => Color::rgb(0x00, 00, 0xff), + _ => Color::rgb(0xff, 0xff, 0xff), + }, + _ => Color::rgb(0xff, 0xff, 0xff), + }; + let mut rect = Container::new() + // .width(width) + // .height(height) + .background(color); + + rect = rect.attach(Grid::row(row as usize)); + rect = rect.attach(Grid::column(col as usize)); + let qwb = QmlWidgetBuilder::new(); + for (child_type, child_qml) in children.iter() { + rect = rect.child(qwb.build( + id, + 0, + 0, + child_type.clone(), + child_qml.clone(), + ctx, + ids, + )); + } + return rect.build(ctx); + }); + } +} diff --git a/src/widget_builders/textedit.rs b/src/widget_builders/textedit.rs new file mode 100644 index 0000000..945926a --- /dev/null +++ b/src/widget_builders/textedit.rs @@ -0,0 +1,60 @@ +use crate::parser::Value::{QmlIdent, QmlString}; +use crate::parser::{Value, QML}; +use crate::state; +use crate::widget_builders::{WidgetBuilder}; +use orbtk::prelude::HashMap; +use orbtk::prelude::*; +use orbtk::Entity; + + +pub struct TextEditBuilder {} + +impl WidgetBuilder for TextEditBuilder { + fn build( + &self, + properties: HashMap, + _children: Vec<(String, QML)>, + ) -> Box) -> Entity> { + return Box::new(move |id, ctx, row, col, ids| -> Entity { + let text = match properties.get("text") { + Some(QmlString(text)) => text.clone(), + _ => String::new(), + }; + + let mut tt = TextBox::new(); + tt = tt.text(text); + tt = tt.attach(Grid::row(row as usize)); + tt = tt.attach(Grid::column(col as usize)); + tt = tt.enabled(true); + + match properties.get("id") { + Some(QmlIdent(text)) => { + tt = tt.id(text.clone()); + ids.push(text.clone()) + } + _ => {} + }; + + let code = match properties.get("onchange").unwrap() { + QmlString(code) => code.clone(), + _ => String::new(), + }; + + tt = tt.on_changed(move |states, _entity: Entity| { + state(id, states).action(code.clone()); + }); + + match properties.get("anchors.centerIn") { + Some(QmlIdent(str)) => { + if str.eq("parent") { + tt = tt.v_align(Alignment::Center); + tt = tt.h_align(Alignment::Center); + } + } + _ => {} + } + let entity = tt.build(ctx); + return entity; + }); + } +} diff --git a/src/widget_builders/textfield.rs b/src/widget_builders/textfield.rs new file mode 100644 index 0000000..fbcb8d1 --- /dev/null +++ b/src/widget_builders/textfield.rs @@ -0,0 +1,49 @@ +use crate::parser::Value::{QmlIdent, QmlString}; +use crate::parser::{Value, QML}; +use crate::widget_builders::{WidgetBuilder}; +use orbtk::prelude::HashMap; +use orbtk::prelude::*; +use orbtk::Entity; + + +pub struct TextBuilder {} + +impl WidgetBuilder for TextBuilder { + fn build( + &self, + properties: HashMap, + _children: Vec<(String, QML)>, + ) -> Box) -> Entity> { + return Box::new(move |_id, ctx, row, col, ids| -> Entity { + let text = match properties.get("text") { + Some(QmlString(text)) => text.clone(), + _ => String::new(), + }; + + let mut tt = TextBlock::new(); + tt = tt.text(text); + tt = tt.attach(Grid::row(row as usize)); + tt = tt.attach(Grid::column(col as usize)); + + match properties.get("id") { + Some(QmlIdent(text)) => { + tt = tt.id(text.clone()); + ids.push(text.clone()) + } + _ => {} + }; + + match properties.get("anchors.centerIn") { + Some(QmlIdent(str)) => { + if str.eq("parent") { + tt = tt.v_align(Alignment::Center); + tt = tt.h_align(Alignment::Center); + } + } + _ => {} + } + let entity = tt.build(ctx); + return entity; + }); + } +}