Skip to content

Commit 197cbcb

Browse files
Reflect non-callback components and resources in bevy_core_widgets and bevy_feathers (#20339)
# Objective - Reflecting public components and resources is essential to allow them to be saved to scenes and function properly in inspectors - Fixes #20040. ## Solution - Derive reflect for all of the public components and resources that didn't have it - Various components that store a `Callback`, like `CoreButton`, are a notable exception - Because Callbacks are not type-erased, and the reflect derive only works when all generics are reflect, I could not get this to work nicely - If you can get this working, please let me know and we can do this in follow-up! - I also slapped a missing Debug derive on the theme resource because it seems extremely useful and I noticed it ## Notes to reviewers - this is not feature-gated: see #20337 for the steps needed to meaningfully do so. Fixing that is out of scope for the 0.17 release. - I've opted to separate the Reflect derive from the other derives wherever rustfmt would let me. While this looks dumb right now, it will reduce the diff noise when fixing #20337. - I could add reflection to the callback-containing components with an ignore for the callback fields, but I don't think this is particularly useful
1 parent 3bd32bc commit 197cbcb

File tree

16 files changed

+93
-28
lines changed

16 files changed

+93
-28
lines changed

crates/bevy_core_widgets/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ bevy_input_focus = { path = "../bevy_input_focus", version = "0.17.0-dev" }
1818
bevy_log = { path = "../bevy_log", version = "0.17.0-dev" }
1919
bevy_math = { path = "../bevy_math", version = "0.17.0-dev" }
2020
bevy_picking = { path = "../bevy_picking", version = "0.17.0-dev" }
21+
bevy_reflect = { path = "../bevy_reflect", version = "0.17.0-dev" }
2122
bevy_ui = { path = "../bevy_ui", version = "0.17.0-dev" }
2223

2324
# other

crates/bevy_core_widgets/src/callback.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use bevy_ecs::system::{Commands, SystemId, SystemInput};
22
use bevy_ecs::world::{DeferredWorld, World};
3+
use bevy_reflect::{prelude::ReflectDefault, Reflect};
34

45
/// A callback defines how we want to be notified when a widget changes state. Unlike an event
56
/// or observer, callbacks are intended for "point-to-point" communication that cuts across the
@@ -27,7 +28,8 @@ use bevy_ecs::world::{DeferredWorld, World};
2728
/// // Later, when we want to execute the callback:
2829
/// app.world_mut().commands().notify(&callback);
2930
/// ```
30-
#[derive(Default, Debug)]
31+
#[derive(Default, Debug, Reflect)]
32+
#[reflect(Default)]
3133
pub enum Callback<I: SystemInput = ()> {
3234
/// Invoke a one-shot system
3335
System(SystemId<I>),

crates/bevy_core_widgets/src/core_radio.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ use bevy_ecs::{
88
component::Component,
99
observer::On,
1010
query::With,
11+
reflect::ReflectComponent,
1112
system::{Commands, Query},
1213
};
1314
use bevy_input::keyboard::{KeyCode, KeyboardInput};
1415
use bevy_input::ButtonState;
1516
use bevy_input_focus::FocusedInput;
1617
use bevy_picking::events::{Click, Pointer};
18+
use bevy_reflect::Reflect;
1719
use bevy_ui::{Checkable, Checked, InteractionDisabled};
1820

1921
use crate::{Activate, Callback, Notify};
@@ -48,6 +50,8 @@ pub struct CoreRadioGroup {
4850
/// See <https://www.w3.org/WAI/ARIA/apg/patterns/radio>/
4951
#[derive(Component, Debug)]
5052
#[require(AccessibilityNode(accesskit::Node::new(Role::RadioButton)), Checkable)]
53+
#[derive(Reflect)]
54+
#[reflect(Component)]
5155
pub struct CoreRadio;
5256

5357
fn radio_group_on_key_input(

crates/bevy_core_widgets/src/core_scrollbar.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@ use bevy_ecs::{
55
hierarchy::{ChildOf, Children},
66
observer::On,
77
query::{With, Without},
8+
reflect::ReflectComponent,
89
system::{Query, Res},
910
};
1011
use bevy_math::Vec2;
1112
use bevy_picking::events::{Cancel, Drag, DragEnd, DragStart, Pointer, Press};
13+
use bevy_reflect::{prelude::ReflectDefault, Reflect};
1214
use bevy_ui::{
1315
ComputedNode, ComputedNodeTarget, Node, ScrollPosition, UiGlobalTransform, UiScale, Val,
1416
};
1517

1618
/// Used to select the orientation of a scrollbar, slider, or other oriented control.
1719
// TODO: Move this to a more central place.
18-
#[derive(Debug, Default, Clone, Copy, PartialEq)]
20+
#[derive(Debug, Default, Clone, Copy, PartialEq, Reflect)]
21+
#[reflect(PartialEq, Clone, Default)]
1922
pub enum ControlOrientation {
2023
/// Horizontal orientation (stretching from left to right)
2124
Horizontal,
@@ -45,7 +48,8 @@ pub enum ControlOrientation {
4548
/// The application is free to position the scrollbars relative to the scrolling container however
4649
/// it wants: it can overlay them on top of the scrolling content, or use a grid layout to displace
4750
/// the content to make room for the scrollbars.
48-
#[derive(Component, Debug)]
51+
#[derive(Component, Debug, Reflect)]
52+
#[reflect(Component)]
4953
pub struct CoreScrollbar {
5054
/// Entity being scrolled.
5155
pub target: Entity,
@@ -62,6 +66,8 @@ pub struct CoreScrollbar {
6266
/// the scrollbar). This should be a child of the scrollbar entity.
6367
#[derive(Component, Debug)]
6468
#[require(CoreScrollbarDragState)]
69+
#[derive(Reflect)]
70+
#[reflect(Component)]
6571
pub struct CoreScrollbarThumb;
6672

6773
impl CoreScrollbar {
@@ -83,7 +89,8 @@ impl CoreScrollbar {
8389

8490
/// Component used to manage the state of a scrollbar during dragging. This component is
8591
/// inserted on the thumb entity.
86-
#[derive(Component, Default)]
92+
#[derive(Component, Default, Reflect)]
93+
#[reflect(Component, Default)]
8794
pub struct CoreScrollbarDragState {
8895
/// Whether the scrollbar is currently being dragged.
8996
pub dragging: bool,

crates/bevy_core_widgets/src/core_slider.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use bevy_ecs::{
1313
component::Component,
1414
observer::On,
1515
query::With,
16+
reflect::ReflectComponent,
1617
system::{Commands, Query},
1718
};
1819
use bevy_input::keyboard::{KeyCode, KeyboardInput};
@@ -21,12 +22,14 @@ use bevy_input_focus::FocusedInput;
2122
use bevy_log::warn_once;
2223
use bevy_math::ops;
2324
use bevy_picking::events::{Drag, DragEnd, DragStart, Pointer, Press};
25+
use bevy_reflect::{prelude::ReflectDefault, Reflect};
2426
use bevy_ui::{ComputedNode, ComputedNodeTarget, InteractionDisabled, UiGlobalTransform, UiScale};
2527

2628
use crate::{Callback, Notify, ValueChange};
2729

2830
/// Defines how the slider should behave when you click on the track (not the thumb).
29-
#[derive(Debug, Default, PartialEq, Clone, Copy)]
31+
#[derive(Debug, Default, PartialEq, Clone, Copy, Reflect)]
32+
#[reflect(Clone, PartialEq, Default)]
3033
pub enum TrackClick {
3134
/// Clicking on the track lets you drag to edit the value, just like clicking on the thumb.
3235
#[default]
@@ -181,6 +184,8 @@ impl Default for SliderRange {
181184
/// shortcuts. Defaults to 1.0.
182185
#[derive(Component, Debug, PartialEq, Clone)]
183186
#[component(immutable)]
187+
#[derive(Reflect)]
188+
#[reflect(Component)]
184189
pub struct SliderStep(pub f32);
185190

186191
impl Default for SliderStep {
@@ -198,7 +203,8 @@ impl Default for SliderStep {
198203
/// The value in this component represents the number of decimal places of desired precision, so a
199204
/// value of 2 would round to the nearest 1/100th. A value of -3 would round to the nearest
200205
/// thousand.
201-
#[derive(Component, Debug, Default, Clone, Copy)]
206+
#[derive(Component, Debug, Default, Clone, Copy, Reflect)]
207+
#[reflect(Component, Default)]
202208
pub struct SliderPrecision(pub i32);
203209

204210
impl SliderPrecision {
@@ -209,7 +215,8 @@ impl SliderPrecision {
209215
}
210216

211217
/// Component used to manage the state of a slider during dragging.
212-
#[derive(Component, Default)]
218+
#[derive(Component, Default, Reflect)]
219+
#[reflect(Component)]
213220
pub struct CoreSliderDragState {
214221
/// Whether the slider is currently being dragged.
215222
pub dragging: bool,

crates/bevy_feathers/src/alpha_pattern.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ use bevy_ecs::{
44
component::Component,
55
lifecycle::Add,
66
observer::On,
7+
reflect::ReflectComponent,
78
resource::Resource,
89
system::{Query, Res},
910
world::FromWorld,
1011
};
11-
use bevy_reflect::TypePath;
12+
use bevy_reflect::{prelude::ReflectDefault, Reflect, TypePath};
1213
use bevy_render::render_resource::{AsBindGroup, ShaderRef};
1314
use bevy_ui_render::ui_material::{MaterialNode, UiMaterial};
1415

@@ -34,7 +35,8 @@ impl FromWorld for AlphaPatternResource {
3435
}
3536

3637
/// Marker that tells us we want to fill in the [`MaterialNode`] with the alpha material.
37-
#[derive(Component, Default, Clone)]
38+
#[derive(Component, Default, Clone, Reflect)]
39+
#[reflect(Component, Default)]
3840
pub(crate) struct AlphaPattern;
3941

4042
/// Observer to fill in the material handle (since we don't have access to the materials asset

crates/bevy_feathers/src/controls/button.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ use bevy_ecs::{
77
hierarchy::{ChildOf, Children},
88
lifecycle::RemovedComponents,
99
query::{Added, Changed, Has, Or},
10+
reflect::ReflectComponent,
1011
schedule::IntoScheduleConfigs,
1112
spawn::{SpawnRelated, SpawnableList},
1213
system::{Commands, In, Query},
1314
};
1415
use bevy_input_focus::tab_navigation::TabIndex;
1516
use bevy_picking::{hover::Hovered, PickingSystems};
17+
use bevy_reflect::{prelude::ReflectDefault, Reflect};
1618
use bevy_ui::{AlignItems, InteractionDisabled, JustifyContent, Node, Pressed, UiRect, Val};
1719

1820
use crate::{
@@ -27,7 +29,8 @@ use crate::{
2729

2830
/// Color variants for buttons. This also functions as a component used by the dynamic styling
2931
/// system to identify which entities are buttons.
30-
#[derive(Component, Default, Clone)]
32+
#[derive(Component, Default, Clone, Reflect)]
33+
#[reflect(Component, Clone, Default)]
3134
pub enum ButtonVariant {
3235
/// The standard button appearance
3336
#[default]

crates/bevy_feathers/src/controls/checkbox.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ use bevy_ecs::{
88
hierarchy::{ChildOf, Children},
99
lifecycle::RemovedComponents,
1010
query::{Added, Changed, Has, Or, With},
11+
reflect::ReflectComponent,
1112
schedule::IntoScheduleConfigs,
1213
spawn::{Spawn, SpawnRelated, SpawnableList},
1314
system::{Commands, In, Query},
1415
};
1516
use bevy_input_focus::tab_navigation::TabIndex;
1617
use bevy_math::Rot2;
1718
use bevy_picking::{hover::Hovered, PickingSystems};
19+
use bevy_reflect::{prelude::ReflectDefault, Reflect};
1820
use bevy_render::view::Visibility;
1921
use bevy_ui::{
2022
AlignItems, BorderRadius, Checked, Display, FlexDirection, InteractionDisabled, JustifyContent,
@@ -38,15 +40,18 @@ pub struct CheckboxProps {
3840
}
3941

4042
/// Marker for the checkbox frame (contains both checkbox and label)
41-
#[derive(Component, Default, Clone)]
43+
#[derive(Component, Default, Clone, Reflect)]
44+
#[reflect(Component, Clone, Default)]
4245
struct CheckboxFrame;
4346

4447
/// Marker for the checkbox outline
45-
#[derive(Component, Default, Clone)]
48+
#[derive(Component, Default, Clone, Reflect)]
49+
#[reflect(Component, Clone, Default)]
4650
struct CheckboxOutline;
4751

4852
/// Marker for the checkbox check mark
49-
#[derive(Component, Default, Clone)]
53+
#[derive(Component, Default, Clone, Reflect)]
54+
#[reflect(Component, Clone, Default)]
5055
struct CheckboxMark;
5156

5257
/// Template function to spawn a checkbox.

crates/bevy_feathers/src/controls/color_swatch.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use bevy_asset::Handle;
22
use bevy_color::Alpha;
3-
use bevy_ecs::{bundle::Bundle, children, component::Component, spawn::SpawnRelated};
3+
use bevy_ecs::{
4+
bundle::Bundle, children, component::Component, reflect::ReflectComponent, spawn::SpawnRelated,
5+
};
6+
use bevy_reflect::{prelude::ReflectDefault, Reflect};
47
use bevy_ui::{BackgroundColor, BorderRadius, Node, PositionType, Val};
58
use bevy_ui_render::ui_material::MaterialNode;
69

@@ -11,13 +14,15 @@ use crate::{
1114
};
1215

1316
/// Marker identifying a color swatch.
14-
#[derive(Component, Default, Clone)]
17+
#[derive(Component, Default, Clone, Reflect)]
18+
#[reflect(Component, Clone, Default)]
1519
pub struct ColorSwatch;
1620

1721
/// Marker identifying the color swatch foreground, the piece that actually displays the color
1822
/// in front of the alpha pattern. This exists so that users can reach in and change the color
1923
/// dynamically.
20-
#[derive(Component, Default, Clone)]
24+
#[derive(Component, Default, Clone, Reflect)]
25+
#[reflect(Component, Clone, Default)]
2126
pub struct ColorSwatchFg;
2227

2328
/// Template function to spawn a color swatch.

crates/bevy_feathers/src/controls/radio.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ use bevy_ecs::{
88
hierarchy::{ChildOf, Children},
99
lifecycle::RemovedComponents,
1010
query::{Added, Changed, Has, Or, With},
11+
reflect::ReflectComponent,
1112
schedule::IntoScheduleConfigs,
1213
spawn::{Spawn, SpawnRelated, SpawnableList},
1314
system::{Commands, Query},
1415
};
1516
use bevy_input_focus::tab_navigation::TabIndex;
1617
use bevy_picking::{hover::Hovered, PickingSystems};
18+
use bevy_reflect::{prelude::ReflectDefault, Reflect};
1719
use bevy_render::view::Visibility;
1820
use bevy_ui::{
1921
AlignItems, BorderRadius, Checked, Display, FlexDirection, InteractionDisabled, JustifyContent,
@@ -30,11 +32,13 @@ use crate::{
3032
};
3133

3234
/// Marker for the radio outline
33-
#[derive(Component, Default, Clone)]
35+
#[derive(Component, Default, Clone, Reflect)]
36+
#[reflect(Component, Clone, Default)]
3437
struct RadioOutline;
3538

3639
/// Marker for the radio check mark
37-
#[derive(Component, Default, Clone)]
40+
#[derive(Component, Default, Clone, Reflect)]
41+
#[reflect(Component, Clone, Default)]
3842
struct RadioMark;
3943

4044
/// Template function to spawn a radio.

0 commit comments

Comments
 (0)