1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![forbid(unsafe_code)]
3#![doc(
4 html_logo_url = "https://bevy.org/assets/icon.png",
5 html_favicon_url = "https://bevy.org/assets/icon.png"
6)]
7#![no_std]
8
9#[cfg(feature = "std")]
16extern crate std;
17
18extern crate alloc;
19
20mod axis;
21mod button_input;
22pub mod common_conditions;
24
25#[cfg(feature = "gamepad")]
26pub mod gamepad;
27
28#[cfg(feature = "gestures")]
29pub mod gestures;
30
31#[cfg(feature = "keyboard")]
32pub mod keyboard;
33
34#[cfg(feature = "mouse")]
35pub mod mouse;
36
37#[cfg(any(feature = "touch", feature = "mouse"))]
39pub mod touch;
40
41pub use axis::*;
42pub use button_input::*;
43
44pub mod prelude {
48 #[doc(hidden)]
49 pub use crate::{Axis, ButtonInput};
50
51 #[doc(hidden)]
52 #[cfg(feature = "gamepad")]
53 pub use crate::gamepad::{Gamepad, GamepadAxis, GamepadButton, GamepadSettings};
54
55 #[doc(hidden)]
56 #[cfg(feature = "keyboard")]
57 pub use crate::keyboard::KeyCode;
58
59 #[doc(hidden)]
60 #[cfg(feature = "mouse")]
61 pub use crate::mouse::MouseButton;
62
63 #[doc(hidden)]
64 #[cfg(feature = "touch")]
65 pub use crate::touch::{TouchInput, Touches};
66}
67
68use bevy_app::prelude::*;
69use bevy_ecs::prelude::*;
70#[cfg(feature = "bevy_reflect")]
71use bevy_reflect::Reflect;
72
73#[cfg(feature = "gestures")]
74use gestures::*;
75
76#[cfg(feature = "keyboard")]
77use keyboard::{keyboard_input_system, Key, KeyCode, KeyboardFocusLost, KeyboardInput};
78
79#[cfg(feature = "mouse")]
80use mouse::{
81 accumulate_mouse_motion_system, accumulate_mouse_scroll_system, mouse_button_input_system,
82 AccumulatedMouseMotion, AccumulatedMouseScroll, MouseButton, MouseButtonInput, MouseMotion,
83 MouseWheel,
84};
85
86#[cfg(feature = "touch")]
87use touch::{touch_screen_input_system, TouchInput, Touches};
88
89#[cfg(feature = "gamepad")]
90use gamepad::{
91 gamepad_connection_system, gamepad_event_processing_system, GamepadAxisChangedEvent,
92 GamepadButtonChangedEvent, GamepadButtonStateChangedEvent, GamepadConnectionEvent,
93 GamepadEvent, GamepadRumbleRequest, RawGamepadAxisChangedEvent, RawGamepadButtonChangedEvent,
94 RawGamepadEvent,
95};
96
97#[cfg(all(feature = "serialize", feature = "bevy_reflect"))]
98use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
99
100#[derive(Default)]
102pub struct InputPlugin;
103
104#[derive(Debug, PartialEq, Eq, Clone, Hash, SystemSet)]
106pub struct InputSystems;
107
108impl Plugin for InputPlugin {
109 #[expect(clippy::allow_attributes, reason = "this is only sometimes unused")]
110 #[allow(unused, reason = "all features could be disabled")]
111 fn build(&self, app: &mut App) {
112 #[cfg(feature = "keyboard")]
113 app.add_message::<KeyboardInput>()
114 .add_message::<KeyboardFocusLost>()
115 .init_resource::<ButtonInput<KeyCode>>()
116 .init_resource::<ButtonInput<Key>>()
117 .add_systems(PreUpdate, keyboard_input_system.in_set(InputSystems));
118
119 #[cfg(feature = "mouse")]
120 app.add_message::<MouseButtonInput>()
121 .add_message::<MouseMotion>()
122 .add_message::<MouseWheel>()
123 .init_resource::<AccumulatedMouseMotion>()
124 .init_resource::<AccumulatedMouseScroll>()
125 .init_resource::<ButtonInput<MouseButton>>()
126 .add_systems(
127 PreUpdate,
128 (
129 mouse_button_input_system,
130 accumulate_mouse_motion_system,
131 accumulate_mouse_scroll_system,
132 )
133 .in_set(InputSystems),
134 );
135
136 #[cfg(feature = "gestures")]
137 app.add_message::<PinchGesture>()
138 .add_message::<RotationGesture>()
139 .add_message::<DoubleTapGesture>()
140 .add_message::<PanGesture>();
141
142 #[cfg(feature = "gamepad")]
143 app.add_message::<GamepadEvent>()
144 .add_message::<GamepadConnectionEvent>()
145 .add_message::<GamepadButtonChangedEvent>()
146 .add_message::<GamepadButtonStateChangedEvent>()
147 .add_message::<GamepadAxisChangedEvent>()
148 .add_message::<RawGamepadEvent>()
149 .add_message::<RawGamepadAxisChangedEvent>()
150 .add_message::<RawGamepadButtonChangedEvent>()
151 .add_message::<GamepadRumbleRequest>()
152 .add_systems(
153 PreUpdate,
154 (
155 gamepad_connection_system,
156 gamepad_event_processing_system.after(gamepad_connection_system),
157 )
158 .in_set(InputSystems),
159 );
160
161 #[cfg(feature = "touch")]
162 app.add_message::<TouchInput>()
163 .init_resource::<Touches>()
164 .add_systems(PreUpdate, touch_screen_input_system.in_set(InputSystems));
165 }
166}
167
168#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
170#[cfg_attr(
171 feature = "bevy_reflect",
172 derive(Reflect),
173 reflect(Debug, Hash, PartialEq, Clone)
174)]
175#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
176#[cfg_attr(
177 all(feature = "serialize", feature = "bevy_reflect"),
178 reflect(Serialize, Deserialize)
179)]
180pub enum ButtonState {
181 Pressed,
183 Released,
185}
186
187impl ButtonState {
188 pub fn is_pressed(&self) -> bool {
190 matches!(self, ButtonState::Pressed)
191 }
192}