1use crate::{ButtonInput, ButtonState};
4use bevy_ecs::{
5 change_detection::DetectChangesMut,
6 entity::Entity,
7 message::{Message, MessageReader},
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(Message, 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(Message, 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
140impl MouseScrollUnit {
141 pub const SCROLL_UNIT_CONVERSION_FACTOR: f32 = 100.;
150}
151
152#[derive(Message, Debug, Clone, Copy, PartialEq)]
156#[cfg_attr(
157 feature = "bevy_reflect",
158 derive(Reflect),
159 reflect(Debug, PartialEq, Clone)
160)]
161#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
162#[cfg_attr(
163 all(feature = "serialize", feature = "bevy_reflect"),
164 reflect(Serialize, Deserialize)
165)]
166pub struct MouseWheel {
167 pub unit: MouseScrollUnit,
169 pub x: f32,
171 pub y: f32,
173 pub window: Entity,
175}
176
177pub fn mouse_button_input_system(
184 mut mouse_button_input: ResMut<ButtonInput<MouseButton>>,
185 mut mouse_button_input_events: MessageReader<MouseButtonInput>,
186) {
187 mouse_button_input.bypass_change_detection().clear();
188 for event in mouse_button_input_events.read() {
189 match event.state {
190 ButtonState::Pressed => mouse_button_input.press(event.button),
191 ButtonState::Released => mouse_button_input.release(event.button),
192 }
193 }
194}
195
196#[derive(Resource, Debug, Clone, Copy, PartialEq, Default)]
202#[cfg_attr(
203 feature = "bevy_reflect",
204 derive(Reflect),
205 reflect(Debug, Default, Resource, PartialEq, Clone)
206)]
207#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
208#[cfg_attr(
209 all(feature = "serialize", feature = "bevy_reflect"),
210 reflect(Serialize, Deserialize)
211)]
212pub struct AccumulatedMouseMotion {
213 pub delta: Vec2,
215}
216
217#[derive(Resource, Debug, Clone, Copy, PartialEq)]
223#[cfg_attr(
224 feature = "bevy_reflect",
225 derive(Reflect),
226 reflect(Debug, Default, Resource, PartialEq, Clone)
227)]
228#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
229#[cfg_attr(
230 all(feature = "serialize", feature = "bevy_reflect"),
231 reflect(Serialize, Deserialize)
232)]
233pub struct AccumulatedMouseScroll {
234 pub unit: MouseScrollUnit,
238 pub delta: Vec2,
240}
241
242impl Default for AccumulatedMouseScroll {
243 fn default() -> Self {
244 Self {
245 unit: MouseScrollUnit::Line,
246 delta: Vec2::ZERO,
247 }
248 }
249}
250
251pub fn accumulate_mouse_motion_system(
254 mut mouse_motion_event: MessageReader<MouseMotion>,
255 mut accumulated_mouse_motion: ResMut<AccumulatedMouseMotion>,
256) {
257 let mut delta = Vec2::ZERO;
258 for event in mouse_motion_event.read() {
259 delta += event.delta;
260 }
261 accumulated_mouse_motion.delta = delta;
262}
263
264pub fn accumulate_mouse_scroll_system(
267 mut mouse_scroll_event: MessageReader<MouseWheel>,
268 mut accumulated_mouse_scroll: ResMut<AccumulatedMouseScroll>,
269) {
270 let mut delta = Vec2::ZERO;
271 let mut unit = MouseScrollUnit::Line;
272 for event in mouse_scroll_event.read() {
273 if event.unit != unit {
274 unit = event.unit;
275 }
276 delta += Vec2::new(event.x, event.y);
277 }
278 accumulated_mouse_scroll.delta = delta;
279 accumulated_mouse_scroll.unit = unit;
280}