diff --git a/src/input.rs b/src/input.rs index 51af182..e1ce94a 100644 --- a/src/input.rs +++ b/src/input.rs @@ -12,13 +12,9 @@ use crate::{ #[derive(Event)] pub enum InputEvent { - StartDrag { id: u64, pos: Vec2 }, - Dragging { id: u64, pos: Vec2 }, - EndDrag { id: u64, pos: Vec2 }, -} - -pub fn run_if_pc() -> bool { - !["android", "ios"].contains(&std::env::consts::OS) + StartDrag { id: u64, pos: Vec2, is_mouse: bool }, + Dragging { id: u64, pos: Vec2, is_mouse: bool }, + EndDrag { id: u64, pos: Vec2, is_mouse: bool }, } fn is_some_and(opt: Option, cb: impl FnOnce(T) -> bool) -> bool { @@ -49,7 +45,12 @@ pub fn update_input( } for event in &input_events { match event { - InputEvent::StartDrag { id, pos } => { + InputEvent::StartDrag { id, pos, is_mouse } => { + if let Some(current_iteraction_is_mouse) = &knob.current_iteraction_is_mouse { + if *current_iteraction_is_mouse != *is_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 +59,7 @@ pub fn update_input( knob.start_pos = *pos; knob.current_pos = *pos; knob.delta = Vec2::ZERO; + knob.current_iteraction_is_mouse = Some(*is_mouse); send_values.send(VirtualJoystickEvent { id: node.id.clone(), event: VirtualJoystickEventType::Press, @@ -67,7 +69,12 @@ pub fn update_input( }); } } - InputEvent::Dragging { id, pos } => { + InputEvent::Dragging { id, pos, is_mouse } => { + if let Some(current_iteraction_is_mouse) = &knob.current_iteraction_is_mouse { + if *current_iteraction_is_mouse != *is_mouse { + continue; + } + } if !is_some_and(knob.id_drag, |i| i == *id) { continue; } @@ -88,7 +95,16 @@ pub fn update_input( d.y.signum() * d.y.abs().min(1.), ); } - InputEvent::EndDrag { id, pos: _ } => { + InputEvent::EndDrag { + id, + pos: _, + is_mouse, + } => { + if let Some(current_iteraction_is_mouse) = &knob.current_iteraction_is_mouse { + if *current_iteraction_is_mouse != *is_mouse { + continue; + } + } if !is_some_and(knob.id_drag, |i| i == *id) { continue; } @@ -97,6 +113,7 @@ pub fn update_input( knob.start_pos = Vec2::ZERO; knob.current_pos = Vec2::ZERO; knob.delta = Vec2::ZERO; + knob.current_iteraction_is_mouse = None; send_values.send(VirtualJoystickEvent { id: node.id.clone(), event: VirtualJoystickEventType::Up, @@ -136,15 +153,27 @@ 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, + is_mouse: false, + }); } // Dragging TouchPhase::Moved => { - send_values.send(InputEvent::Dragging { id: *id, pos: *pos }); + send_values.send(InputEvent::Dragging { + id: *id, + pos: *pos, + is_mouse: false, + }); } // End drag TouchPhase::Ended | TouchPhase::Canceled => { - send_values.send(InputEvent::EndDrag { id: *id, pos: *pos }); + send_values.send(InputEvent::EndDrag { + id: *id, + pos: *pos, + is_mouse: false, + }); } } } @@ -162,17 +191,29 @@ 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, + is_mouse: true, + }); } // 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, + is_mouse: true, + }); } } // Dragging if mouse_button_input.pressed(MouseButton::Left) { - send_values.send(InputEvent::Dragging { id: 0, pos }); + send_values.send(InputEvent::Dragging { + id: 0, + pos, + is_mouse: true, + }); } } diff --git a/src/lib.rs b/src/lib.rs index 5eb1ff3..85c8222 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, @@ -47,17 +47,10 @@ impl Plugin for VirtualJoystickPlugin { .register_type::() .add_event::>() .add_event::() + .add_systems(PreUpdate, update_joystick.before(update_input::)) .add_systems( PreUpdate, - update_joystick - .before(update_input::) - .run_if(not(run_if_pc)), - ) - .add_systems( - PreUpdate, - update_joystick_by_mouse - .before(update_input::) - .run_if(run_if_pc), + update_joystick_by_mouse.before(update_input::), ) .add_systems(PreUpdate, update_input::) .add_systems( diff --git a/src/ui/bundles.rs b/src/ui/bundles.rs index 520b4ad..a29f02b 100644 --- a/src/ui/bundles.rs +++ b/src/ui/bundles.rs @@ -70,6 +70,10 @@ pub struct VirtualJoystickData { pub current_pos: Vec2, pub delta: Vec2, pub interactable_zone_rect: Rect, + /// None means no current interaction
+ /// Some(false) means current interaction is touch
+ /// Some(true) means current interaction is mouse + pub current_iteraction_is_mouse: Option, } impl VirtualJoystickBundle {