1use crate::{touch::TouchPhase, ButtonInput, ButtonState};
4#[cfg(feature = "bevy_reflect")]
5use bevy_ecs::prelude::ReflectMessage;
6use bevy_ecs::{
7 change_detection::DetectChangesMut,
8 entity::Entity,
9 message::{Message, MessageReader},
10 resource::Resource,
11 system::ResMut,
12};
13use bevy_math::Vec2;
14#[cfg(feature = "bevy_reflect")]
15use {
16 bevy_ecs::reflect::ReflectResource,
17 bevy_reflect::{std_traits::ReflectDefault, Reflect},
18};
19
20#[cfg(all(feature = "serialize", feature = "bevy_reflect"))]
21use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
22
23#[derive(Message, Debug, Clone, Copy, PartialEq, Eq)]
32#[cfg_attr(
33 feature = "bevy_reflect",
34 derive(Reflect),
35 reflect(Debug, PartialEq, Clone, Message)
36)]
37#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
38#[cfg_attr(
39 all(feature = "serialize", feature = "bevy_reflect"),
40 reflect(Serialize, Deserialize)
41)]
42pub struct MouseButtonInput {
43 pub button: MouseButton,
45 pub state: ButtonState,
47 pub window: Entity,
49}
50
51#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
62#[cfg_attr(
63 feature = "bevy_reflect",
64 derive(Reflect),
65 reflect(Debug, Hash, PartialEq, Clone)
66)]
67#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
68#[cfg_attr(
69 all(feature = "serialize", feature = "bevy_reflect"),
70 reflect(Serialize, Deserialize)
71)]
72pub enum MouseButton {
73 Left,
75 Right,
77 Middle,
79 Back,
81 Forward,
83 Other(u16),
85}
86
87#[derive(Message, Debug, Clone, Copy, PartialEq)]
97#[cfg_attr(
98 feature = "bevy_reflect",
99 derive(Reflect),
100 reflect(Debug, PartialEq, Clone, Message)
101)]
102#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
103#[cfg_attr(
104 all(feature = "serialize", feature = "bevy_reflect"),
105 reflect(Serialize, Deserialize)
106)]
107pub struct MouseMotion {
108 pub delta: Vec2,
110}
111
112#[derive(Debug, Hash, Clone, Copy, Eq, PartialEq)]
119#[cfg_attr(
120 feature = "bevy_reflect",
121 derive(Reflect),
122 reflect(Debug, PartialEq, Clone)
123)]
124#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
125#[cfg_attr(
126 all(feature = "serialize", feature = "bevy_reflect"),
127 reflect(Serialize, Deserialize)
128)]
129pub enum MouseScrollUnit {
130 Line,
135 Pixel,
140}
141
142impl MouseScrollUnit {
143 pub const SCROLL_UNIT_CONVERSION_FACTOR: f32 = 100.;
152}
153
154#[derive(Message, Debug, Clone, Copy, PartialEq)]
158#[cfg_attr(
159 feature = "bevy_reflect",
160 derive(Reflect),
161 reflect(Debug, PartialEq, Clone, Message)
162)]
163#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
164#[cfg_attr(
165 all(feature = "serialize", feature = "bevy_reflect"),
166 reflect(Serialize, Deserialize)
167)]
168pub struct MouseWheel {
169 pub unit: MouseScrollUnit,
171 pub x: f32,
173 pub y: f32,
175 pub window: Entity,
177 pub phase: TouchPhase,
181}
182
183pub fn mouse_button_input_system(
190 mut mouse_button_input: ResMut<ButtonInput<MouseButton>>,
191 mut mouse_button_input_events: MessageReader<MouseButtonInput>,
192) {
193 mouse_button_input.bypass_change_detection().clear();
194 for event in mouse_button_input_events.read() {
195 match event.state {
196 ButtonState::Pressed => mouse_button_input.press(event.button),
197 ButtonState::Released => mouse_button_input.release(event.button),
198 }
199 }
200}
201
202#[derive(Resource, Debug, Clone, Copy, PartialEq, Default)]
208#[cfg_attr(
209 feature = "bevy_reflect",
210 derive(Reflect),
211 reflect(Debug, Default, Resource, PartialEq, Clone)
212)]
213#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
214#[cfg_attr(
215 all(feature = "serialize", feature = "bevy_reflect"),
216 reflect(Serialize, Deserialize)
217)]
218pub struct AccumulatedMouseMotion {
219 pub delta: Vec2,
221}
222
223#[derive(Resource, Debug, Clone, Copy, PartialEq)]
229#[cfg_attr(
230 feature = "bevy_reflect",
231 derive(Reflect),
232 reflect(Debug, Default, Resource, PartialEq, Clone)
233)]
234#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
235#[cfg_attr(
236 all(feature = "serialize", feature = "bevy_reflect"),
237 reflect(Serialize, Deserialize)
238)]
239pub struct AccumulatedMouseScroll {
240 pub unit: MouseScrollUnit,
244 pub delta: Vec2,
246}
247
248impl Default for AccumulatedMouseScroll {
249 fn default() -> Self {
250 Self {
251 unit: MouseScrollUnit::Line,
252 delta: Vec2::ZERO,
253 }
254 }
255}
256
257pub fn accumulate_mouse_motion_system(
260 mut mouse_motion_event: MessageReader<MouseMotion>,
261 mut accumulated_mouse_motion: ResMut<AccumulatedMouseMotion>,
262) {
263 let mut delta = Vec2::ZERO;
264 for event in mouse_motion_event.read() {
265 delta += event.delta;
266 }
267 accumulated_mouse_motion.delta = delta;
268}
269
270pub fn accumulate_mouse_scroll_system(
273 mut mouse_scroll_event: MessageReader<MouseWheel>,
274 mut accumulated_mouse_scroll: ResMut<AccumulatedMouseScroll>,
275) {
276 let mut delta = Vec2::ZERO;
277 let mut unit = MouseScrollUnit::Line;
278 for event in mouse_scroll_event.read() {
279 if event.unit != unit {
280 unit = event.unit;
281 }
282 delta += Vec2::new(event.x, event.y);
283 }
284 accumulated_mouse_scroll.delta = delta;
285 accumulated_mouse_scroll.unit = unit;
286}