|
|
|
|
|
|
using UnityEngine; |
|
|
|
|
|
|
|
namespace Unity.UIWidgets.gestures { |
|
|
|
|
|
|
|
enum _ScaleState { |
|
|
|
ready, |
|
|
|
possible, |
|
|
|
|
|
|
public ScaleStartDetails(Offset focalPoint = null) { |
|
|
|
this.focalPoint = focalPoint ?? Offset.zero; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public readonly Offset focalPoint; |
|
|
|
|
|
|
|
public override string ToString() { |
|
|
|
|
|
|
float rotation = 0.0f |
|
|
|
) { |
|
|
|
focalPoint = focalPoint ?? Offset.zero; |
|
|
|
|
|
|
|
|
|
|
|
D.assert(scale >= 0.0f); |
|
|
|
D.assert(horizontalScale >= 0.0f); |
|
|
|
D.assert(verticalScale >= 0.0f); |
|
|
|
|
|
|
this.verticalScale = verticalScale; |
|
|
|
this.rotation = rotation; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public readonly Offset focalPoint; |
|
|
|
|
|
|
|
public readonly float scale; |
|
|
|
|
|
|
public readonly float rotation; |
|
|
|
|
|
|
|
public override string ToString() { |
|
|
|
return $"ScaleUpdateDetails(focalPoint: {this.focalPoint}, scale: {this.scale}, horizontalScale: {this.horizontalScale}, verticalScale: {this.verticalScale}, rotation: {this.rotation}"; |
|
|
|
return |
|
|
|
$"ScaleUpdateDetails(focalPoint: {this.focalPoint}, scale: {this.scale}, horizontalScale: {this.horizontalScale}, verticalScale: {this.verticalScale}, rotation: {this.rotation}"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public readonly Velocity velocity; |
|
|
|
|
|
|
|
public override string ToString() { |
|
|
|
|
|
|
int pointerEndId = 1) { |
|
|
|
pointerStartLocation = pointerEndLocation ?? Offset.zero; |
|
|
|
pointerEndLocation = pointerEndLocation ?? Offset.zero; |
|
|
|
|
|
|
|
|
|
|
|
D.assert(pointerStartId != pointerEndId); |
|
|
|
|
|
|
|
this.pointerStartLocation = pointerStartLocation; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public readonly Offset pointerStartLocation; |
|
|
|
|
|
|
|
public readonly int pointerStartId; |
|
|
|
|
|
|
|
|
|
|
class ScaleGestureRecognizer : OneSequenceGestureRecognizer { |
|
|
|
public ScaleGestureRecognizer(object debugOwner) : base(debugOwner: debugOwner) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Offset _initialFocalPoint; |
|
|
|
Offset _currentFocalPoint; |
|
|
|
float _initialSpan; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
float _horizontalScaleFactor { |
|
|
|
get { return this._initialHorizontalSpan > 0.0f ? this._currentHorizontalSpan / this._initialHorizontalSpan : 1.0f; } |
|
|
|
get { |
|
|
|
return this._initialHorizontalSpan > 0.0f |
|
|
|
? this._currentHorizontalSpan / this._initialHorizontalSpan |
|
|
|
: 1.0f; |
|
|
|
} |
|
|
|
get { return this._initialVerticalSpan > 0.0f ? this._currentVerticalSpan / this._initialVerticalSpan : 1.0f; } |
|
|
|
get { |
|
|
|
return this._initialVerticalSpan > 0.0f ? this._currentVerticalSpan / this._initialVerticalSpan : 1.0f; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float fx = this._initialLine.pointerStartLocation.dx; |
|
|
|
float fy = this._initialLine.pointerStartLocation.dy; |
|
|
|
float sx = this._initialLine.pointerEndLocation.dx; |
|
|
|
|
|
|
|
|
|
|
return angle2 - angle1; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void addAllowedPointer(PointerDownEvent evt) { |
|
|
|
this.startTrackingPointer(evt.pointer); |
|
|
|
this._velocityTrackers[evt.pointer] = new VelocityTracker(); |
|
|
|
|
|
|
this._pointerQueue = new List<int>(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (evt is PointerMoveEvent) { |
|
|
|
VelocityTracker tracker = this._velocityTrackers[evt.pointer]; |
|
|
|
D.assert(tracker != null); |
|
|
|
|
|
|
|
|
|
|
this._pointerLocations[evt.pointer] = evt.position; |
|
|
|
shouldStartIfAccepted = true; |
|
|
|
} else if (evt is PointerDownEvent) { |
|
|
|
} |
|
|
|
else if (evt is PointerDownEvent) { |
|
|
|
} else if (evt is PointerUpEvent || evt is PointerCancelEvent) { |
|
|
|
} |
|
|
|
else if (evt is PointerUpEvent || evt is PointerCancelEvent) { |
|
|
|
this._pointerLocations.Remove(evt.pointer); |
|
|
|
this._pointerQueue.Remove(evt.pointer); |
|
|
|
didChangeConfiguration = true; |
|
|
|
|
|
|
|
|
|
|
this.stopTrackingIfPointerNoLongerDown(evt); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void _update() { |
|
|
|
int count = this._pointerLocations.Keys.Count; |
|
|
|
|
|
|
|
|
|
|
float totalDeviation = 0.0f; |
|
|
|
float totalHorizontalDeviation = 0.0f; |
|
|
|
float totalVerticalDeviation = 0.0f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else if (this._initialLine != null && |
|
|
|
this._initialLine.pointerStartId == this._pointerQueue[0] && |
|
|
|
this._initialLine.pointerEndId == this._pointerQueue[1]) { |
|
|
|
} |
|
|
|
else if (this._initialLine != null && |
|
|
|
this._initialLine.pointerStartId == this._pointerQueue[0] && |
|
|
|
this._initialLine.pointerEndId == this._pointerQueue[1]) { |
|
|
|
this._currentLine = new _LineBetweenPointers( |
|
|
|
pointerStartId: this._pointerQueue[0], |
|
|
|
pointerStartLocation: this._pointerLocations[this._pointerQueue[0]], |
|
|
|
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
this._initialLine = new _LineBetweenPointers( |
|
|
|
pointerStartId: this._pointerQueue[0], |
|
|
|
pointerStartLocation: this._pointerLocations[this._pointerQueue[0]], |
|
|
|
|
|
|
this._currentLine = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool _reconfigure(int pointer) { |
|
|
|
this._initialFocalPoint = this._currentFocalPoint; |
|
|
|
this._initialSpan = this._currentSpan; |
|
|
|
|
|
|
Velocity velocity = tracker.getVelocity(); |
|
|
|
if (_ScaleGestureUtils._isFlingGesture(velocity)) { |
|
|
|
Offset pixelsPerSecond = velocity.pixelsPerSecond; |
|
|
|
if (pixelsPerSecond.distanceSquared > Constants.kMaxFlingVelocity * Constants.kMaxFlingVelocity) |
|
|
|
velocity = new Velocity(pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * Constants.kMaxFlingVelocity); |
|
|
|
if (pixelsPerSecond.distanceSquared > |
|
|
|
Constants.kMaxFlingVelocity * Constants.kMaxFlingVelocity) { |
|
|
|
velocity = new Velocity( |
|
|
|
pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * |
|
|
|
Constants.kMaxFlingVelocity); |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
this.invokeCallback<object>("onEnd", () => { |
|
|
|
this.onEnd(new ScaleEndDetails(velocity: Velocity.zero)); |
|
|
|
return null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void _advanceStateMachine(bool shouldStartIfAccepted) { |
|
|
|
if (this._state == _ScaleState.ready) { |
|
|
|
this._state = _ScaleState.possible; |
|
|
|
|
|
|
if (spanDelta > Constants.kScaleSlop || focalPointDelta > Constants.kPanSlop) { |
|
|
|
this.resolve(GestureDisposition.accepted); |
|
|
|
} |
|
|
|
} else if (this._state >= _ScaleState.accepted) { |
|
|
|
} |
|
|
|
else if (this._state >= _ScaleState.accepted) { |
|
|
|
this.resolve(GestureDisposition.accepted); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (this._state == _ScaleState.started && this.onUpdate != null) |
|
|
|
if (this._state == _ScaleState.started && this.onUpdate != null) { |
|
|
|
this.onUpdate(new ScaleUpdateDetails( |
|
|
|
scale: this._scaleFactor, |
|
|
|
horizontalScale: this._horizontalScaleFactor, |
|
|
|
verticalScale: this._verticalScaleFactor, |
|
|
|
focalPoint: this._currentFocalPoint, |
|
|
|
rotation: this._computeRotationFactor() |
|
|
|
)); |
|
|
|
this.onUpdate(new ScaleUpdateDetails( |
|
|
|
scale: this._scaleFactor, |
|
|
|
horizontalScale: this._horizontalScaleFactor, |
|
|
|
verticalScale: this._verticalScaleFactor, |
|
|
|
focalPoint: this._currentFocalPoint, |
|
|
|
rotation: this._computeRotationFactor() |
|
|
|
)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (this.onStart != null) |
|
|
|
if (this.onStart != null) { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override void acceptGesture(int pointer) { |
|
|
|
if (this._state == _ScaleState.possible) { |
|
|
|
this._state = _ScaleState.started; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected override void didStopTrackingLastPointer(int pointer) { |
|
|
|
switch (this._state) { |
|
|
|
case _ScaleState.possible: |
|
|
|
|
|
|
D.assert(false); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override void dispose() { |
|
|
|
this._velocityTrackers.Clear(); |
|
|
|
base.dispose(); |
|
|
|