mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 14:21:16 +00:00
Emit signal handler bindings and expressions for emitting signals in the Rust frontend
This commit is contained in:
parent
a3892ea102
commit
97dc677854
1 changed files with 40 additions and 23 deletions
|
@ -196,24 +196,28 @@ pub fn sixtyfps(stream: TokenStream) -> TokenStream {
|
|||
quote!(#field_name.)
|
||||
};
|
||||
let rust_property = quote!(#rust_property_accessor_prefix#rust_property_ident);
|
||||
let tokens_for_expression = compile_expression(binding_expression);
|
||||
|
||||
let v = compile_expression(binding_expression);
|
||||
if v.is_none() {
|
||||
// FIXME: this is because signals are not yet implemented
|
||||
continue;
|
||||
}
|
||||
|
||||
if binding_expression.is_constant() {
|
||||
if matches!(item.lookup_property(k.as_str()), Type::Signal) {
|
||||
init.push(quote!(
|
||||
self_.#rust_property.set(#v);
|
||||
));
|
||||
} else {
|
||||
init.push(quote!(
|
||||
self_.#rust_property.set_binding(|context| {
|
||||
self_.#rust_property.set_handler(|context, ()| {
|
||||
let _self = context.component.downcast::<#component_id>().unwrap();
|
||||
#v
|
||||
#tokens_for_expression;
|
||||
});
|
||||
));
|
||||
} else {
|
||||
if binding_expression.is_constant() {
|
||||
init.push(quote!(
|
||||
self_.#rust_property.set(#tokens_for_expression);
|
||||
));
|
||||
} else {
|
||||
init.push(quote!(
|
||||
self_.#rust_property.set_binding(|context| {
|
||||
let _self = context.component.downcast::<#component_id>().unwrap();
|
||||
#tokens_for_expression
|
||||
});
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
item_names.push(field_name);
|
||||
|
@ -269,12 +273,12 @@ pub fn sixtyfps(stream: TokenStream) -> TokenStream {
|
|||
result.into()
|
||||
}
|
||||
|
||||
fn compile_expression(e: &Expression) -> Option<proc_macro2::TokenStream> {
|
||||
Some(match e {
|
||||
fn compile_expression(e: &Expression) -> proc_macro2::TokenStream {
|
||||
match e {
|
||||
Expression::StringLiteral(s) => quote!(sixtyfps::re_exports::SharedString::from(#s)),
|
||||
Expression::NumberLiteral(n) => quote!(#n as _),
|
||||
Expression::Cast { from, to } => {
|
||||
let f = compile_expression(&*from)?;
|
||||
let f = compile_expression(&*from);
|
||||
match (from.ty(), to) {
|
||||
(Type::Float32, Type::String) | (Type::Int32, Type::String) => {
|
||||
quote!(sixtyfps::re_exports::SharedString::from(format("{}", #f).to_str()))
|
||||
|
@ -293,19 +297,32 @@ fn compile_expression(e: &Expression) -> Option<proc_macro2::TokenStream> {
|
|||
}
|
||||
}
|
||||
Expression::CodeBlock(sub) => {
|
||||
if sub.iter().map(|e| compile_expression(e)).any(|e| e.is_none()) {
|
||||
// fixme: Remove!
|
||||
return None;
|
||||
}
|
||||
let map = sub.iter().map(|e| compile_expression(e));
|
||||
quote!({ #(#map);* })
|
||||
}
|
||||
// FIXME: signals!
|
||||
Expression::SignalReference { .. } => return None,
|
||||
Expression::FunctionCall { .. } => return None,
|
||||
Expression::SignalReference { element, name, .. } => {
|
||||
let name_ident = quote::format_ident!("{}", name);
|
||||
let e = element.upgrade().unwrap();
|
||||
if !e.borrow().property_declarations.contains_key(name) {
|
||||
let elem_ident = quote::format_ident!("{}", e.borrow().id);
|
||||
quote!(_self.#elem_ident.#name_ident)
|
||||
} else {
|
||||
quote!(_self.#name_ident)
|
||||
}
|
||||
}
|
||||
Expression::FunctionCall { function } => {
|
||||
if matches!(function.ty(), Type::Signal) {
|
||||
let base = compile_expression(function);
|
||||
quote!(#base.emit(&context, ()))
|
||||
} else {
|
||||
let error = format!("the function {:?} is not a signal", e);
|
||||
quote!(compile_error! {#error})
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let error = format!("unsupported expression {:?}", e);
|
||||
quote!(compile_error! {#error})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue