1use crate::{ButtonInput, ButtonState};
4use bevy_ecs::{
5 change_detection::DetectChangesMut,
6 entity::Entity,
7 event::{Event, EventReader},
8 system::{ResMut, Resource},
9};
10use bevy_math::Vec2;
11#[cfg(feature = "bevy_reflect")]
12use {
13 bevy_ecs::reflect::ReflectResource,
14 bevy_reflect::{std_traits::ReflectDefault, Reflect},
15};
16
17#[cfg(all(feature = "serialize", feature = "bevy_reflect"))]
18use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
19
20#[derive(Event, Debug, Clone, Copy, PartialEq, Eq)]
29#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
30#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
31#[cfg_attr(
32 all(feature = "serialize", feature = "bevy_reflect"),
33 reflect(Serialize, Deserialize)
34)]
35pub struct MouseButtonInput {
36 pub button: MouseButton,
38 pub state: ButtonState,
40 pub window: Entity,
42}
43
44#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
55#[cfg_attr(
56 feature = "bevy_reflect",
57 derive(Reflect),
58 reflect(Debug, Hash, PartialEq)
59)]
60#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
61#[cfg_attr(
62 all(feature = "serialize", feature = "bevy_reflect"),
63 reflect(Serialize, Deserialize)
64)]
65pub enum MouseButton {
66 Left,
68 Right,
70 Middle,
72 Back,
74 Forward,
76 Other(u16),
78}
79
80#[derive(Event, Debug, Clone, Copy, PartialEq)]
90#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
91#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
92#[cfg_attr(
93 all(feature = "serialize", feature = "bevy_reflect"),
94 reflect(Serialize, Deserialize)
95)]
96pub struct MouseMotion {
97 pub delta: Vec2,
99}
100
101#[derive(Debug, Hash, Clone, Copy, Eq, PartialEq)]
108#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
109#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
110#[cfg_attr(
111 all(feature = "serialize", feature = "bevy_reflect"),
112 reflect(Serialize, Deserialize)
113)]
114pub enum MouseScrollUnit {
115 Line,
120 Pixel,
125}
126
127#[derive(Event, Debug, Clone, Copy, PartialEq)]
131#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Debug, PartialEq))]
132#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
133#[cfg_attr(
134 all(feature = "serialize", feature = "bevy_reflect"),
135 reflect(Serialize, Deserialize)
136)]
137pub struct MouseWheel {
138 pub unit: MouseScrollUnit,
140 pub x: f32,
142 pub y: f32,
144 pub window: Entity,
146}
147
148pub fn mouse_button_input_system(
155 mut mouse_button_input: ResMut<ButtonInput<MouseButton>>,
156 mut mouse_button_input_events: EventReader<MouseButtonInput>,
157) {
158 mouse_button_input.bypass_change_detection().clear();
159 for event in mouse_button_input_events.read() {
160 match event.state {
161 ButtonState::Pressed => mouse_button_input.press(event.button),
162 ButtonState::Released => mouse_button_input.release(event.button),
163 }
164 }
165}
166
167#[derive(Resource, Debug, Clone, Copy, PartialEq, Default)]
173#[cfg_attr(
174 feature = "bevy_reflect",
175 derive(Reflect),
176 reflect(Debug, Default, Resource, PartialEq)
177)]
178#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
179#[cfg_attr(
180 all(feature = "serialize", feature = "bevy_reflect"),
181 reflect(Serialize, Deserialize)
182)]
183pub struct AccumulatedMouseMotion {
184 pub delta: Vec2,
186}
187
188#[derive(Resource, Debug, Clone, Copy, PartialEq)]
194#[cfg_attr(
195 feature = "bevy_reflect",
196 derive(Reflect),
197 reflect(Debug, Default, Resource, PartialEq)
198)]
199#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
200#[cfg_attr(
201 all(feature = "serialize", feature = "bevy_reflect"),
202 reflect(Serialize, Deserialize)
203)]
204pub struct AccumulatedMouseScroll {
205 pub unit: MouseScrollUnit,
209 pub delta: Vec2,
211}
212
213impl Default for AccumulatedMouseScroll {
214 fn default() -> Self {
215 Self {
216 unit: MouseScrollUnit::Line,
217 delta: Vec2::ZERO,
218 }
219 }
220}
221
222pub fn accumulate_mouse_motion_system(
225 mut mouse_motion_event: EventReader<MouseMotion>,
226 mut accumulated_mouse_motion: ResMut<AccumulatedMouseMotion>,
227) {
228 let mut delta = Vec2::ZERO;
229 for event in mouse_motion_event.read() {
230 delta += event.delta;
231 }
232 accumulated_mouse_motion.delta = delta;
233}
234
235pub fn accumulate_mouse_scroll_system(
238 mut mouse_scroll_event: EventReader<MouseWheel>,
239 mut accumulated_mouse_scroll: ResMut<AccumulatedMouseScroll>,
240) {
241 let mut delta = Vec2::ZERO;
242 let mut unit = MouseScrollUnit::Line;
243 for event in mouse_scroll_event.read() {
244 if event.unit != unit {
245 unit = event.unit;
246 }
247 delta += Vec2::new(event.x, event.y);
248 }
249 accumulated_mouse_scroll.delta = delta;
250 accumulated_mouse_scroll.unit = unit;
251}