Reflect bevy_input_focus
(#17212)
# Objective Fixes #17099. ## Solution Derive, register, and feature flag. ## Testing Ran CI.
This commit is contained in:
parent
8baf4e5b2c
commit
3578f9e4d0
@ -9,6 +9,17 @@ license = "MIT OR Apache-2.0"
|
||||
keywords = ["bevy"]
|
||||
rust-version = "1.83.0"
|
||||
|
||||
[features]
|
||||
default = ["bevy_reflect"]
|
||||
|
||||
## Adds runtime reflection support using `bevy_reflect`.
|
||||
bevy_reflect = [
|
||||
"dep:bevy_reflect",
|
||||
"bevy_app/bevy_reflect",
|
||||
"bevy_ecs/bevy_reflect",
|
||||
"bevy_math/bevy_reflect",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
# bevy
|
||||
bevy_app = { path = "../bevy_app", version = "0.16.0-dev", default-features = false }
|
||||
@ -17,6 +28,9 @@ bevy_input = { path = "../bevy_input", version = "0.16.0-dev", default-features
|
||||
bevy_hierarchy = { path = "../bevy_hierarchy", version = "0.16.0-dev", default-features = false }
|
||||
bevy_math = { path = "../bevy_math", version = "0.16.0-dev", default-features = false }
|
||||
bevy_window = { path = "../bevy_window", version = "0.16.0-dev", default-features = false }
|
||||
bevy_reflect = { path = "../bevy_reflect", version = "0.16.0-dev", features = [
|
||||
"glam",
|
||||
], default-features = false, optional = true }
|
||||
|
||||
# other
|
||||
thiserror = { version = "2", default-features = false }
|
||||
|
@ -1,6 +1,8 @@
|
||||
//! Contains the [`AutoFocus`] component and related machinery.
|
||||
|
||||
use bevy_ecs::{component::ComponentId, prelude::*, world::DeferredWorld};
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
use bevy_reflect::{prelude::*, Reflect};
|
||||
|
||||
use crate::InputFocus;
|
||||
|
||||
@ -12,6 +14,11 @@ use crate::InputFocus;
|
||||
/// The focus is swapped when this component is added
|
||||
/// or an entity with this component is spawned.
|
||||
#[derive(Debug, Default, Component, Copy, Clone)]
|
||||
#[cfg_attr(
|
||||
feature = "bevy_reflect",
|
||||
derive(Reflect),
|
||||
reflect(Debug, Default, Component)
|
||||
)]
|
||||
#[component(on_add = on_auto_focus_added)]
|
||||
pub struct AutoFocus;
|
||||
|
||||
|
@ -22,6 +22,8 @@ use bevy_ecs::{
|
||||
system::SystemParam,
|
||||
};
|
||||
use bevy_math::CompassOctant;
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
use bevy_reflect::{prelude::*, Reflect};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::InputFocus;
|
||||
@ -33,11 +35,20 @@ pub struct DirectionalNavigationPlugin;
|
||||
impl Plugin for DirectionalNavigationPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<DirectionalNavigationMap>();
|
||||
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
app.register_type::<NavNeighbors>()
|
||||
.register_type::<DirectionalNavigationMap>();
|
||||
}
|
||||
}
|
||||
|
||||
/// The up-to-eight neighbors of a focusable entity, one for each [`CompassOctant`].
|
||||
#[derive(Default, Debug, Clone, PartialEq)]
|
||||
#[cfg_attr(
|
||||
feature = "bevy_reflect",
|
||||
derive(Reflect),
|
||||
reflect(Default, Debug, PartialEq)
|
||||
)]
|
||||
pub struct NavNeighbors {
|
||||
/// The array of neighbors, one for each [`CompassOctant`].
|
||||
/// The mapping between array elements and directions is determined by [`CompassOctant::to_index`].
|
||||
@ -79,6 +90,11 @@ impl NavNeighbors {
|
||||
///
|
||||
/// For now, this graph must be built manually, and the developer is responsible for ensuring that it meets the above criteria.
|
||||
#[derive(Resource, Debug, Default, Clone, PartialEq)]
|
||||
#[cfg_attr(
|
||||
feature = "bevy_reflect",
|
||||
derive(Reflect),
|
||||
reflect(Resource, Debug, Default, PartialEq)
|
||||
)]
|
||||
pub struct DirectionalNavigationMap {
|
||||
/// A directed graph of focusable entities.
|
||||
///
|
||||
|
@ -28,6 +28,8 @@ use bevy_app::{App, Plugin, PreUpdate, Startup};
|
||||
use bevy_ecs::{prelude::*, query::QueryData, system::SystemParam, traversal::Traversal};
|
||||
use bevy_hierarchy::{HierarchyQueryExt, Parent};
|
||||
use bevy_input::{gamepad::GamepadButtonChangedEvent, keyboard::KeyboardInput, mouse::MouseWheel};
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
use bevy_reflect::{prelude::*, Reflect};
|
||||
use bevy_window::{PrimaryWindow, Window};
|
||||
use core::fmt::Debug;
|
||||
|
||||
@ -69,6 +71,11 @@ use core::fmt::Debug;
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default, Resource)]
|
||||
#[cfg_attr(
|
||||
feature = "bevy_reflect",
|
||||
derive(Reflect),
|
||||
reflect(Debug, Default, Resource)
|
||||
)]
|
||||
pub struct InputFocus(pub Option<Entity>);
|
||||
|
||||
impl InputFocus {
|
||||
@ -108,6 +115,7 @@ impl InputFocus {
|
||||
///
|
||||
/// To easily access information about whether focus indicators should be shown for a given entity, use the [`IsFocused`] trait.
|
||||
#[derive(Clone, Debug, Resource)]
|
||||
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, Resource))]
|
||||
pub struct InputFocusVisible(pub bool);
|
||||
|
||||
/// A bubble-able user input event that starts at the currently focused entity.
|
||||
@ -118,6 +126,7 @@ pub struct InputFocusVisible(pub bool);
|
||||
/// To set up your own bubbling input event, add the [`dispatch_focused_input::<MyEvent>`](dispatch_focused_input) system to your app,
|
||||
/// in the [`InputFocusSet::Dispatch`] system set during [`PreUpdate`].
|
||||
#[derive(Clone, Debug, Component)]
|
||||
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Component))]
|
||||
pub struct FocusedInput<E: Event + Clone> {
|
||||
/// The underlying input event.
|
||||
pub input: E,
|
||||
@ -176,6 +185,11 @@ impl Plugin for InputDispatchPlugin {
|
||||
)
|
||||
.in_set(InputFocusSet::Dispatch),
|
||||
);
|
||||
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
app.register_type::<AutoFocus>()
|
||||
.register_type::<InputFocus>()
|
||||
.register_type::<InputFocusVisible>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
//! This object can be injected into your systems, and provides a [`navigate`](`TabNavigation::navigate`) method which can be
|
||||
//! used to navigate between focusable entities.
|
||||
use bevy_app::{App, Plugin, Startup};
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
use bevy_ecs::prelude::ReflectComponent;
|
||||
use bevy_ecs::{
|
||||
component::Component,
|
||||
entity::Entity,
|
||||
@ -36,6 +38,8 @@ use bevy_input::{
|
||||
keyboard::{KeyCode, KeyboardInput},
|
||||
ButtonInput, ButtonState,
|
||||
};
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
use bevy_reflect::{prelude::*, Reflect};
|
||||
use bevy_window::PrimaryWindow;
|
||||
use thiserror::Error;
|
||||
use tracing::warn;
|
||||
@ -47,10 +51,20 @@ use crate::{FocusedInput, InputFocus, InputFocusVisible};
|
||||
/// Note that you must also add the [`TabGroup`] component to the entity's ancestor in order
|
||||
/// for this component to have any effect.
|
||||
#[derive(Debug, Default, Component, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[cfg_attr(
|
||||
feature = "bevy_reflect",
|
||||
derive(Reflect),
|
||||
reflect(Debug, Default, Component, PartialEq)
|
||||
)]
|
||||
pub struct TabIndex(pub i32);
|
||||
|
||||
/// A component used to mark a tree of entities as containing tabbable elements.
|
||||
#[derive(Debug, Default, Component, Copy, Clone)]
|
||||
#[cfg_attr(
|
||||
feature = "bevy_reflect",
|
||||
derive(Reflect),
|
||||
reflect(Debug, Default, Component)
|
||||
)]
|
||||
pub struct TabGroup {
|
||||
/// The order of the tab group relative to other tab groups.
|
||||
pub order: i32,
|
||||
@ -287,6 +301,9 @@ pub struct TabNavigationPlugin;
|
||||
impl Plugin for TabNavigationPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, setup_tab_navigation);
|
||||
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
app.register_type::<TabIndex>().register_type::<TabGroup>();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user