use crate::{ButtonInput, ButtonState};
use bevy_ecs::{
change_detection::DetectChangesMut,
entity::Entity,
event::{BufferedEvent, EventReader},
resource::Resource,
system::ResMut,
};
use bevy_math::Vec2;
#[cfg(feature = "bevy_reflect")]
use {
bevy_ecs::reflect::ReflectResource,
bevy_reflect::{std_traits::ReflectDefault, Reflect},
};
#[cfg(all(feature = "serialize", feature = "bevy_reflect"))]
use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Debug, PartialEq, Clone)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct MouseButtonInput {
pub button: MouseButton,
pub state: ButtonState,
pub window: Entity,
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Debug, Hash, PartialEq, Clone)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub enum MouseButton {
Left,
Right,
Middle,
Back,
Forward,
Other(u16),
}
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Debug, PartialEq, Clone)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct MouseMotion {
pub delta: Vec2,
}
#[derive(Debug, Hash, Clone, Copy, Eq, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Debug, PartialEq, Clone)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub enum MouseScrollUnit {
Line,
Pixel,
}
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Debug, PartialEq, Clone)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct MouseWheel {
pub unit: MouseScrollUnit,
pub x: f32,
pub y: f32,
pub window: Entity,
}
pub fn mouse_button_input_system(
mut mouse_button_input: ResMut<ButtonInput<MouseButton>>,
mut mouse_button_input_events: EventReader<MouseButtonInput>,
) {
mouse_button_input.bypass_change_detection().clear();
for event in mouse_button_input_events.read() {
match event.state {
ButtonState::Pressed => mouse_button_input.press(event.button),
ButtonState::Released => mouse_button_input.release(event.button),
}
}
}
#[derive(Resource, Debug, Clone, Copy, PartialEq, Default)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Debug, Default, Resource, PartialEq, Clone)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct AccumulatedMouseMotion {
pub delta: Vec2,
}
#[derive(Resource, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Debug, Default, Resource, PartialEq, Clone)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct AccumulatedMouseScroll {
pub unit: MouseScrollUnit,
pub delta: Vec2,
}
impl Default for AccumulatedMouseScroll {
fn default() -> Self {
Self {
unit: MouseScrollUnit::Line,
delta: Vec2::ZERO,
}
}
}
pub fn accumulate_mouse_motion_system(
mut mouse_motion_event: EventReader<MouseMotion>,
mut accumulated_mouse_motion: ResMut<AccumulatedMouseMotion>,
) {
let mut delta = Vec2::ZERO;
for event in mouse_motion_event.read() {
delta += event.delta;
}
accumulated_mouse_motion.delta = delta;
}
pub fn accumulate_mouse_scroll_system(
mut mouse_scroll_event: EventReader<MouseWheel>,
mut accumulated_mouse_scroll: ResMut<AccumulatedMouseScroll>,
) {
let mut delta = Vec2::ZERO;
let mut unit = MouseScrollUnit::Line;
for event in mouse_scroll_event.read() {
if event.unit != unit {
unit = event.unit;
}
delta += Vec2::new(event.x, event.y);
}
accumulated_mouse_scroll.delta = delta;
accumulated_mouse_scroll.unit = unit;
}