Skip to content

Commit

Permalink
support both touch and mouse on same target platform
Browse files Browse the repository at this point in the history
  • Loading branch information
clinuxrulz committed Jan 26, 2024
1 parent 22c8696 commit df90e44
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 22 deletions.
52 changes: 36 additions & 16 deletions src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>(opt: Option<T>, cb: impl FnOnce(T) -> bool) -> bool {
Expand Down Expand Up @@ -49,7 +52,12 @@ pub fn update_input<S: VirtualJoystickID>(
}
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)
Expand All @@ -58,6 +66,7 @@ pub fn update_input<S: VirtualJoystickID>(
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,
Expand All @@ -67,7 +76,12 @@ pub fn update_input<S: VirtualJoystickID>(
});
}
}
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;
}
Expand All @@ -88,7 +102,12 @@ pub fn update_input<S: VirtualJoystickID>(
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;
}
Expand All @@ -97,6 +116,7 @@ pub fn update_input<S: VirtualJoystickID>(
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,
Expand Down Expand 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 });
}
}
}
Expand All @@ -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 });
}
}
8 changes: 3 additions & 5 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 @@ -50,14 +50,12 @@ impl<S: VirtualJoystickID> Plugin for VirtualJoystickPlugin<S> {
.add_systems(
PreUpdate,
update_joystick
.before(update_input::<S>)
.run_if(not(run_if_pc)),
.before(update_input::<S>),
)
.add_systems(
PreUpdate,
update_joystick_by_mouse
.before(update_input::<S>)
.run_if(run_if_pc),
.before(update_input::<S>),
)
.add_systems(PreUpdate, update_input::<S>)
.add_systems(
Expand Down
3 changes: 2 additions & 1 deletion src/ui/bundles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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<TouchOrMouse>,
}

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

0 comments on commit df90e44

Please sign in to comment.