Files
NativeScript/packages/core/ui/gestures/gestures-common.ts
2023-08-11 07:09:32 -07:00

403 lines
8.2 KiB
TypeScript

import type { GesturesObserver as GesturesObserverDefinition } from '.';
import type { View } from '../core/view';
import type { EventData } from '../../data/observable';
export * from './touch-manager';
/**
* Events emitted during gesture lifecycle
*/
export enum GestureEvents {
/**
* When the gesture is attached to the view
* Provides access to the native gesture recognizer for further customization
*/
gestureAttached = 'gestureAttached',
/**
* When a touch down was detected
*/
touchDown = 'touchDown',
/**
* When a touch up was detected
*/
touchUp = 'touchUp',
}
/**
* Defines an enum with supported gesture types.
*/
export enum GestureTypes {
/**
* Denotes tap (click) gesture.
*/
tap = 1 << 0,
/**
* Denotes double tap gesture.
*/
doubleTap = 1 << 1,
/**
* Denotes pinch gesture.
*/
pinch = 1 << 2,
/**
* Denotes pan gesture.
*/
pan = 1 << 3,
/**
* Denotes swipe gesture.
*/
swipe = 1 << 4,
/**
* Denotes rotation gesture.
*/
rotation = 1 << 5,
/**
* Denotes long press gesture.
*/
longPress = 1 << 6,
/**
* Denotes touch action.
*/
touch = 1 << 7,
}
/**
* Defines an enum with supported gesture states.
*/
export enum GestureStateTypes {
/**
* Gesture canceled.
*/
cancelled,
/**
* Gesture began.
*/
began,
/**
* Gesture changed.
*/
changed,
/**
* Gesture ended.
*/
ended,
}
/**
* Defines an enum for swipe gesture direction.
*/
export enum SwipeDirection {
/**
* Denotes right direction for swipe gesture.
*/
right = 1 << 0,
/**
* Denotes left direction for swipe gesture.
*/
left = 1 << 1,
/**
* Denotes up direction for swipe gesture.
*/
up = 1 << 2,
/**
* Denotes down direction for swipe gesture.
*/
down = 1 << 3,
}
/**
* Defines a touch action
*/
export enum TouchAction {
/**
* Down action.
*/
down = 'down',
/**
* Up action.
*/
up = 'up',
/**
* Move action.
*/
move = 'move',
/**
* Cancel action.
*/
cancel = 'cancel',
}
/**
* Provides gesture event data.
*/
export interface GestureEventData extends EventData {
/**
* Gets the type of the gesture.
*/
type: GestureTypes;
/**
* Gets the view which originates the gesture.
*/
view: View;
/**
* Gets the underlying native iOS specific [UIGestureRecognizer](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIGestureRecognizer_Class/).
*/
ios: any /* UIGestureRecognizer */;
/**
* Gets the underlying native android specific [gesture detector](http://developer.android.com/reference/android/view/GestureDetector.html).
*/
android: any;
}
/**
* Provides gesture event data.
*/
export interface TapGestureEventData extends GestureEventData {
/**
* Gets the number of pointers in the event.
*/
getPointerCount(): number;
/**
* Gets the X coordinate of this event inside the view that triggered the event
*/
getX(): number;
/**
* Gets the Y coordinate of the event inside the view that triggered the event.
*/
getY(): number;
}
/**
* Provides gesture event data.
*/
export interface TouchGestureEventData extends TapGestureEventData {
/**
* Gets action of the touch. Possible values: 'up', 'move', 'down', 'cancel'
*/
action: 'up' | 'move' | 'down' | 'cancel';
/**
* Gets the pointers that triggered the event.
* Note: In Android there is aways only one active pointer.
*/
getActivePointers(): Array<Pointer>;
/**
* Gets all pointers.
*/
getAllPointers(): Array<Pointer>;
}
/**
* Pointer is an object representing a finger (or other object) that is touching the screen.
*/
export interface Pointer {
/**
* The id of the pointer.
*/
android: any;
/**
* The UITouch object associated to the touch
*/
ios: any;
/**
* Gets the X coordinate of the pointer inside the view that triggered the event.
*/
getX(): number;
/**
* Gets the Y coordinate of the pointer inside the view that triggered the event.
*/
getY(): number;
/**
* Gests the X coordinate of the pointer inside the view that triggered the event.
* @returns The X coordinate in _Device Pixels_.
*/
getXPixels(): number;
/**
* Gets the X coordinate of the pointer inside the view that triggered the event.
* @returns The X coordinate in _Device Independent Pixels_.
*/
getXDIP(): number;
/**
* Gests the Y coordinate of the pointer inside the view that triggered the event.
* @returns The Y coordinate in _Device Pixels_.
*/
getYPixels(): number;
/**
* Gets the Y coordinate of the pointer inside the view that triggered the event.
* @returns The Y coordinate in _Device Independent Pixels_.
*/
getYDIP(): number;
}
/**
* Provides gesture event data.
*/
export interface GestureEventDataWithState extends GestureEventData {
state: number;
}
/**
* Provides gesture event data for pinch gesture.
*/
export interface PinchGestureEventData extends GestureEventDataWithState {
scale: number;
getFocusX(): number;
getFocusY(): number;
}
/**
* Provides gesture event data for swipe gesture.
*/
export interface SwipeGestureEventData extends GestureEventData {
direction: SwipeDirection;
}
/**
* Provides gesture event data for pan gesture.
*/
export interface PanGestureEventData extends GestureEventDataWithState {
deltaX: number;
deltaY: number;
}
/**
* Provides gesture event data for rotation gesture.
*/
export interface RotationGestureEventData extends GestureEventDataWithState {
rotation: number;
}
/**
* Returns a string representation of a gesture type.
* @param type - Type of the gesture.
* @param separator(optional) - Text separator between gesture type strings.
*/
export function toString(type: GestureTypes, separator?: string): string {
const types = new Array<string>();
if (type & GestureTypes.tap) {
types.push('tap');
}
if (type & GestureTypes.doubleTap) {
types.push('doubleTap');
}
if (type & GestureTypes.pinch) {
types.push('pinch');
}
if (type & GestureTypes.pan) {
types.push('pan');
}
if (type & GestureTypes.swipe) {
types.push('swipe');
}
if (type & GestureTypes.rotation) {
types.push('rotation');
}
if (type & GestureTypes.longPress) {
types.push('longPress');
}
if (type & GestureTypes.touch) {
types.push('touch');
}
return types.join(separator);
}
// NOTE: toString could return the text of multiple GestureTypes.
// Souldn't fromString do split on separator and return multiple GestureTypes?
/**
* Returns a gesture type enum value from a string (case insensitive).
* @param type - A string representation of a gesture type (e.g. Tap).
*/
export function fromString(type: string): GestureTypes {
const t = type.trim().toLowerCase();
if (t === 'tap') {
return GestureTypes.tap;
} else if (t === 'doubletap') {
return GestureTypes.doubleTap;
} else if (t === 'pinch') {
return GestureTypes.pinch;
} else if (t === 'pan') {
return GestureTypes.pan;
} else if (t === 'swipe') {
return GestureTypes.swipe;
} else if (t === 'rotation') {
return GestureTypes.rotation;
} else if (t === 'longpress') {
return GestureTypes.longPress;
} else if (t === 'touch') {
return GestureTypes.touch;
}
return undefined;
}
export abstract class GesturesObserverBase implements GesturesObserverDefinition {
private _callback: (args: GestureEventData) => void;
private _target: View;
private _context: any;
public type: GestureTypes;
public get callback(): (args: GestureEventData) => void {
return this._callback;
}
public get target(): View {
return this._target;
}
public get context() {
return this._context;
}
constructor(target: View, callback: (args: GestureEventData) => void, context: any) {
this._target = target;
this._callback = callback;
this._context = context;
}
public abstract androidOnTouchEvent(motionEvent: android.view.MotionEvent);
public abstract observe(type: GestureTypes);
public disconnect() {
// remove gesture observer from map
if (this.target) {
const list = this.target.getGestureObservers(this.type);
if (list && list.length > 0) {
for (let i = 0; i < list.length; i++) {
if (list[i].callback === this.callback) {
break;
}
}
list.length = 0;
this.target._gestureObservers[this.type] = undefined;
delete this.target._gestureObservers[this.type];
}
}
this._target = null;
this._callback = null;
this._context = null;
}
}