11use crate :: tags:: { Tag , TagAttributes } ;
22use crate :: utils:: attr:: * ;
3+ use crate :: utils:: expr:: expr_opt;
34use crate :: utils:: panel:: * ;
45use crate :: utils:: render:: render_children_stmt;
56use efx_attrnames:: AttrNames ;
67use efx_core:: Element ;
78use proc_macro2:: TokenStream ;
89use quote:: { ToTokens , quote} ;
9- use crate :: utils :: expr :: expr_opt ;
10+ use syn :: Expr ;
1011
1112pub struct Window {
1213 attributes : Attributes ,
@@ -123,24 +124,38 @@ impl Tag for Window {
123124
124125 // anchor (Align2 + offset)
125126 if self . attributes . anchor_h . is_some ( ) || self . attributes . anchor_v . is_some ( ) {
126- let h = self . attributes . anchor_h . clone ( ) . unwrap_or_else ( || "center" . to_string ( ) ) ;
127- let v = self . attributes . anchor_v . clone ( ) . unwrap_or_else ( || "center" . to_string ( ) ) ;
127+ let h = self
128+ . attributes
129+ . anchor_h
130+ . clone ( )
131+ . unwrap_or_else ( || "center" . to_string ( ) ) ;
132+ let v = self
133+ . attributes
134+ . anchor_v
135+ . clone ( )
136+ . unwrap_or_else ( || "center" . to_string ( ) ) ;
128137
129138 let h_align = match h. as_str ( ) {
130- "left" => quote ! ( egui:: Align :: Min ) ,
131- "center" => quote ! ( egui:: Align :: Center ) ,
132- "right" => quote ! ( egui:: Align :: Max ) ,
139+ "left" => quote ! ( egui:: Align :: Min ) ,
140+ "center" => quote ! ( egui:: Align :: Center ) ,
141+ "right" => quote ! ( egui:: Align :: Max ) ,
133142 other => {
134- let msg = format ! ( "efx: <Window> `anchor-h` expected left|center|right, got `{}`" , other) ;
143+ let msg = format ! (
144+ "efx: <Window> `anchor-h` expected left|center|right, got `{}`" ,
145+ other
146+ ) ;
135147 return quote ! { compile_error!( #msg) ; } ;
136148 }
137149 } ;
138150 let v_align = match v. as_str ( ) {
139- "top" => quote ! ( egui:: Align :: Min ) ,
140- "center" => quote ! ( egui:: Align :: Center ) ,
141- "bottom" => quote ! ( egui:: Align :: Max ) ,
151+ "top" => quote ! ( egui:: Align :: Min ) ,
152+ "center" => quote ! ( egui:: Align :: Center ) ,
153+ "bottom" => quote ! ( egui:: Align :: Max ) ,
142154 other => {
143- let msg = format ! ( "efx: <Window> `anchor-v` expected top|center|bottom, got `{}`" , other) ;
155+ let msg = format ! (
156+ "efx: <Window> `anchor-v` expected top|center|bottom, got `{}`" ,
157+ other
158+ ) ;
144159 return quote ! { compile_error!( #msg) ; } ;
145160 }
146161 } ;
@@ -149,11 +164,16 @@ impl Tag for Window {
149164 let ay = self . attributes . anchor_y . unwrap_or ( 0.0 ) ;
150165
151166 win. extend ( quote ! (
152- __efx_window = __efx_window. anchor( egui:: Align2 ( #h_align, #v_align) , egui:: vec2( #ax as f32 , #ay as f32 ) ) ;
167+ __efx_window = __efx_window. anchor( egui:: Align2 ( [ #h_align, #v_align] ) , egui:: vec2( #ax as f32 , #ay as f32 ) ) ;
153168 ) ) ;
154169 }
155170
156171 let open_bind = if let Some ( expr) = & self . attributes . open_expr {
172+ if !is_assignable_expr ( expr) {
173+ return quote ! {
174+ compile_error!( "efx: <Window> `open` must be an assignable boolean lvalue (e.g. {self.show_window})" ) ;
175+ } ;
176+ }
157177 quote ! {
158178 let mut __efx_open = ( #expr) ;
159179 __efx_window = __efx_window. open( & mut __efx_open) ;
@@ -167,7 +187,15 @@ impl Tag for Window {
167187 #frame_ts
168188 #win
169189 #open_bind
170- __efx_window. show( & #ui. ctx( ) , |ui| { #children } ) ;
190+ let __efx_ctx = #ui. ctx( ) . clone( ) ;
191+ // Explicitly limit the lifetime of the result of show(...)
192+ {
193+ let __efx_tmp = __efx_window. show( & __efx_ctx, |ui| { #children } ) ;
194+ let _ = __efx_tmp;
195+ }
196+
197+ // Nothing comes back out
198+ ( )
171199 } }
172200 }
173201}
@@ -191,7 +219,7 @@ struct Attributes {
191219
192220 // opening state binding (expression)
193221 #[ attr( name = "open" ) ]
194- open_expr : Option < TokenStream > ,
222+ open_expr : Option < Expr > ,
195223
196224 // geometry: positions
197225 #[ attr( name = "default-x" ) ]
0 commit comments