diff --git a/crates/bevy_feathers/src/controls/color_slider.rs b/crates/bevy_feathers/src/controls/color_slider.rs index f422986c4a808..efdebf5746294 100644 --- a/crates/bevy_feathers/src/controls/color_slider.rs +++ b/crates/bevy_feathers/src/controls/color_slider.rs @@ -251,7 +251,7 @@ impl FeathersColorSlider { Node { flex_grow: 1.0, } - BackgroundGradient({vec![Gradient::Linear(LinearGradient { + BackgroundGradient(vec![Gradient::Linear(LinearGradient { angle: PI * 0.5, stops: vec![ ColorStop::new(Color::NONE, percent(0)), @@ -259,7 +259,7 @@ impl FeathersColorSlider { ColorStop::new(Color::NONE, percent(100)), ], color_space: InterpolationColorSpace::Srgba, - })]}) + })]) ZIndex(1) Children [( Node { diff --git a/crates/bevy_feathers/src/controls/menu.rs b/crates/bevy_feathers/src/controls/menu.rs index 4dd95c4fce095..5ce931ea52bed 100644 --- a/crates/bevy_feathers/src/controls/menu.rs +++ b/crates/bevy_feathers/src/controls/menu.rs @@ -223,7 +223,7 @@ impl FeathersMenuPopup { ) GlobalZIndex(100) Popover { - positions: {vec![ + positions: vec![ PopoverPlacement { side: PopoverSide::Bottom, align: PopoverAlign::Start, @@ -234,7 +234,7 @@ impl FeathersMenuPopup { align: PopoverAlign::Start, gap: 2.0, }, - ]}, + ], window_margin: 10.0, } OverrideClip diff --git a/crates/bevy_feathers/src/controls/slider.rs b/crates/bevy_feathers/src/controls/slider.rs index 815c1cc80057c..1600214320073 100644 --- a/crates/bevy_feathers/src/controls/slider.rs +++ b/crates/bevy_feathers/src/controls/slider.rs @@ -96,7 +96,7 @@ impl FeathersSlider { TabIndex(0) FocusIndicator // Use a gradient to draw the moving bar - BackgroundGradient({vec![Gradient::Linear(LinearGradient { + BackgroundGradient(vec![Gradient::Linear(LinearGradient { angle: PI * 0.5, stops: vec![ ColorStop::new(Color::NONE, percent(0)), @@ -105,7 +105,7 @@ impl FeathersSlider { ColorStop::new(Color::NONE, percent(100)), ], color_space: InterpolationColorSpace::Srgba, - })]}) + })]) Children [( // Text container Node { diff --git a/crates/bevy_scene/macros/src/bsn/parse.rs b/crates/bevy_scene/macros/src/bsn/parse.rs index 92d5d98c04d9d..58e7477414e72 100644 --- a/crates/bevy_scene/macros/src/bsn/parse.rs +++ b/crates/bevy_scene/macros/src/bsn/parse.rs @@ -449,6 +449,13 @@ fn parenthesized_tokens(input: &ParseBuffer) -> Result { content.parse::() } +// Used to parse bracketed tokens "loosely" without caring about the content in `[...]`. This ensures autocomplete works. +fn bracketed_tokens(input: &ParseBuffer) -> Result { + let content; + bracketed!(content in input); + content.parse::() +} + fn tokens_between(begin: Cursor, end: Cursor) -> TokenStream { assert!(begin <= end); let mut cursor = begin; @@ -487,8 +494,19 @@ impl Parse for BsnValue { match PathType::new(&path) { PathType::TypeFunction | PathType::Function => { input.parse::()?; - let token_stream = parenthesized_tokens(input)?; - BsnValue::Expr(quote! { #path(#token_stream) }) + let maybe_macro = input.parse::().ok(); + if input.peek(Paren) { + let token_stream = parenthesized_tokens(input)?; + BsnValue::Expr(quote! { #path #maybe_macro (#token_stream) }) + } else if input.peek(Bracket) { + let token_stream = bracketed_tokens(input)?; + BsnValue::Expr(quote! { #path #maybe_macro [#token_stream] }) + } else if input.peek(Brace) { + let token_stream = braced_tokens(input)?; + BsnValue::Expr(quote! { #path #maybe_macro { #token_stream } }) + } else { + return Err(input.error("Unexpected input after function name")); + } } PathType::Const | PathType::TypeConst => { input.parse::()?; diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index cb46595b41459..4c0b081ef214b 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -2183,4 +2183,23 @@ mod tests { let indirect_ent = world.spawn_scene(indirect).unwrap(); assert!(indirect_ent.get::().unwrap().callback == id2); } + + #[test] + fn direct_macro_values_in_bsn() { + let mut app = test_app(); + let world = app.world_mut(); + + #[derive(Component, Default, Clone)] + struct Foo { + value: Vec, + } + let entity = world + .spawn_scene(bsn! { + Foo { + value: vec! [ 10usize ], + } + }) + .unwrap(); + assert_eq!(entity.get::().unwrap().value, vec![10usize]); + } } diff --git a/examples/large_scenes/bevy_city/src/settings.rs b/examples/large_scenes/bevy_city/src/settings.rs index ac7cb38f22f01..190fc3bfd379a 100644 --- a/examples/large_scenes/bevy_city/src/settings.rs +++ b/examples/large_scenes/bevy_city/src/settings.rs @@ -64,7 +64,7 @@ pub fn settings_ui() -> impl Scene { Text("Settings"), ( @FeathersCheckbox { - @caption: {bsn! { Text("Simulate Cars") ThemedText }} + @caption: bsn! { Text("Simulate Cars") ThemedText } } Checked on(checkbox_self_update) @@ -74,7 +74,7 @@ pub fn settings_ui() -> impl Scene { ), ( @FeathersCheckbox { - @caption: {bsn! { Text("Shadow maps enabled") ThemedText }} + @caption: bsn! { Text("Shadow maps enabled") ThemedText } } Checked on(checkbox_self_update) @@ -92,7 +92,7 @@ pub fn settings_ui() -> impl Scene { ), ( @FeathersCheckbox { - @caption: {bsn! { Text("Contact shadows enabled") ThemedText }} + @caption: bsn! { Text("Contact shadows enabled") ThemedText } } Checked on(checkbox_self_update) @@ -110,7 +110,7 @@ pub fn settings_ui() -> impl Scene { ), ( @FeathersCheckbox { - @caption: {bsn! { Text("Wireframe Enabled") ThemedText }} + @caption: bsn! { Text("Wireframe Enabled") ThemedText } } on(checkbox_self_update) on( @@ -124,7 +124,7 @@ pub fn settings_ui() -> impl Scene { ), ( @FeathersCheckbox { - @caption: {bsn! { Text("CPU culling") ThemedText }} + @caption: bsn! { Text("CPU culling") ThemedText } } Checked on(checkbox_self_update) @@ -147,7 +147,7 @@ pub fn settings_ui() -> impl Scene { ), ( @FeathersButton { - @caption: {bsn! { Text("Regenerate City") ThemedText }} + @caption: bsn! { Text("Regenerate City") ThemedText } } on( |_activate: On, diff --git a/examples/ui/widgets/feathers_gallery.rs b/examples/ui/widgets/feathers_gallery.rs index 63d9786de5cac..54b8d5a692e38 100644 --- a/examples/ui/widgets/feathers_gallery.rs +++ b/examples/ui/widgets/feathers_gallery.rs @@ -123,7 +123,7 @@ fn demo_column_1() -> impl Scene { Children [ ( @FeathersButton { - @caption: {bsn! { Text("Normal") ThemedText }} + @caption: bsn! { Text("Normal") ThemedText } } Node { flex_grow: 1.0, @@ -136,7 +136,7 @@ fn demo_column_1() -> impl Scene { ), ( @FeathersButton { - @caption: {bsn! { Text("Disabled") ThemedText }}, + @caption: bsn! { Text("Disabled") ThemedText }, } Node { flex_grow: 1.0, @@ -150,7 +150,7 @@ fn demo_column_1() -> impl Scene { ), ( @FeathersButton { - @caption: {bsn! { Text("Primary") ThemedText }}, + @caption: bsn! { Text("Primary") ThemedText }, @variant: ButtonVariant::Primary, } AccessibleLabel("Primary") @@ -166,7 +166,7 @@ fn demo_column_1() -> impl Scene { Children [ ( @FeathersMenuButton { - @caption: {bsn! { Text("Menu") ThemedText }} + @caption: bsn! { Text("Menu") ThemedText } } AccessibleLabel("Menu Example") Node { @@ -178,7 +178,7 @@ fn demo_column_1() -> impl Scene { Children [ ( @FeathersMenuItem { - @caption: {bsn! { Text("MenuItem 1") ThemedText }} + @caption: bsn! { Text("MenuItem 1") ThemedText } } on(|_: On| { info!("Menu item 1 clicked!"); @@ -186,7 +186,7 @@ fn demo_column_1() -> impl Scene { ), ( @FeathersMenuItem { - @caption: {bsn! { Text("MenuItem 2") ThemedText }} + @caption: bsn! { Text("MenuItem 2") ThemedText } } on(|_: On| { info!("Menu item 2 clicked!"); @@ -195,7 +195,7 @@ fn demo_column_1() -> impl Scene { @FeathersMenuDivider, ( @FeathersMenuItem { - @caption: {bsn! { Text("MenuItem 3") ThemedText }} + @caption: bsn! { Text("MenuItem 3") ThemedText } } on(|_: On| { info!("Menu item 3 clicked!"); @@ -218,7 +218,7 @@ fn demo_column_1() -> impl Scene { Children [ ( @FeathersButton { - @caption: {bsn! { Text("Left") ThemedText }}, + @caption: bsn! { Text("Left") ThemedText }, @corners: RoundedCorners::Left, } Node { @@ -231,7 +231,7 @@ fn demo_column_1() -> impl Scene { ), ( @FeathersButton { - @caption: {bsn! { Text("Center") ThemedText }}, + @caption: bsn! { Text("Center") ThemedText }, @corners: RoundedCorners::None, } Node { @@ -244,7 +244,7 @@ fn demo_column_1() -> impl Scene { ), ( @FeathersButton { - @caption: {bsn! { Text("Right") ThemedText }}, + @caption: bsn! { Text("Right") ThemedText }, @variant: ButtonVariant::Primary, @corners: RoundedCorners::Right, } @@ -272,7 +272,7 @@ fn demo_column_1() -> impl Scene { ), ( @FeathersCheckbox { - @caption: {bsn! { Text("Checkbox") ThemedText }} + @caption: bsn! { Text("Checkbox") ThemedText } } Checked AccessibleLabel("Checkbox Example") @@ -298,7 +298,7 @@ fn demo_column_1() -> impl Scene { ), ( @FeathersCheckbox { - @caption: {bsn! { Text("Fast Click Checkbox") ThemedText }} + @caption: bsn! { Text("Fast Click Checkbox") ThemedText } } ActivateOnPress AccessibleLabel("Fast Click Checkbox Example") @@ -317,7 +317,7 @@ fn demo_column_1() -> impl Scene { ), ( @FeathersCheckbox { - @caption: {bsn! { Text("Disabled") ThemedText }}, + @caption: bsn! { Text("Disabled") ThemedText }, } InteractionDisabled AccessibleLabel("Disabled Checkbox Example") @@ -327,7 +327,7 @@ fn demo_column_1() -> impl Scene { ), ( @FeathersCheckbox { - @caption: {bsn! { Text("Checked+Disabled") ThemedText }} + @caption: bsn! { Text("Checked+Disabled") ThemedText } } InteractionDisabled Checked @@ -356,22 +356,22 @@ fn demo_column_1() -> impl Scene { Children [ ( @FeathersRadio { - @caption: {bsn! { Text("One") ThemedText }} + @caption: bsn! { Text("One") ThemedText } } Checked ), @FeathersRadio { - @caption: {bsn! { Text("Two") ThemedText }} + @caption: bsn! { Text("Two") ThemedText } }, ( @FeathersRadio { - @caption: {bsn! { Text("Fast Click") ThemedText }} + @caption: bsn! { Text("Fast Click") ThemedText } } ActivateOnPress ), ( @FeathersRadio { - @caption: {bsn! { Text("Disabled") ThemedText }} + @caption: bsn! { Text("Disabled") ThemedText } } InteractionDisabled ),