Skip to content

Commit 3faee1d

Browse files
committed
Fixing bugs
1 parent 3729e2c commit 3faee1d

8 files changed

Lines changed: 124 additions & 33 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
[workspace]
22
members = ["efx", "efx-core", "efx-attrnames", "efx-sandbox"]
33
resolver = "2"
4+
5+
[workspace.package]
46
rust-version = "1.85"

efx-sandbox/src/main.rs

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,54 @@ fn main() -> eframe::Result<()> {
1010
)
1111
}
1212

13-
#[derive(Default)]
1413
struct App {
1514
counter: i32,
1615
input: String,
16+
show_settings: bool,
17+
}
18+
19+
impl Default for App {
20+
fn default() -> Self {
21+
Self {
22+
counter: 0,
23+
input: String::new(),
24+
show_settings: true,
25+
}
26+
}
1727
}
1828

1929
impl eframe::App for App {
2030
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
2131
egui::CentralPanel::default().show(ctx, |ui| {
22-
// Header
23-
let _ = efx!(
24-
ui,
25-
r#"
26-
<Column gap="8">
27-
<Label size="20" bold="true">EFx sandbox</Label>
28-
<Separator/>
29-
</Column>
30-
"#
31-
);
32+
ui.scope(|ui| {
33+
// Window + Column
34+
efx!(
35+
ui,
36+
r##"
37+
<Window
38+
id="settings"
39+
title="Settings"
40+
open="self.show_settings"
41+
movable="true"
42+
resizable="true"
43+
default-width="360"
44+
default-height="240"
45+
anchor-h="right"
46+
anchor-v="top"
47+
anchor-x="-12"
48+
anchor-y="12"
49+
fill="#14161B"
50+
stroke-width="1"
51+
stroke-color="#262A33"
52+
>
53+
<Column gap="8">
54+
<Label size="20" bold="true">EFx sandbox</Label>
55+
<Separator/>
56+
</Column>
57+
</Window>
58+
"##
59+
);
60+
});
3261

3362
// Increment/decrement buttons - catch Response
3463
ui.horizontal(|ui| {

efx/src/tags/bottom_panel.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ impl Tag for BottomPanel {
4646
quote! {{
4747
#frame_ts
4848
#panel_ts
49-
__efx_panel.show(&#ui.ctx(), |ui| { #children });
49+
let __efx_ctx = #ui.ctx().clone();
50+
{
51+
let __efx_tmp = __efx_panel.show(&__efx_ctx, |ui| { #children });
52+
let _ = __efx_tmp;
53+
}
54+
()
5055
}}
5156
}
5257
}

efx/src/tags/central_panel.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,14 @@ impl Tag for CentralPanel {
2828

2929
quote! {{
3030
#frame_ts
31-
egui::CentralPanel::default()
32-
.frame(__efx_frame)
33-
.show(&#ui.ctx(), |ui| { #children });
31+
let __efx_ctx = #ui.ctx().clone();
32+
{
33+
let __efx_tmp = egui::CentralPanel::default()
34+
.frame(__efx_frame)
35+
.show(&__efx_ctx, |ui| { #children });
36+
let _ = __efx_tmp;
37+
}
38+
()
3439
}}
3540
}
3641
}

efx/src/tags/side_panel.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,12 @@ impl Tag for SidePanel {
8484
quote! {{
8585
#frame_ts
8686
#panel_ts
87-
__efx_panel.show(&#ui.ctx(), |ui| { #children });
87+
let __efx_ctx = #ui.ctx().clone();
88+
{
89+
let __efx_tmp = __efx_panel.show(&__efx_ctx, |ui| { #children });
90+
let _ = __efx_tmp;
91+
}
92+
()
8893
}}
8994
}
9095
}

efx/src/tags/top_panel.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ impl Tag for TopPanel {
4646
quote! {{
4747
#frame_ts
4848
#panel_ts
49-
__efx_panel.show(&#ui.ctx(), |ui| { #children });
49+
let __efx_ctx = #ui.ctx().clone();
50+
{
51+
let __efx_tmp = __efx_panel.show(&__efx_ctx, |ui| { #children });
52+
let _ = __efx_tmp;
53+
}
54+
()
5055
}}
5156
}
5257
}

efx/src/tags/window.rs

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use crate::tags::{Tag, TagAttributes};
22
use crate::utils::attr::*;
3+
use crate::utils::expr::expr_opt;
34
use crate::utils::panel::*;
45
use crate::utils::render::render_children_stmt;
56
use efx_attrnames::AttrNames;
67
use efx_core::Element;
78
use proc_macro2::TokenStream;
89
use quote::{ToTokens, quote};
9-
use crate::utils::expr::expr_opt;
10+
use syn::Expr;
1011

1112
pub 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")]

efx/src/utils/attr.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
use crate::attr_adapters as A;
12
use efx_core::Element;
23
use proc_macro2::TokenStream;
34
use quote::quote;
45
use std::collections::BTreeMap;
5-
6-
use crate::attr_adapters as A;
6+
use syn::Expr;
77

88
#[inline]
99
pub fn attr_map<'a>(
@@ -115,3 +115,15 @@ pub fn stroke_tokens(width: Option<f32>, color: Option<TokenStream>) -> Option<T
115115

116116
Some(quote!( egui::Stroke { width: #w as _, color: #c } ))
117117
}
118+
119+
pub fn is_assignable_expr(e: &Expr) -> bool {
120+
use syn::{
121+
Expr::{Field, Index, Paren, Path},
122+
ExprParen,
123+
};
124+
match e {
125+
Path(_) | Field(_) | Index(_) => true,
126+
Paren(ExprParen { expr, .. }) => is_assignable_expr(expr),
127+
_ => false,
128+
}
129+
}

0 commit comments

Comments
 (0)