diff --git a/src/input.rs b/src/input.rs index 51af182..3c396df 100644 --- a/src/input.rs +++ b/src/input.rs @@ -10,15 +10,18 @@ use crate::{ VirtualJoystickType, }; -#[derive(Event)] -pub enum InputEvent { - StartDrag { id: u64, pos: Vec2 }, - Dragging { id: u64, pos: Vec2 }, - EndDrag { id: u64, pos: Vec2 }, +#[derive(Clone, Copy, Debug, Default, Reflect, PartialEq, Eq)] +pub enum TouchOrMouse { + #[default] + Touch, + Mouse, } -pub fn run_if_pc() -> bool { - !["android", "ios"].contains(&std::env::consts::OS) +#[derive(Event)] +pub enum InputEvent { + StartDrag { id: u64, pos: Vec2, touch_or_mouse: TouchOrMouse }, + Dragging { id: u64, pos: Vec2, touch_or_mouse: TouchOrMouse }, + EndDrag { id: u64, pos: Vec2, touch_or_mouse: TouchOrMouse }, } fn is_some_and(opt: Option, cb: impl FnOnce(T) -> bool) -> bool { @@ -49,7 +52,12 @@ pub fn update_input( } for event in &input_events { match event { - InputEvent::StartDrag { id, pos } => { + InputEvent::StartDrag { id, pos, touch_or_mouse } => { + if let Some(current_interaction_touch_or_mouse) = &knob.current_interaction_touch_or_mouse { + if *current_interaction_touch_or_mouse != *touch_or_mouse { + continue; + } + } if knob.interactable_zone_rect.contains(*pos) && knob.id_drag.is_none() || is_some_and(knob.id_drag, |i| i != *id) && knob.interactable_zone_rect.contains(*pos) @@ -58,6 +66,7 @@ pub fn update_input( knob.start_pos = *pos; knob.current_pos = *pos; knob.delta = Vec2::ZERO; + knob.current_interaction_touch_or_mouse = Some(*touch_or_mouse); send_values.send(VirtualJoystickEvent { id: node.id.clone(), event: VirtualJoystickEventType::Press, @@ -67,7 +76,12 @@ pub fn update_input( }); } } - InputEvent::Dragging { id, pos } => { + InputEvent::Dragging { id, pos, touch_or_mouse } => { + if let Some(current_interaction_touch_or_mouse) = &knob.current_interaction_touch_or_mouse { + if *current_interaction_touch_or_mouse != *touch_or_mouse { + continue; + } + } if !is_some_and(knob.id_drag, |i| i == *id) { continue; } @@ -88,7 +102,12 @@ pub fn update_input( d.y.signum() * d.y.abs().min(1.), ); } - InputEvent::EndDrag { id, pos: _ } => { + InputEvent::EndDrag { id, pos: _, touch_or_mouse } => { + if let Some(current_interaction_touch_or_mouse) = &knob.current_interaction_touch_or_mouse { + if *current_interaction_touch_or_mouse != *touch_or_mouse { + continue; + } + } if !is_some_and(knob.id_drag, |i| i == *id) { continue; } @@ -97,6 +116,7 @@ pub fn update_input( knob.start_pos = Vec2::ZERO; knob.current_pos = Vec2::ZERO; knob.delta = Vec2::ZERO; + knob.current_interaction_touch_or_mouse = None; send_values.send(VirtualJoystickEvent { id: node.id.clone(), event: VirtualJoystickEventType::Up, @@ -136,15 +156,15 @@ pub fn update_joystick( match phase { // Start drag TouchPhase::Started => { - send_values.send(InputEvent::StartDrag { id: *id, pos: *pos }); + send_values.send(InputEvent::StartDrag { id: *id, pos: *pos, touch_or_mouse: TouchOrMouse::Touch }); } // Dragging TouchPhase::Moved => { - send_values.send(InputEvent::Dragging { id: *id, pos: *pos }); + send_values.send(InputEvent::Dragging { id: *id, pos: *pos, touch_or_mouse: TouchOrMouse::Touch }); } // End drag TouchPhase::Ended | TouchPhase::Canceled => { - send_values.send(InputEvent::EndDrag { id: *id, pos: *pos }); + send_values.send(InputEvent::EndDrag { id: *id, pos: *pos, touch_or_mouse: TouchOrMouse::Touch }); } } } @@ -162,17 +182,17 @@ pub fn update_joystick_by_mouse( for mousebtn in mousebtn_evr.read() { // End drag if mousebtn.button == MouseButton::Left && mousebtn.state == ButtonState::Released { - send_values.send(InputEvent::EndDrag { id: 0, pos }); + send_values.send(InputEvent::EndDrag { id: 0, pos, touch_or_mouse: TouchOrMouse::Mouse }); } // Start drag if mousebtn.button == MouseButton::Left && mousebtn.state == ButtonState::Pressed { - send_values.send(InputEvent::StartDrag { id: 0, pos }); + send_values.send(InputEvent::StartDrag { id: 0, pos, touch_or_mouse: TouchOrMouse::Mouse }); } } // Dragging if mouse_button_input.pressed(MouseButton::Left) { - send_values.send(InputEvent::Dragging { id: 0, pos }); + send_values.send(InputEvent::Dragging { id: 0, pos, touch_or_mouse: TouchOrMouse::Mouse }); } } diff --git a/src/lib.rs b/src/lib.rs index 5eb1ff3..1d8102e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,7 @@ mod ui; mod utils; pub use behaviour::{VirtualJoystickAxis, VirtualJoystickType}; -use input::{run_if_pc, update_input, update_joystick, update_joystick_by_mouse, InputEvent}; +use input::{update_input, update_joystick, update_joystick_by_mouse, InputEvent}; pub use ui::{ VirtualJoystickBundle, VirtualJoystickInteractionArea, VirtualJoystickNode, VirtualJoystickUIBackground, VirtualJoystickUIKnob, @@ -50,14 +50,12 @@ impl Plugin for VirtualJoystickPlugin { .add_systems( PreUpdate, update_joystick - .before(update_input::) - .run_if(not(run_if_pc)), + .before(update_input::), ) .add_systems( PreUpdate, update_joystick_by_mouse - .before(update_input::) - .run_if(run_if_pc), + .before(update_input::), ) .add_systems(PreUpdate, update_input::) .add_systems( diff --git a/src/ui/bundles.rs b/src/ui/bundles.rs index 520b4ad..0b8f8a8 100644 --- a/src/ui/bundles.rs +++ b/src/ui/bundles.rs @@ -3,7 +3,7 @@ use bevy::{prelude::*, ui::RelativeCursorPosition}; #[cfg(feature = "inspect")] use bevy_inspector_egui::prelude::*; -use crate::{VirtualJoystickAxis, VirtualJoystickID, VirtualJoystickType}; +use crate::{input::TouchOrMouse, VirtualJoystickAxis, VirtualJoystickID, VirtualJoystickType}; #[derive(Component, Clone, Debug, Default, Reflect)] #[reflect(Component, Default)] @@ -70,6 +70,7 @@ pub struct VirtualJoystickData { pub current_pos: Vec2, pub delta: Vec2, pub interactable_zone_rect: Rect, + pub current_interaction_touch_or_mouse: Option, } impl VirtualJoystickBundle {