bevy_ui: Add FromReflect derives (#8495)

# Objective

A lot of items in `bevy_ui` could be `FromReflect` but aren't. This
prevents users and library authors from being able to convert from a
`dyn Reflect` to one of these items.

## Solution

Derive `FromReflect` where possible. Also register the
`ReflectFromReflect` type data.
This commit is contained in:
Gino Valente 2023-04-26 05:17:23 -07:00 committed by GitHub
parent 74d425263a
commit 85c3251c10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 63 deletions

View file

@ -2,6 +2,8 @@
use bevy_ecs::component::Component;
use bevy_ecs::prelude::With;
use bevy_ecs::reflect::ReflectComponent;
use bevy_reflect::{std_traits::ReflectDefault, FromReflect, Reflect, ReflectFromReflect};
use bevy_render::camera::Camera;
use bevy_render::extract_component::ExtractComponent;
@ -10,8 +12,9 @@ use bevy_render::extract_component::ExtractComponent;
/// When a [`Camera`] doesn't have the [`UiCameraConfig`] component,
/// it will display the UI by default.
///
#[derive(Component, Clone, ExtractComponent)]
#[derive(Component, Clone, ExtractComponent, Reflect, FromReflect)]
#[extract_component_filter(With<Camera>)]
#[reflect(Component, FromReflect, Default)]
pub struct UiCameraConfig {
/// Whether to output UI to this camera view.
///

View file

@ -10,7 +10,9 @@ use bevy_ecs::{
};
use bevy_input::{mouse::MouseButton, touch::Touches, Input};
use bevy_math::Vec2;
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
use bevy_reflect::{
FromReflect, Reflect, ReflectDeserialize, ReflectFromReflect, ReflectSerialize,
};
use bevy_render::{camera::NormalizedRenderTarget, prelude::Camera, view::ComputedVisibility};
use bevy_transform::components::GlobalTransform;
@ -32,8 +34,10 @@ use smallvec::SmallVec;
///
/// Note that you can also control the visibility of a node using the [`Display`](crate::ui_node::Display) property,
/// which fully collapses it during layout calculations.
#[derive(Component, Copy, Clone, Eq, PartialEq, Debug, Reflect, Serialize, Deserialize)]
#[reflect(Component, Serialize, Deserialize, PartialEq)]
#[derive(
Component, Copy, Clone, Eq, PartialEq, Debug, Reflect, FromReflect, Serialize, Deserialize,
)]
#[reflect(Component, FromReflect, Serialize, Deserialize, PartialEq)]
pub enum Interaction {
/// The node has been clicked
Clicked,
@ -68,10 +72,11 @@ impl Default for Interaction {
PartialEq,
Debug,
Reflect,
FromReflect,
Serialize,
Deserialize,
)]
#[reflect(Component, Serialize, Deserialize, PartialEq)]
#[reflect(Component, FromReflect, Serialize, Deserialize, PartialEq)]
pub struct RelativeCursorPosition {
/// Cursor position relative to size and position of the Node.
pub normalized: Option<Vec2>,
@ -87,8 +92,10 @@ impl RelativeCursorPosition {
}
/// Describes whether the node should block interactions with lower nodes
#[derive(Component, Copy, Clone, Eq, PartialEq, Debug, Reflect, Serialize, Deserialize)]
#[reflect(Component, Serialize, Deserialize, PartialEq)]
#[derive(
Component, Copy, Clone, Eq, PartialEq, Debug, Reflect, FromReflect, Serialize, Deserialize,
)]
#[reflect(Component, FromReflect, Serialize, Deserialize, PartialEq)]
pub enum FocusPolicy {
/// Blocks interaction
Block,

View file

@ -1,5 +1,5 @@
use crate::Val;
use bevy_reflect::Reflect;
use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect};
use std::ops::{Div, DivAssign, Mul, MulAssign};
/// A type which is commonly used to define margins, paddings and borders.
@ -46,8 +46,8 @@ use std::ops::{Div, DivAssign, Mul, MulAssign};
/// bottom: Val::Px(40.0),
/// };
/// ```
#[derive(Copy, Clone, PartialEq, Debug, Reflect)]
#[reflect(PartialEq)]
#[derive(Copy, Clone, PartialEq, Debug, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq)]
pub struct UiRect {
/// The value corresponding to the left side of the UI rect.
pub left: Val,
@ -285,8 +285,8 @@ impl Default for UiRect {
/// A 2-dimensional area defined by a width and height.
///
/// It is commonly used to define the size of a text or UI element.
#[derive(Copy, Clone, PartialEq, Debug, Reflect)]
#[reflect(PartialEq)]
#[derive(Copy, Clone, PartialEq, Debug, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq)]
pub struct Size {
/// The width of the 2-dimensional area.
pub width: Val,

View file

@ -3,6 +3,7 @@ use bevy_asset::Handle;
use bevy_ecs::{prelude::Component, reflect::ReflectComponent};
use bevy_math::{Rect, Vec2};
use bevy_reflect::prelude::*;
use bevy_reflect::ReflectFromReflect;
use bevy_render::{
color::Color,
texture::{Image, DEFAULT_IMAGE_HANDLE},
@ -62,8 +63,8 @@ impl Default for Node {
///
/// This enum allows specifying values for various [`Style`] properties in different units,
/// such as logical pixels, percentages, or automatically determined values.
#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum Val {
/// Automatically determine the value based on the context and other `Style` properties.
Auto,
@ -278,8 +279,8 @@ impl Val {
/// - [A Complete Guide To CSS Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) by CSS Tricks. This is detailed guide with illustrations and comphrehensive written explanation of the different CSS Grid properties and how they work.
/// - [CSS Grid Garden](https://cssgridgarden.com/). An interactive tutorial/game that teaches the essential parts of CSS Grid in a fun engaging way.
#[derive(Component, Clone, PartialEq, Debug, Reflect)]
#[reflect(Component, Default, PartialEq)]
#[derive(Component, Clone, PartialEq, Debug, Reflect, FromReflect)]
#[reflect(Component, FromReflect, Default, PartialEq)]
pub struct Style {
/// Which layout algorithm to use when laying out this node's contents:
/// - [`Display::Flex`]: Use the Flexbox layout algorithm
@ -598,8 +599,8 @@ impl Default for Style {
}
/// How items are aligned according to the cross axis
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum AlignItems {
/// The items are packed in their default position as if no alignment was applied
Default,
@ -632,8 +633,8 @@ impl Default for AlignItems {
}
/// How items are aligned according to the cross axis
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum JustifyItems {
/// The items are packed in their default position as if no alignment was applied
Default,
@ -661,8 +662,8 @@ impl Default for JustifyItems {
/// How this item is aligned according to the cross axis.
/// Overrides [`AlignItems`].
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum AlignSelf {
/// Use the parent node's [`AlignItems`] value to determine how this item should be aligned.
Auto,
@ -696,8 +697,8 @@ impl Default for AlignSelf {
/// How this item is aligned according to the cross axis.
/// Overrides [`AlignItems`].
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum JustifySelf {
/// Use the parent node's [`AlignItems`] value to determine how this item should be aligned.
Auto,
@ -726,8 +727,8 @@ impl Default for JustifySelf {
/// Defines how each line is aligned within the flexbox.
///
/// It only applies if [`FlexWrap::Wrap`] is present and if there are multiple lines of items.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum AlignContent {
/// The items are packed in their default position as if no alignment was applied
Default,
@ -765,8 +766,8 @@ impl Default for AlignContent {
}
/// Defines how items are aligned according to the main axis
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum JustifyContent {
/// The items are packed in their default position as if no alignment was applied
Default,
@ -801,8 +802,8 @@ impl Default for JustifyContent {
/// Defines the text direction
///
/// For example English is written LTR (left-to-right) while Arabic is written RTL (right-to-left).
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum Direction {
/// Inherit from parent node.
Inherit,
@ -825,8 +826,8 @@ impl Default for Direction {
/// Whether to use a Flexbox layout model.
///
/// Part of the [`Style`] component.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum Display {
/// Use Flexbox layout model to determine the position of this [`Node`].
Flex,
@ -850,8 +851,8 @@ impl Default for Display {
}
/// Defines how flexbox items are ordered within a flexbox
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum FlexDirection {
/// Same way as text direction along the main axis.
Row,
@ -874,8 +875,8 @@ impl Default for FlexDirection {
}
/// Whether to show or hide overflowing items
#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect, Serialize, Deserialize)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect, Serialize, Deserialize, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub struct Overflow {
/// Whether to show or clip overflowing items on the x axis
pub x: OverflowAxis,
@ -934,8 +935,8 @@ impl Default for Overflow {
}
/// Whether to show or hide overflowing items
#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect, Serialize, Deserialize)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Reflect, FromReflect, Serialize, Deserialize)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum OverflowAxis {
/// Show overflowing items.
Visible,
@ -959,8 +960,8 @@ impl Default for OverflowAxis {
}
/// The strategy used to position this node
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum PositionType {
/// Relative to all other nodes with the [`PositionType::Relative`] value.
Relative,
@ -981,8 +982,8 @@ impl Default for PositionType {
}
/// Defines if flexbox items appear on a single line or on multiple lines
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum FlexWrap {
/// Single line, will overflow if needed.
NoWrap,
@ -1009,8 +1010,8 @@ impl Default for FlexWrap {
/// Defaults to [`GridAutoFlow::Row`]
///
/// <https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow>
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum GridAutoFlow {
/// Items are placed by filling each row in turn, adding new rows as necessary
Row,
@ -1033,7 +1034,7 @@ impl Default for GridAutoFlow {
}
#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect_value(PartialEq, Serialize, Deserialize)]
#[reflect_value(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum MinTrackSizingFunction {
/// Track minimum size should be a fixed pixel value
Px(f32),
@ -1048,7 +1049,7 @@ pub enum MinTrackSizingFunction {
}
#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect_value(PartialEq, Serialize, Deserialize)]
#[reflect_value(FromReflect, PartialEq, Serialize, Deserialize)]
pub enum MaxTrackSizingFunction {
/// Track maximum size should be a fixed pixel value
Px(f32),
@ -1073,7 +1074,7 @@ pub enum MaxTrackSizingFunction {
/// A [`GridTrack`] is a Row or Column of a CSS Grid. This struct specifies what size the track should be.
/// See below for the different "track sizing functions" you can specify.
#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub struct GridTrack {
pub(crate) min_sizing_function: MinTrackSizingFunction,
pub(crate) max_sizing_function: MaxTrackSizingFunction,
@ -1191,7 +1192,7 @@ impl Default for GridTrack {
}
#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
/// How many times to repeat a repeated grid track
///
/// <https://developer.mozilla.org/en-US/docs/Web/CSS/repeat>
@ -1241,7 +1242,7 @@ impl From<usize> for GridTrackRepetition {
/// then all track (in and outside of the repetition) must be fixed size (px or percent). Integer repetitions are just shorthand for writing out
/// N tracks longhand and are not subject to the same limitations.
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
pub struct RepeatedGridTrack {
pub(crate) repetition: GridTrackRepetition,
pub(crate) tracks: SmallVec<[GridTrack; 1]>,
@ -1390,8 +1391,8 @@ impl From<RepeatedGridTrack> for Vec<RepeatedGridTrack> {
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
#[reflect(PartialEq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect, FromReflect)]
#[reflect(FromReflect, PartialEq, Serialize, Deserialize)]
/// Represents the position of a grid item in a single axis.
///
/// There are 3 fields which may be set:
@ -1513,8 +1514,8 @@ impl Default for GridPlacement {
///
/// This serves as the "fill" color.
/// When combined with [`UiImage`], tints the provided texture.
#[derive(Component, Copy, Clone, Debug, Reflect)]
#[reflect(Component, Default)]
#[derive(Component, Copy, Clone, Debug, Reflect, FromReflect)]
#[reflect(FromReflect, Component, Default)]
pub struct BackgroundColor(pub Color);
impl BackgroundColor {
@ -1585,8 +1586,8 @@ impl From<Handle<Image>> for UiImage {
}
/// The calculated clip of the node
#[derive(Component, Default, Copy, Clone, Debug, Reflect)]
#[reflect(Component)]
#[derive(Component, Default, Copy, Clone, Debug, Reflect, FromReflect)]
#[reflect(FromReflect, Component)]
pub struct CalculatedClip {
/// The rect of the clip
pub clip: Rect,
@ -1605,8 +1606,8 @@ pub struct CalculatedClip {
/// [`ZIndex::Local(n)`] and [`ZIndex::Global(n)`] for root nodes.
///
/// Nodes without this component will be treated as if they had a value of [`ZIndex::Local(0)`].
#[derive(Component, Copy, Clone, Debug, Reflect)]
#[reflect(Component)]
#[derive(Component, Copy, Clone, Debug, Reflect, FromReflect)]
#[reflect(Component, FromReflect)]
pub enum ZIndex {
/// Indicates the order in which this node should be rendered relative to its siblings.
Local(i32),

View file

@ -1,9 +1,9 @@
use bevy_ecs::prelude::Component;
use bevy_ecs::reflect::ReflectComponent;
use bevy_reflect::std_traits::ReflectDefault;
use bevy_reflect::Reflect;
use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect};
/// Marker struct for buttons
#[derive(Component, Debug, Default, Clone, Copy, Reflect)]
#[reflect(Component, Default)]
#[derive(Component, Debug, Default, Clone, Copy, Reflect, FromReflect)]
#[reflect(Component, FromReflect, Default)]
pub struct Button;

View file

@ -1,9 +1,9 @@
use bevy_ecs::prelude::Component;
use bevy_ecs::reflect::ReflectComponent;
use bevy_reflect::std_traits::ReflectDefault;
use bevy_reflect::Reflect;
use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect};
/// Marker struct for labels
#[derive(Component, Debug, Default, Clone, Copy, Reflect)]
#[reflect(Component, Default)]
#[derive(Component, Debug, Default, Clone, Copy, Reflect, FromReflect)]
#[reflect(Component, FromReflect, Default)]
pub struct Label;