1use crate::{ButtonInput, ButtonState};
4use bevy_ecs::{
5 change_detection::DetectChangesMut,
6 entity::Entity,
7 event::{Event, EventReader},
8 resource::Resource,
9 system::ResMut,
10};
11use bevy_math::Vec2;
12#[cfg(feature = "bevy_reflect")]
13use {
14 bevy_ecs::reflect::ReflectResource,
15 bevy_reflect::{std_traits::ReflectDefault, Reflect},
16};
17
18#[cfg(all(feature = "serialize", feature = "bevy_reflect"))]
19use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
20
21#[derive(Event, Debug, Clone, Copy, PartialEq, Eq)]
30#[cfg_attr(
31 feature = "bevy_reflect",
32 derive(Reflect),
33 reflect(Debug, PartialEq, Clone)
34)]
35#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
36#[cfg_attr(
37 all(feature = "serialize", feature = "bevy_reflect"),
38 reflect(Serialize, Deserialize)
39)]
40pub struct MouseButtonInput {
41 pub button: MouseButton,
43 pub state: ButtonState,
45 pub window: Entity,
47}
48
49#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
60#[cfg_attr(
61 feature = "bevy_reflect",
62 derive(Reflect),
63 reflect(Debug, Hash, PartialEq, Clone)
64)]
65#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
66#[cfg_attr(
67 all(feature = "serialize", feature = "bevy_reflect"),
68 reflect(Serialize, Deserialize)
69)]
70pub enum MouseButton {
71 Left,
73 Right,
75 Middle,
77 Back,
79 Forward,
81 Other(u16),
83}
84
85#[derive(Event, Debug, Clone, Copy, PartialEq)]
95#[cfg_attr(
96 feature = "bevy_reflect",
97 derive(Reflect),
98 reflect(Debug, PartialEq, Clone)
99)]
100#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
101#[cfg_attr(
102 all(feature = "serialize", feature = "bevy_reflect"),
103 reflect(Serialize, Deserialize)
104)]
105pub struct MouseMotion {
106 pub delta: Vec2,
108}
109
110#[derive(Debug, Hash, Clone, Copy, Eq, PartialEq)]
117#[cfg_attr(
118 feature = "bevy_reflect",
119 derive(Reflect),
120 reflect(Debug, PartialEq, Clone)
121)]
122#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
123#[cfg_attr(
124 all(feature = "serialize", feature = "bevy_reflect"),
125 reflect(Serialize, Deserialize)
126)]
127pub enum MouseScrollUnit {
128 Line,
133 Pixel,
138}
139
140#[derive(Event, Debug, Clone, Copy, PartialEq)]
144#[cfg_attr(
145 feature = "bevy_reflect",
146 derive(Reflect),
147 reflect(Debug, PartialEq, Clone)
148)]
149#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
150#[cfg_attr(
151 all(feature = "serialize", feature = "bevy_reflect"),
152 reflect(Serialize, Deserialize)
153)]
154pub struct MouseWheel {
155 pub unit: MouseScrollUnit,
157 pub x: f32,
159 pub y: f32,
161 pub window: Entity,
163}
164
165pub fn mouse_button_input_system(
172 mut mouse_button_input: ResMut<ButtonInput<MouseButton>>,
173 mut mouse_button_input_events: EventReader<MouseButtonInput>,
174) {
175 mouse_button_input.bypass_change_detection().clear();
176 for event in mouse_button_input_events.read() {
177 match event.state {
178 ButtonState::Pressed => mouse_button_input.press(event.button),
179 ButtonState::Released => mouse_button_input.release(event.button),
180 }
181 }
182}
183
184#[derive(Resource, Debug, Clone, Copy, PartialEq, Default)]
190#[cfg_attr(
191 feature = "bevy_reflect",
192 derive(Reflect),
193 reflect(Debug, Default, Resource, PartialEq, Clone)
194)]
195#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
196#[cfg_attr(
197 all(feature = "serialize", feature = "bevy_reflect"),
198 reflect(Serialize, Deserialize)
199)]
200pub struct AccumulatedMouseMotion {
201 pub delta: Vec2,
203}
204
205#[derive(Resource, Debug, Clone, Copy, PartialEq)]
211#[cfg_attr(
212 feature = "bevy_reflect",
213 derive(Reflect),
214 reflect(Debug, Default, Resource, PartialEq, Clone)
215)]
216#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
217#[cfg_attr(
218 all(feature = "serialize", feature = "bevy_reflect"),
219 reflect(Serialize, Deserialize)
220)]
221pub struct AccumulatedMouseScroll {
222 pub unit: MouseScrollUnit,
226 pub delta: Vec2,
228}
229
230impl Default for AccumulatedMouseScroll {
231 fn default() -> Self {
232 Self {
233 unit: MouseScrollUnit::Line,
234 delta: Vec2::ZERO,
235 }
236 }
237}
238
239pub fn accumulate_mouse_motion_system(
242 mut mouse_motion_event: EventReader<MouseMotion>,
243 mut accumulated_mouse_motion: ResMut<AccumulatedMouseMotion>,
244) {
245 let mut delta = Vec2::ZERO;
246 for event in mouse_motion_event.read() {
247 delta += event.delta;
248 }
249 accumulated_mouse_motion.delta = delta;
250}
251
252pub fn accumulate_mouse_scroll_system(
255 mut mouse_scroll_event: EventReader<MouseWheel>,
256 mut accumulated_mouse_scroll: ResMut<AccumulatedMouseScroll>,
257) {
258 let mut delta = Vec2::ZERO;
259 let mut unit = MouseScrollUnit::Line;
260 for event in mouse_scroll_event.read() {
261 if event.unit != unit {
262 unit = event.unit;
263 }
264 delta += Vec2::new(event.x, event.y);
265 }
266 accumulated_mouse_scroll.delta = delta;
267 accumulated_mouse_scroll.unit = unit;
268}