Finished widget_new

This commit is contained in:
Samuel Guerra 2020-02-25 00:32:17 -03:00
parent 7a966d6f05
commit b9cfa887df
3 changed files with 86 additions and 21 deletions

View File

@ -3,3 +3,6 @@ scancode
winit
formatx
vn
req
fnv
Fnv

View File

@ -9,12 +9,12 @@ use zero_ui::prelude::*;
fn main() {
App::default().run(|ctx| {
//ctx.services.req::<Windows>().open(|ctx| {
// window! {
// title: "Button Example";
// => example()
// }
//});
ctx.services.req::<Windows>().open(|_| {
window! {
title: "Button Example";
=> example()
}
});
})
}
@ -24,6 +24,7 @@ fn example() -> impl UiNode {
on_click: enclose!{ (t) move |a| {
a.ctx().updates.push_set(&t, "Clicked!".to_text()).ok();
}};
//content_align: Alignment::TOP_LEFT;
align: Alignment::CENTER;
font_size: 28;
text_color: rgb(0, 100, 200);

View File

@ -34,8 +34,10 @@ pub fn expand_widget_new(input: proc_macro::TokenStream) -> proc_macro::TokenStr
// declarations of property arguments in the user written order.
let mut let_args = Vec::with_capacity(input.input.sets.len());
let mut let_default_args = vec![];
// metadata about [let_args].
let mut setted_props = Vec::with_capacity(let_args.capacity());
let mut setted_default_props = vec![];
// collects property assigns from the user.
for set in input.input.sets {
@ -82,39 +84,98 @@ pub fn expand_widget_new(input: proc_macro::TokenStream) -> proc_macro::TokenStr
BuiltPropertyKind::Required => {
abort_call_site!("missing required property `{}`", prop);
}
BuiltPropertyKind::Default => let_args.push(quote! {
let #name = #widget_name::df::#prop();
}),
BuiltPropertyKind::Default => {
let_default_args.push(quote! {
let #name = #widget_name::df::#prop();
});
setted_default_props.push((prop, target, true));
}
BuiltPropertyKind::Local => {}
}
}
// generate property set calls.
#[derive(Default)]
struct SetProps {
context: Vec<TokenStream>,
event: Vec<TokenStream>,
outer: Vec<TokenStream>,
inner: Vec<TokenStream>,
}
let mut set_child = SetProps::default();
let mut set_self = SetProps::default();
for (prop, target, in_widget) in setted_default_props.into_iter().chain(setted_props) {
let set;
let expected_new_args;
match target {
DefaultBlockTarget::Child => {
set = &mut set_child;
expected_new_args = &input.new_child;
}
DefaultBlockTarget::Self_ => {
set = &mut set_self;
expected_new_args = &input.new;
}
}
if !expected_new_args.iter().any(|a| a == &prop) {
let name = ident! {"{}_args", prop};
let props = if in_widget { quote!(#widget_name::ps::) } else { quote!() };
set.context
.push(quote!(let (node, #name) = #props #prop::set_context(node, #name);));
set.event.push(quote!(let (node, #name) = #props #prop::set_event(node, #name);));
set.outer.push(quote!(let (node, #name) = #props #prop::set_outer(node, #name);));
set.inner.push(quote!(let (node, #name) = #props #prop::set_inner(node, #name);));
}
}
let SetProps {
context: set_child_props_ctx,
event: set_child_props_event,
outer: set_child_props_outer,
inner: set_child_props_inner,
} = set_child;
let new_child_args = input.new_child.into_iter().map(|n| ident!("{}_args", n));
let SetProps {
context: set_self_props_ctx,
event: set_self_props_event,
outer: set_self_props_outer,
inner: set_self_props_inner,
} = set_self;
let new_args = input.new.into_iter().map(|n| ident!("{}_args", n));
// widget child expression `=> {this}`
let child = input.input.child_expr;
// declarations of self property arguments.
let r = quote! {{
#(#let_default_args)*
#(#let_args)*
let __node = #child;
let node = #child;
// apply child properties
//#(#set_child_props_ctx)*
//#(#set_child_props_event)*
//#(#set_child_props_outer)*
//#(#set_child_props_inner)*
#(#set_child_props_ctx)*
#(#set_child_props_event)*
#(#set_child_props_outer)*
#(#set_child_props_inner)*
//let __node = #ident::new_child(__node, #(#new_child_args),*);
let node = #widget_name::new_child(node, #(#new_child_args),*);
// apply self properties
//#(#set_self_props_ctx)*
//#(#set_self_props_event)*
//#(#set_self_props_outer)*
//#(#set_self_props_inner)*
#(#set_self_props_ctx)*
#(#set_self_props_event)*
#(#set_self_props_outer)*
#(#set_self_props_inner)*
//#ident::new(__node, #(#new_args),*)
__node
#widget_name::new(node, #(#new_args),*)
}};
r.into()