@@ -1001,6 +1001,9 @@ fn generate_sub_component(
1001
1001
sub_component_types. push ( sub_component_id) ;
1002
1002
}
1003
1003
1004
+ let popup_id_names =
1005
+ component. popup_windows . iter ( ) . enumerate ( ) . map ( |( i, _) | internal_popup_id ( i) ) ;
1006
+
1004
1007
for ( prop1, prop2) in & component. two_way_bindings {
1005
1008
let p1 = access_member ( prop1, & ctx) ;
1006
1009
let p2 = access_member ( prop2, & ctx) ;
@@ -1116,6 +1119,7 @@ fn generate_sub_component(
1116
1119
struct #inner_component_id {
1117
1120
#( #item_names : sp:: #item_types, ) *
1118
1121
#( #sub_component_names : #sub_component_types, ) *
1122
+ #( #popup_id_names : :: core:: cell:: Cell <sp:: Option <:: core:: num:: NonZeroU32 >>, ) *
1119
1123
#( #declared_property_vars : sp:: Property <#declared_property_types>, ) *
1120
1124
#( #declared_callbacks : sp:: Callback <( #( #declared_callbacks_types, ) * ) , #declared_callbacks_ret>, ) *
1121
1125
#( #repeated_element_names : sp:: Repeater <#repeated_element_components>, ) *
@@ -1819,6 +1823,12 @@ fn inner_component_id(component: &llr::SubComponent) -> proc_macro2::Ident {
1819
1823
format_ident ! ( "Inner{}" , ident( & component. name) )
1820
1824
}
1821
1825
1826
+ fn internal_popup_id ( index : usize ) -> proc_macro2:: Ident {
1827
+ let mut name = index. to_string ( ) ;
1828
+ name. insert_str ( 0 , "popup_id_" ) ;
1829
+ ident ( & name)
1830
+ }
1831
+
1822
1832
fn global_inner_name ( g : & llr:: GlobalComponent ) -> TokenStream {
1823
1833
if g. is_builtin {
1824
1834
let i = ident ( & g. name ) ;
@@ -2660,27 +2670,51 @@ fn compile_builtin_function_call(
2660
2670
2661
2671
let close_policy = compile_expression ( close_policy, ctx) ;
2662
2672
let window_adapter_tokens = access_window_adapter_field ( ctx) ;
2673
+ let popup_id_name = internal_popup_id ( * popup_index as usize ) ;
2663
2674
quote ! ( {
2664
2675
let popup_instance = #popup_window_id:: new( #component_access_tokens. self_weak. get( ) . unwrap( ) . clone( ) ) . unwrap( ) ;
2665
2676
let popup_instance_vrc = sp:: VRc :: map( popup_instance. clone( ) , |x| x) ;
2666
2677
#popup_window_id:: user_init( popup_instance_vrc. clone( ) ) ;
2667
2678
let position = { let _self = popup_instance_vrc. as_pin_ref( ) ; #position } ;
2668
- sp:: WindowInner :: from_pub( #window_adapter_tokens. window( ) ) . show_popup(
2669
- & sp:: VRc :: into_dyn( popup_instance. into( ) ) ,
2670
- position,
2671
- #close_policy,
2672
- #parent_component
2673
- )
2679
+ if let Some ( current_id) = #component_access_tokens. #popup_id_name. take( ) {
2680
+ sp:: WindowInner :: from_pub( #window_adapter_tokens. window( ) ) . close_popup( current_id) ;
2681
+ }
2682
+ #component_access_tokens. #popup_id_name. set( Some (
2683
+ sp:: WindowInner :: from_pub( #window_adapter_tokens. window( ) ) . show_popup(
2684
+ & sp:: VRc :: into_dyn( popup_instance. into( ) ) ,
2685
+ position,
2686
+ #close_policy,
2687
+ #parent_component
2688
+ ) )
2689
+ ) ;
2674
2690
} )
2675
2691
} else {
2676
2692
panic ! ( "internal error: invalid args to ShowPopupWindow {:?}" , arguments)
2677
2693
}
2678
2694
}
2679
2695
BuiltinFunction :: ClosePopupWindow => {
2680
- let window_adapter_tokens = access_window_adapter_field ( ctx) ;
2681
- quote ! (
2682
- sp:: WindowInner :: from_pub( #window_adapter_tokens. window( ) ) . close_popup( )
2683
- )
2696
+ if let [ Expression :: NumberLiteral ( popup_index) , Expression :: PropertyReference ( parent_ref) ] =
2697
+ arguments
2698
+ {
2699
+ let mut parent_ctx = ctx;
2700
+ let mut component_access_tokens = quote ! ( _self) ;
2701
+ if let llr:: PropertyReference :: InParent { level, .. } = parent_ref {
2702
+ for _ in 0 ..level. get ( ) {
2703
+ component_access_tokens =
2704
+ quote ! ( #component_access_tokens. parent. upgrade( ) . unwrap( ) . as_pin_ref( ) ) ;
2705
+ parent_ctx = parent_ctx. parent . as_ref ( ) . unwrap ( ) . ctx ;
2706
+ }
2707
+ }
2708
+ let window_adapter_tokens = access_window_adapter_field ( ctx) ;
2709
+ let popup_id_name = internal_popup_id ( * popup_index as usize ) ;
2710
+ quote ! (
2711
+ if let Some ( current_id) = #component_access_tokens. #popup_id_name. take( ) {
2712
+ sp:: WindowInner :: from_pub( #window_adapter_tokens. window( ) ) . close_popup( current_id) ;
2713
+ }
2714
+ )
2715
+ } else {
2716
+ panic ! ( "internal error: invalid args to ClosePopupWindow {:?}" , arguments)
2717
+ }
2684
2718
}
2685
2719
BuiltinFunction :: SetSelectionOffsets => {
2686
2720
if let [ llr:: Expression :: PropertyReference ( pr) , from, to] = arguments {
0 commit comments