bindings!
This commit is contained in:
parent
7f06d1f6bc
commit
5ec842f6ee
|
@ -19,6 +19,7 @@ Grid {
|
|||
Rectangle {
|
||||
color: "blue"
|
||||
Text {
|
||||
id: target
|
||||
anchors.centerIn: parent
|
||||
text: "Hello, World!"
|
||||
}
|
||||
|
@ -48,6 +49,7 @@ Grid {
|
|||
text: "Hello, World!"
|
||||
onclick = [[
|
||||
print("Hello World!");
|
||||
update_property("target", "text", "123");
|
||||
]]
|
||||
}
|
||||
}
|
||||
|
|
158
src/main.rs
158
src/main.rs
|
@ -1,5 +1,7 @@
|
|||
use orbtk::prelude::*;
|
||||
use rhai::{packages::*, Engine, EvalAltResult, INT};
|
||||
use rhai::RegisterFn;
|
||||
|
||||
extern crate pest;
|
||||
#[macro_use]
|
||||
extern crate pest_derive;
|
||||
|
@ -7,8 +9,13 @@ extern crate pest_derive;
|
|||
use crate::Value::{QmlIdent, QmlNumber, QmlString};
|
||||
use pest::iterators::{Pair, Pairs};
|
||||
use pest::Parser;
|
||||
use std::borrow::Borrow;
|
||||
use std::borrow::{Borrow, BorrowMut};
|
||||
use std::fs::read_to_string;
|
||||
use std::sync::mpsc::{Sender, Receiver};
|
||||
use std::sync::mpsc;
|
||||
use std::thread;
|
||||
use crate::Action::Code;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[grammar = "../pest/qml.pest"]
|
||||
|
@ -93,8 +100,10 @@ fn parse_qml(qml: Pairs<Rule>) -> QML {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
Application::new()
|
||||
.window(|ctx| {
|
||||
let mut app_context:HashMap<String, Entity> = HashMap::new();
|
||||
let qml = read_to_string("./res/example.qml").unwrap();
|
||||
let qml_tokens = QmlParser::parse(Rule::qml, qml.as_str()).unwrap_or_else(|e| panic!("{}", e));
|
||||
let qml_doc = parse_qml(qml_tokens);
|
||||
|
@ -109,34 +118,119 @@ fn main() {
|
|||
_ => 600.0,
|
||||
};
|
||||
println!("{:?}", qml_doc);
|
||||
Window::create()
|
||||
let (tx, rx): (Sender<(String,String,String)>, Receiver<(String,String,String)>) = mpsc::channel();
|
||||
let w = Window::create()
|
||||
.title("QML")
|
||||
.position((100.0, 100.0))
|
||||
.resizeable(true)
|
||||
.size(width, height)
|
||||
.child(render_ctx(ctx, &top_level, 0, 0, &HashMap::new()).unwrap())
|
||||
.build(ctx)
|
||||
.child(MainViewState{ action: None, qml: top_level.clone(), rx: None, state1: Some(MVState{tx:Some(tx.clone()),rx:None}),state2: Some(MVState{rx:Some(rx),tx:None})}.build(ctx))
|
||||
.build(ctx);
|
||||
w
|
||||
})
|
||||
.run();
|
||||
}
|
||||
|
||||
fn parse_number(val: Option<&Value>, env: &HashMap<String, Value>) -> f64 {
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
enum Action {
|
||||
Code,
|
||||
}
|
||||
|
||||
|
||||
#[derive(AsAny)]
|
||||
pub struct MainViewState {
|
||||
action: Option<Action>,
|
||||
qml: Vec<(String, QML)>,
|
||||
rx: Option<Receiver<String>>,
|
||||
state1: Option<MVState>,
|
||||
state2: Option<MVState>
|
||||
}
|
||||
|
||||
impl Widget for MainViewState {
|
||||
fn create() -> 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()));
|
||||
this
|
||||
}
|
||||
|
||||
fn insert_handler(self, handler: impl Into<Rc<dyn EventHandler>>) -> Self {
|
||||
self
|
||||
}
|
||||
|
||||
fn child(self, child: Entity) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(AsAny)]
|
||||
struct MVState {
|
||||
tx: Option<Sender<(String,String,String)>>,
|
||||
rx: Option<Receiver<(String,String,String)>>
|
||||
}
|
||||
|
||||
impl MVState {
|
||||
fn action(&mut self, action: String) {
|
||||
match self.tx.clone() {
|
||||
Some(tx) => {
|
||||
let mut engine = Engine::new();
|
||||
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 = engine.eval::<()>(action.as_str());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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.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("hijack"));
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Template for MainViewState {
|
||||
|
||||
}
|
||||
|
||||
fn parse_number(val: Option<&Value>) -> f64 {
|
||||
match val {
|
||||
Some(QmlNumber(num)) => num.clone(),
|
||||
Some(QmlIdent(ident)) => match env.get(ident) {
|
||||
Some(QmlNumber(num)) => num.clone(),
|
||||
_ => 0.0,
|
||||
},
|
||||
_ => 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
fn render_ctx(
|
||||
id: Entity,
|
||||
ctx: &mut BuildContext,
|
||||
qml: &Vec<(String, QML)>,
|
||||
row: u32,
|
||||
col: u32,
|
||||
env: &HashMap<String, Value>,
|
||||
col: u32
|
||||
) -> Option<Entity> {
|
||||
for (ident, child) in qml.iter() {
|
||||
match ident.as_str() {
|
||||
|
@ -144,8 +238,8 @@ fn render_ctx(
|
|||
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"), &env) as u32;
|
||||
let cols = parse_number(child.properties.get("cols"), &env) as u32;
|
||||
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 {
|
||||
|
@ -163,7 +257,7 @@ fn render_ctx(
|
|||
let mut gcol = 0u32;
|
||||
//rect = rect.attach(Grid::column(gcol as usize));
|
||||
for (i, s) in child.children.iter() {
|
||||
match render_ctx(ctx, &vec![(i.clone(), s.clone())], grow, gcol, &env) {
|
||||
match render_ctx(id, ctx, &vec![(i.clone(), s.clone())], grow, gcol) {
|
||||
Some(entity) => {
|
||||
grid = grid.child(entity);
|
||||
grow += 1;
|
||||
|
@ -179,8 +273,8 @@ fn render_ctx(
|
|||
return Some(grid.build(ctx));
|
||||
}
|
||||
"Rectangle" => {
|
||||
let width = parse_number(child.properties.get("width"), &env);
|
||||
let height = parse_number(child.properties.get("height"), &env);
|
||||
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() {
|
||||
|
@ -198,12 +292,9 @@ fn render_ctx(
|
|||
rect = rect.attach(Grid::row(row as usize));
|
||||
rect = rect.attach(Grid::column(col as usize));
|
||||
|
||||
let mut env = env.clone();
|
||||
env.insert(String::from("parent.width"), QmlNumber(width));
|
||||
env.insert(String::from("parent.height"), QmlNumber(height));
|
||||
|
||||
for (i, s) in child.children.iter() {
|
||||
match render_ctx(ctx, &vec![(i.clone(), s.clone())], 0, 0, &env) {
|
||||
match render_ctx(id, ctx, &vec![(i.clone(), s.clone())], 0, 0) {
|
||||
Some(entity) => {
|
||||
rect = rect.child(entity);
|
||||
}
|
||||
|
@ -222,8 +313,9 @@ fn render_ctx(
|
|||
QmlString(code) => code.clone(),
|
||||
_ => String::new(),
|
||||
};
|
||||
button = button.on_click(move |x, y| -> bool {
|
||||
rhai_script(code.clone());
|
||||
|
||||
button = button.on_click(move |states, _| -> bool {
|
||||
state(id, states).action(code.clone());
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -246,16 +338,24 @@ fn render_ctx(
|
|||
return Some(button.build(ctx));
|
||||
}
|
||||
"Text" => {
|
||||
let text = match child.properties.get("text").unwrap() {
|
||||
QmlString(text) => text.clone(),
|
||||
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") {
|
||||
|
@ -265,8 +365,8 @@ fn render_ctx(
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
return Some(tt.build(ctx));
|
||||
let entity = tt.build(ctx);
|
||||
return Some(entity);
|
||||
}
|
||||
_ => println!("unknown ident {}", ident),
|
||||
}
|
||||
|
@ -274,7 +374,7 @@ fn render_ctx(
|
|||
None
|
||||
}
|
||||
|
||||
fn rhai_script(run: String) {
|
||||
let mut engine = Engine::new();
|
||||
engine.eval::<()>(run.as_str());
|
||||
|
||||
fn state<'a>(id: Entity, states: &'a mut StatesContext) -> &'a mut MVState {
|
||||
states.get_mut(id)
|
||||
}
|
Loading…
Reference in New Issue