184 lines
6.1 KiB
Rust
184 lines
6.1 KiB
Rust
use orbtk::prelude::*;
|
|
|
|
use rhai::RegisterFn;
|
|
use rhai::{Array, Engine};
|
|
use std::sync::mpsc::{Receiver, Sender};
|
|
use std::time::Duration;
|
|
pub mod parser;
|
|
pub mod widget_builders;
|
|
use crate::parser::QML;
|
|
use crate::parser::{parse_qml, Value};
|
|
use crate::widget_builders::{QmlContext, QmlWidgetBuilder};
|
|
use evmap::{ReadHandle, WriteHandle};
|
|
|
|
use rand::Rng;
|
|
use std::borrow::BorrowMut;
|
|
use std::collections::VecDeque;
|
|
use std::ops::Index;
|
|
use std::sync::mpsc;
|
|
|
|
#[macro_use]
|
|
extern crate pest_derive;
|
|
|
|
#[derive(AsAny)]
|
|
pub struct MainViewState {
|
|
pub imports: Vec<String>,
|
|
pub qml: Vec<(String, QML)>,
|
|
pub rx: Option<Receiver<String>>,
|
|
}
|
|
|
|
impl Widget for MainViewState {
|
|
fn new() -> Self {
|
|
unimplemented!()
|
|
}
|
|
|
|
fn build(self, ctx: &mut BuildContext) -> Entity {
|
|
let top_level = self.qml.clone();
|
|
let widget = ctx.create_entity();
|
|
|
|
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 qmlctx = QmlContext {
|
|
indexes: vec![],
|
|
code: Default::default(),
|
|
};
|
|
let this = QmlWidgetBuilder::new().build(widget, 0, 0, top_level[0].0.clone(), top_level[0].1.clone(), ctx, qmlctx.borrow_mut()); //render_ctx(widget, ctx, &top_level, 0, 0, ids.borrow_mut()).unwrap();
|
|
ctx.register_property("dirty", widget, false);
|
|
ctx.register_state(
|
|
this,
|
|
Box::new(MVState {
|
|
tx: Some(tx.clone()),
|
|
rx: Some(rxf),
|
|
engine: Engine::new(),
|
|
codes: VecDeque::new(),
|
|
ids: qmlctx.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: qmlctx.clone(),
|
|
value_map: (Some(r), None),
|
|
}),
|
|
);
|
|
this
|
|
}
|
|
|
|
fn insert_handler(self, _handler: impl Into<Rc<dyn EventHandler>>) -> Self {
|
|
self
|
|
}
|
|
|
|
fn child(self, _child: Entity) -> Self {
|
|
self
|
|
}
|
|
}
|
|
|
|
#[derive(AsAny)]
|
|
pub struct MVState {
|
|
pub engine: Engine,
|
|
pub tx: Option<Sender<(String, String, String)>>,
|
|
pub rx: Option<Receiver<(String, String, String)>>,
|
|
pub codes: VecDeque<String>,
|
|
pub ids: QmlContext,
|
|
pub value_map: (Option<ReadHandle<String, String>>, Option<WriteHandle<String, String>>),
|
|
}
|
|
|
|
impl MVState {
|
|
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 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);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl State for MVState {
|
|
fn init(&mut self, registry: &mut Registry, ctx: &mut Context) {
|
|
self.update(registry, ctx);
|
|
}
|
|
|
|
fn update(&mut self, _registry: &mut Registry, ctx: &mut Context) {
|
|
match self.value_map.1.borrow_mut() {
|
|
Some(w) => {
|
|
self.engine.register_fn("rand_opacity", move || -> (f32) {
|
|
let mut rng = rand::thread_rng();
|
|
rng.gen_range(0.0, 1.0) as f32
|
|
});
|
|
|
|
for id in self.ids.indexes.iter() {
|
|
if ctx.child(id.as_str()).has::<String16>("text") {
|
|
let res = ctx.child(id.as_str()).get::<String16>("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());
|
|
}
|
|
if ctx.child(id.as_str()).has::<i32>("selected_index") {
|
|
let index = ctx.child(id.as_str()).get::<i32>("selected_index").clone();
|
|
match self.ids.code.get(&(id.clone(), String::from("items").clone())) {
|
|
Some(code) => {
|
|
let engine = Engine::new();
|
|
match engine.eval::<Array>(code.as_str()) {
|
|
Ok(list) => {
|
|
w.update(id.clone() + ".selected", list.index(index as usize).to_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)) => {
|
|
ctx.child(x.as_str()).set::<String16>(y.as_str(), String16::from(z));
|
|
}
|
|
_ => {}
|
|
},
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Template for MainViewState {}
|
|
|
|
pub fn state<'a>(id: Entity, states: &'a mut StatesContext) -> &'a mut MVState {
|
|
states.get_mut(id)
|
|
}
|