Add touch pressure information for touch events on iOS (#1090)
* Add touch pressure information for touch events on iOS * Add a variant for calibrated touch pressure
This commit is contained in:
parent
8e73287646
commit
1366dc326a
10 changed files with 131 additions and 14 deletions
88
src/event.rs
88
src/event.rs
|
|
@ -303,30 +303,94 @@ pub enum TouchPhase {
|
|||
Cancelled,
|
||||
}
|
||||
|
||||
/// Represents touch event
|
||||
/// Represents a touch event
|
||||
///
|
||||
/// Every time user touches screen new Start event with some finger id is generated.
|
||||
/// When the finger is removed from the screen End event with same id is generated.
|
||||
/// Every time the user touches the screen, a new `Start` event with an unique
|
||||
/// identifier for the finger is generated. When the finger is lifted, an `End`
|
||||
/// event is generated with the same finger id.
|
||||
///
|
||||
/// For every id there will be at least 2 events with phases Start and End (or Cancelled).
|
||||
/// There may be 0 or more Move events.
|
||||
/// After a `Start` event has been emitted, there may be zero or more `Move`
|
||||
/// events when the finger is moved or the touch pressure changes.
|
||||
///
|
||||
/// The finger id may be reused by the system after an `End` event. The user
|
||||
/// should assume that a new `Start` event received with the same id has nothing
|
||||
/// to do with the old finger and is a new finger.
|
||||
///
|
||||
/// Depending on platform implementation id may or may not be reused by system after End event.
|
||||
///
|
||||
/// Gesture regonizer using this event should assume that Start event received with same id
|
||||
/// as previously received End event is a new finger and has nothing to do with an old one.
|
||||
///
|
||||
/// Touch may be cancelled if for example window lost focus.
|
||||
/// A `Cancelled` event is emitted when the system has canceled tracking this
|
||||
/// touch, such as when the window loses focus, or on iOS if the user moves the
|
||||
/// device against their face.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Touch {
|
||||
pub device_id: DeviceId,
|
||||
pub phase: TouchPhase,
|
||||
pub location: LogicalPosition,
|
||||
/// unique identifier of a finger.
|
||||
/// Describes how hard the screen was pressed. May be `None` if the platform
|
||||
/// does not support pressure sensitivity.
|
||||
///
|
||||
/// ## Platform-specific
|
||||
///
|
||||
/// - Only available on **iOS**.
|
||||
pub force: Option<Force>,
|
||||
/// Unique identifier of a finger.
|
||||
pub id: u64,
|
||||
}
|
||||
|
||||
/// Describes the force of a touch event
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Force {
|
||||
/// On iOS, the force is calibrated so that the same number corresponds to
|
||||
/// roughly the same amount of pressure on the screen regardless of the
|
||||
/// device.
|
||||
Calibrated {
|
||||
/// The force of the touch, where a value of 1.0 represents the force of
|
||||
/// an average touch (predetermined by the system, not user-specific).
|
||||
///
|
||||
/// The force reported by Apple Pencil is measured along the axis of the
|
||||
/// pencil. If you want a force perpendicular to the device, you need to
|
||||
/// calculate this value using the `altitude_angle` value.
|
||||
force: f64,
|
||||
/// The maximum possible force for a touch.
|
||||
///
|
||||
/// The value of this field is sufficiently high to provide a wide
|
||||
/// dynamic range for values of the `force` field.
|
||||
max_possible_force: f64,
|
||||
/// The altitude (in radians) of the stylus.
|
||||
///
|
||||
/// A value of 0 radians indicates that the stylus is parallel to the
|
||||
/// surface. The value of this property is Pi/2 when the stylus is
|
||||
/// perpendicular to the surface.
|
||||
altitude_angle: Option<f64>,
|
||||
},
|
||||
/// If the platform reports the force as normalized, we have no way of
|
||||
/// knowing how much pressure 1.0 corresponds to – we know it's the maximum
|
||||
/// amount of force, but as to how much force, you might either have to
|
||||
/// press really really hard, or not hard at all, depending on the device.
|
||||
Normalized(f64),
|
||||
}
|
||||
|
||||
impl Force {
|
||||
/// Returns the force normalized to the range between 0.0 and 1.0 inclusive.
|
||||
/// Instead of normalizing the force, you should prefer to handle
|
||||
/// `Force::Calibrated` so that the amount of force the user has to apply is
|
||||
/// consistent across devices.
|
||||
pub fn normalized(&self) -> f64 {
|
||||
match self {
|
||||
Force::Calibrated {
|
||||
force,
|
||||
max_possible_force,
|
||||
altitude_angle,
|
||||
} => {
|
||||
let force = match altitude_angle {
|
||||
Some(altitude_angle) => force / altitude_angle.sin(),
|
||||
None => *force,
|
||||
};
|
||||
force / max_possible_force
|
||||
}
|
||||
Force::Normalized(force) => *force,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Hardware-dependent keyboard scan code.
|
||||
pub type ScanCode = u32;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue