Skip to content

Commit

Permalink
Merge pull request #17 from clinuxrulz/wasm-touch-v2
Browse files Browse the repository at this point in the history
Support both touch and mouse on same target platform (touch for Web Assembly target)
  • Loading branch information
SergioRibera authored Jan 26, 2024
2 parents 22c8696 + 22ff52a commit 0e8b924
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 26 deletions.
73 changes: 57 additions & 16 deletions src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(opt: Option<T>, cb: impl FnOnce(T) -> bool) -> bool {
Expand Down Expand Up @@ -49,7 +45,12 @@ pub fn update_input<S: VirtualJoystickID>(
}
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)
Expand All @@ -58,6 +59,7 @@ pub fn update_input<S: VirtualJoystickID>(
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,
Expand All @@ -67,7 +69,12 @@ pub fn update_input<S: VirtualJoystickID>(
});
}
}
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;
}
Expand All @@ -88,7 +95,16 @@ pub fn update_input<S: VirtualJoystickID>(
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;
}
Expand All @@ -97,6 +113,7 @@ pub fn update_input<S: VirtualJoystickID>(
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,
Expand Down Expand 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,
});
}
}
}
Expand All @@ -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,
});
}
}
13 changes: 3 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -47,17 +47,10 @@ impl<S: VirtualJoystickID> Plugin for VirtualJoystickPlugin<S> {
.register_type::<VirtualJoystickEventType>()
.add_event::<VirtualJoystickEvent<S>>()
.add_event::<InputEvent>()
.add_systems(PreUpdate, update_joystick.before(update_input::<S>))
.add_systems(
PreUpdate,
update_joystick
.before(update_input::<S>)
.run_if(not(run_if_pc)),
)
.add_systems(
PreUpdate,
update_joystick_by_mouse
.before(update_input::<S>)
.run_if(run_if_pc),
update_joystick_by_mouse.before(update_input::<S>),
)
.add_systems(PreUpdate, update_input::<S>)
.add_systems(
Expand Down
4 changes: 4 additions & 0 deletions src/ui/bundles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ pub struct VirtualJoystickData {
pub current_pos: Vec2,
pub delta: Vec2,
pub interactable_zone_rect: Rect,
/// None means no current interaction<br/>
/// Some(false) means current interaction is touch<br/>
/// Some(true) means current interaction is mouse
pub current_iteraction_is_mouse: Option<bool>,
}

impl<S: VirtualJoystickID> VirtualJoystickBundle<S> {
Expand Down

0 comments on commit 0e8b924

Please sign in to comment.