-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement basic touch support #334
Conversation
IMO I think going with struct names based on "Touch" makes more sense than "Finger." Because touch input can include things like stylus and pen tablets, it would be strange to call them fingers. |
I don't know, but could you use #59 Axis API for the finger position? Or is it too different? |
+1 on calling it touch. Btw I didn't realise this PR exists and duplicated some efforts here #87 (comment) Perhaps it may be of interest. I actually implemented an alternative to
Perhaps is what I did in my link closer to what you're looking for? Rather than a raw event stream. |
app.resources.get_mut::<Events<TouchFingerInput>>().unwrap(); | ||
touch_finger_input_events.send(converters::convert_touch_input( | ||
ElementState::Released, | ||
&touch, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we should be mapping Cancelled
to Released
. The Input
abstraction as it stands doesn't map well to touch. I think either we extend Input
or create a different abstraction for touch... I think I personally would prefer the latter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this. We should mirror the winit TouchPhase enum in the bevy events.
// This system prints messages when you use the touchscreen | ||
fn touch_system(finger_input: Res<Input<Finger>>) { | ||
if finger_input.pressed(Finger(0)) { | ||
println!("finger 0 pressed"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not 100% sure this works on all platforms? For example on iOS I was getting huge numbers, not 0 and 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think we should assume that a "touch id" is an opaque identifier.
@@ -192,6 +193,64 @@ pub fn winit_runner(mut app: App) { | |||
}); | |||
} | |||
}, | |||
WindowEvent::Touch( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think its much more legible to compress these into a single match arm, then have a second match inside:
WindowEvent::Touch(touch) => match touch.phase {
TouchPhase::Started => {
let mut touch_finger_input_events =
app.resources.get_mut::<Events<TouchFingerInput>>().unwrap();
touch_finger_input_events.send(converters::convert_touch_input(
ElementState::Pressed,
&touch,
));
}
TouchPhase::Ended => {
let mut touch_finger_input_events =
app.resources.get_mut::<Events<TouchFingerInput>>().unwrap();
touch_finger_input_events.send(converters::convert_touch_input(
ElementState::Released,
&touch,
));
}
TouchPhase::Cancelled => {
let mut touch_finger_input_events =
app.resources.get_mut::<Events<TouchFingerInput>>().unwrap();
touch_finger_input_events.send(converters::convert_touch_input(
ElementState::Released,
&touch,
));
}
TouchPhase::Moved => {
let mut touch_finger_moved_events =
app.resources.get_mut::<Events<TouchMotion>>().unwrap();
touch_finger_moved_events.send(TouchMotion {
finger: Finger(touch.id),
position: Vec2::new(touch.location.x as f32, touch.location.y as f32),
});
}
},
app.resources.get_mut::<Events<TouchFingerInput>>().unwrap(); | ||
touch_finger_input_events.send(converters::convert_touch_input( | ||
ElementState::Released, | ||
&touch, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this. We should mirror the winit TouchPhase enum in the bevy events.
/// A finger on a touch screen device | ||
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] | ||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] | ||
pub struct Finger(pub u64); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think I would prefer it if we didn't call this finger. I think TouchId is a more generic term
// This system prints messages when you use the touchscreen | ||
fn touch_system(finger_input: Res<Input<Finger>>) { | ||
if finger_input.pressed(Finger(0)) { | ||
println!("finger 0 pressed"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think we should assume that a "touch id" is an opaque identifier.
} | ||
|
||
/// Updates the Input<Finger> resource with the latest TouchFingerInput events | ||
pub fn touch_finger_input_system( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As nice as this api is to consume, I think we should remove Input<Finger>
for now. Touch events might need their own abstraction because they have more state to track and TouchId might be unstable / hard to know ahead of time.
@TomBebb are you planning on updating this? Otherwise myself or others could help push this along.
I think so yes. In my iOS bevy project I store start and current positions and use distance from the start position for virtual joysticks. If the joystick is moved past some "max" distance, the joystick itself then starts to move around the screen. |
Closed in favor of #696 |
Hi guys, first proper pull request!
This implements touch motion and finger pressing using winit API - see bug #300
I couldn't decide on finger vs touch in struct names, I am happy to refactor code if anyone has better ideas for names
Is it worth storing last finger positions so we can give delta in finger motion events like we do in mouse motion events?