|
|
|
|
|
|
|
|
|
|
namespace Unity.UIWidgets.gestures { |
|
|
|
public class TapDownDetails { |
|
|
|
public TapDownDetails(Offset globalPosition = null) { |
|
|
|
public TapDownDetails(Offset globalPosition = null, |
|
|
|
Offset localPosition = null, |
|
|
|
PointerDeviceKind kind = PointerDeviceKind.touch, |
|
|
|
int device = 0) { |
|
|
|
this.localPosition = localPosition ?? this.globalPosition; |
|
|
|
this.kind = kind; |
|
|
|
this.device = device; |
|
|
|
|
|
|
|
public readonly Offset localPosition; |
|
|
|
|
|
|
|
public readonly PointerDeviceKind kind; |
|
|
|
|
|
|
|
public readonly int device; |
|
|
|
public TapUpDetails(Offset globalPosition = null) { |
|
|
|
public TapUpDetails(Offset globalPosition = null, |
|
|
|
Offset localPosition = null, |
|
|
|
PointerDeviceKind kind = PointerDeviceKind.touch, |
|
|
|
int device = 0) { |
|
|
|
this.localPosition = localPosition ?? this.globalPosition; |
|
|
|
this.kind = kind; |
|
|
|
this.device = device; |
|
|
|
|
|
|
|
public readonly Offset localPosition; |
|
|
|
|
|
|
|
public readonly PointerDeviceKind kind; |
|
|
|
|
|
|
|
public readonly int device; |
|
|
|
} |
|
|
|
|
|
|
|
public delegate void GestureTapUpCallback(TapUpDetails details); |
|
|
|
|
|
|
public delegate void GestureTapCancelCallback(); |
|
|
|
|
|
|
|
public class TapGestureRecognizer : PrimaryPointerGestureRecognizer { |
|
|
|
public TapGestureRecognizer(object debugOwner = null) |
|
|
|
: base(deadline: Constants.kPressTimeout, debugOwner: debugOwner) { } |
|
|
|
public GestureTapDownCallback onTapDown; |
|
|
|
public abstract class BaseTapGestureRecognizer : PrimaryPointerGestureRecognizer { |
|
|
|
public BaseTapGestureRecognizer(object debugOwner = null) |
|
|
|
: base(deadline: Constants.kPressTimeout, debugOwner: debugOwner) { |
|
|
|
|
|
|
|
} |
|
|
|
public GestureTapUpCallback onTapUp; |
|
|
|
bool _sentTapDown = false; |
|
|
|
bool _wonArenaForPrimaryPointer = false; |
|
|
|
public GestureTapCallback onTap; |
|
|
|
PointerDownEvent _down; |
|
|
|
PointerUpEvent _up; |
|
|
|
public GestureTapCancelCallback onTapCancel; |
|
|
|
protected abstract void handleTapDown(PointerDownEvent down); |
|
|
|
bool _sentTapDown = false; |
|
|
|
protected abstract void handleTapUp(PointerDownEvent down, PointerUpEvent up); |
|
|
|
bool _wonArenaForPrimaryPointer = false; |
|
|
|
protected abstract void handleTapCancel(PointerDownEvent down, PointerCancelEvent cancel, string reason); |
|
|
|
Offset _finalPosition; |
|
|
|
public override void addAllowedPointer(PointerDownEvent evt) { |
|
|
|
if (this.state == GestureRecognizerState.ready) { |
|
|
|
this._down = evt; |
|
|
|
} |
|
|
|
base.addAllowedPointer(evt); |
|
|
|
} |
|
|
|
this._finalPosition = evt.position; |
|
|
|
|
|
|
|
if (this._wonArenaForPrimaryPointer) { |
|
|
|
this.resolve(GestureDisposition.accepted); |
|
|
|
this._checkUp(); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (evt is PointerCancelEvent) { |
|
|
|
if (this._sentTapDown && this.onTapCancel != null) { |
|
|
|
this.invokeCallback<object>("onTapCancel", () => this.onTapCancel); |
|
|
|
this._up = (PointerUpEvent) evt; |
|
|
|
this._checkUp(); |
|
|
|
} else if (evt is PointerCancelEvent) { |
|
|
|
this.resolve(GestureDisposition.rejected); |
|
|
|
if (this._sentTapDown) { |
|
|
|
this._checkCancel((PointerCancelEvent) evt, ""); |
|
|
|
} else if (evt.buttons != this._down?.buttons) { |
|
|
|
this.resolve(GestureDisposition.rejected); |
|
|
|
this.stopTrackingPointer(this.primaryPointer); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
if (this.onTapCancel != null) { |
|
|
|
this.invokeCallback<object>("spontaneous onTapCancel", () => { |
|
|
|
this.onTapCancel(); |
|
|
|
return null; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
this._checkCancel(null, "spontaneous"); |
|
|
|
|
|
|
|
|
|
|
|
base.resolve(disposition); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override void acceptGesture(int pointer) { |
|
|
|
base.acceptGesture(pointer); |
|
|
|
|
|
|
|
if (pointer == this.primaryPointer) { |
|
|
|
this._checkDown(); |
|
|
|
this._wonArenaForPrimaryPointer = true; |
|
|
|
|
|
|
public override void rejectGesture(int pointer) { |
|
|
|
base.rejectGesture(pointer); |
|
|
|
if (pointer == this.primaryPointer) { |
|
|
|
if (this._sentTapDown && this.onTapCancel != null) { |
|
|
|
this.invokeCallback<object>("forced onTapCancel", () => { |
|
|
|
this.onTapCancel(); |
|
|
|
return null; |
|
|
|
}); |
|
|
|
D.assert(this.state != GestureRecognizerState.possible); |
|
|
|
if (this._sentTapDown) { |
|
|
|
this._checkCancel(null, "forced"); |
|
|
|
} |
|
|
|
|
|
|
|
this._reset(); |
|
|
|
|
|
|
void _checkDown() { |
|
|
|
if (!this._sentTapDown) { |
|
|
|
if (this.onTapDown != null) { |
|
|
|
this.invokeCallback<object>("onTapDown", () => { |
|
|
|
this.onTapDown(new TapDownDetails(globalPosition: this.initialPosition)); |
|
|
|
return null; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
this._sentTapDown = true; |
|
|
|
if (this._sentTapDown) { |
|
|
|
return; |
|
|
|
|
|
|
|
this.handleTapDown(down: this._down); |
|
|
|
this._sentTapDown = true; |
|
|
|
if (this._finalPosition != null) { |
|
|
|
if (this.onTapUp != null) { |
|
|
|
this.invokeCallback<object>("onTapUp", () => { |
|
|
|
this.onTapUp(new TapUpDetails(globalPosition: this._finalPosition)); |
|
|
|
return null; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
if (this.onTap != null) { |
|
|
|
this.invokeCallback<object>("onTap", () => { |
|
|
|
this.onTap(); |
|
|
|
return null; |
|
|
|
}); |
|
|
|
} |
|
|
|
if (!this._wonArenaForPrimaryPointer || this._up == null) { |
|
|
|
return; |
|
|
|
} |
|
|
|
this.handleTapUp(down: this._down, up: this._up); |
|
|
|
this._reset(); |
|
|
|
} |
|
|
|
this._reset(); |
|
|
|
} |
|
|
|
void _checkCancel(PointerCancelEvent evt, string note) { |
|
|
|
this.handleTapCancel(down: this._down, cancel: evt, reason: note); |
|
|
|
this._finalPosition = null; |
|
|
|
this._up = null; |
|
|
|
this._down = null; |
|
|
|
|
|
|
|
|
|
|
|
get { return "tap"; } |
|
|
|
get { return "base tap"; } |
|
|
|
|
|
|
|
|
|
|
|
properties.add(new FlagProperty("wonArenaForPrimaryPointer", |
|
|
|
value: this._wonArenaForPrimaryPointer, |
|
|
|
ifTrue: "won arena")); |
|
|
|
properties.add(new DiagnosticsProperty<Offset>("finalPosition", |
|
|
|
this._finalPosition, defaultValue: Diagnostics.kNullDefaultValue)); |
|
|
|
properties.add(new FlagProperty("sentTapDown", |
|
|
|
value: this._sentTapDown, ifTrue: "sent tap down")); |
|
|
|
properties.add(new FlagProperty("wonArenaForPrimaryPointer", value: this._wonArenaForPrimaryPointer, ifTrue: "won arena")); |
|
|
|
properties.add(new DiagnosticsProperty<Offset>("finalPosition", this._up?.position, defaultValue: null)); |
|
|
|
properties.add(new DiagnosticsProperty<Offset>("finalLocalPosition", this._up?.position, defaultValue: this._up?.position)); |
|
|
|
properties.add(new DiagnosticsProperty<int>("button", this._down?.buttons?? 0, defaultValue: 0)); |
|
|
|
properties.add(new FlagProperty("sentTapDown", value: this._sentTapDown, ifTrue: "sent tap down")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public class TapGestureRecognizer : BaseTapGestureRecognizer { |
|
|
|
public TapGestureRecognizer(object debugOwner = null) : base(debugOwner: debugOwner) { |
|
|
|
} |
|
|
|
|
|
|
|
public GestureTapDownCallback onTapDown; |
|
|
|
|
|
|
|
public GestureTapUpCallback onTapUp; |
|
|
|
|
|
|
|
public GestureTapCallback onTap; |
|
|
|
|
|
|
|
public GestureTapCancelCallback onTapCancel; |
|
|
|
|
|
|
|
public GestureTapDownCallback onSecondaryTapDown; |
|
|
|
|
|
|
|
public GestureTapUpCallback onSecondaryTapUp; |
|
|
|
|
|
|
|
public GestureTapCancelCallback onSecondaryTapCancel; |
|
|
|
|
|
|
|
protected override bool isPointerAllowed(PointerDownEvent evt) { |
|
|
|
if (this.onTapDown == null && |
|
|
|
this.onTap == null && |
|
|
|
this.onTapUp == null && |
|
|
|
this.onTapCancel == null) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
return base.isPointerAllowed(evt); |
|
|
|
} |
|
|
|
|
|
|
|
protected override void handleTapDown(PointerDownEvent down) { |
|
|
|
|
|
|
|
if (this.onTapDown != null) { |
|
|
|
TapDownDetails details = new TapDownDetails( |
|
|
|
globalPosition: down.position, |
|
|
|
kind: down.kind, |
|
|
|
device: down.device |
|
|
|
); |
|
|
|
|
|
|
|
this.invokeCallback<object>("onTapDown", () => { |
|
|
|
this.onTapDown(details); |
|
|
|
return null; |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected override void handleTapUp(PointerDownEvent down, PointerUpEvent up) { |
|
|
|
TapUpDetails details = new TapUpDetails( |
|
|
|
globalPosition: up.position, |
|
|
|
kind: up.kind, |
|
|
|
device: up.device |
|
|
|
); |
|
|
|
|
|
|
|
if (this.onTapUp != null) { |
|
|
|
this.invokeCallback<object>("onTapUp", () => { |
|
|
|
this.onTapUp(details); |
|
|
|
return null; |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
if (this.onTap != null) { |
|
|
|
this.invokeCallback<object>("onTap", () => { |
|
|
|
this.onTap(); |
|
|
|
return null; |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected override void handleTapCancel(PointerDownEvent down, PointerCancelEvent cancel, string note) { |
|
|
|
if (this.onTapCancel != null) { |
|
|
|
this.invokeCallback<object>("onTapCancel", () => { |
|
|
|
this.onTapCancel(); |
|
|
|
return null; |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public override string debugDescription { |
|
|
|
get { return "tap"; } |
|
|
|
} |
|
|
|
} |
|
|
|
} |