Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions doc/flame/inputs/gesture_input.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ Detectors will be deprecated in the future. Prefer `Callbacks` instead.
- onHorizontalDragEnd
- onHorizontalDragCancel

- ForcePressDetector
- onForcePressStart
- onForcePressPeak
- onForcePressUpdate
- onForcePressEnd

- PanDetector
- onPanDown
- onPanStart
Expand Down
24 changes: 24 additions & 0 deletions doc/flame/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,30 @@ major versions of Flame, together with the steps required to migrate your code.
## Migrating from v1.38.0 to v2.0.0


### `ForcePressDetector` removed

The `ForcePressDetector` mixin and its `ForcePressInfo` event class have been removed, with no
replacement.
Comment thread
luanpotter marked this conversation as resolved.

It was a niche API, only available on some older Apple's 3D Touch devices; the iPhone XS and XS Max
Comment thread
luanpotter marked this conversation as resolved.
(2018) were the last models to include it (see Apple's
[Models with 3D Touch](https://support.apple.com/guide/iphone/aside/iph945ccc462/14.0/ios/14.0),
a list that Apple even stopped carrying forward after the iOS 14 guide). Every iPhone since,
starting with the XR, uses Haptic Touch, which responds to how long a press lasts rather than how
hard it is, and so never produces these callbacks. Only a handful of Android devices ever
supported it, and some of those (such as the Pixel 2 and 3) have faux pressure sensors that never
fired the callbacks anyway.

Combined with force press being the last gesture without an equivalent on the component-level event
system, maintaining it was no longer worth the surface area.

If you do still target a 3D Touch device, the gesture remains fully available from Flutter: wrap
your `GameWidget` in a
[`GestureDetector`](https://api.flutter.dev/flutter/widgets/GestureDetector-class.html) and use its
`onForcePressStart`, `onForcePressPeak`, `onForcePressUpdate` and `onForcePressEnd` callbacks
directly.


### Deprecated tap and long press game detectors removed

The game-level detector mixins that were deprecated in v1.38.0 have now been removed, together with
Expand Down
2 changes: 0 additions & 2 deletions packages/flame/lib/events.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ export 'src/game/mixins/keyboard.dart'
show HasKeyboardHandlerComponents, KeyboardEvents;
export 'src/gestures/detectors.dart'
show
ForcePressDetector,
HorizontalDragDetector,
MouseMovementDetector,
PanDetector,
Expand All @@ -93,7 +92,6 @@ export 'src/gestures/events.dart'
DragEndInfo,
DragStartInfo,
DragUpdateInfo,
ForcePressInfo,
PointerHoverInfo,
PointerScrollInfo,
PositionInfo,
Expand Down
1 change: 0 additions & 1 deletion packages/flame/lib/src/game/flame_game.dart
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@ class FlameGame<W extends World> extends ComponentTreeRoot
// so any in-bounds point is a hit.
if (this is VerticalDragDetector ||
this is HorizontalDragDetector ||
this is ForcePressDetector ||
this is PanDetector ||
this is ScaleDetector ||
this is MultiTapListener ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,6 @@ class GestureDetectorBuilder {
},
);
}
if (game is ForcePressDetector) {
register(
ForcePressGestureRecognizer.new,
(ForcePressGestureRecognizer instance) {
instance.onStart = game.handleForcePressStart;
instance.onPeak = game.handleForcePressPeak;
instance.onUpdate = game.handleForcePressUpdate;
instance.onEnd = game.handleForcePressEnd;
},
);
}
if (game is PanDetector) {
register(
PanGestureRecognizer.new,
Expand Down
23 changes: 0 additions & 23 deletions packages/flame/lib/src/gestures/detectors.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,6 @@ mixin HorizontalDragDetector on Game {
}
}

mixin ForcePressDetector on Game {
void onForcePressStart(ForcePressInfo info) {}
void onForcePressPeak(ForcePressInfo info) {}
void onForcePressUpdate(ForcePressInfo info) {}
void onForcePressEnd(ForcePressInfo info) {}

void handleForcePressStart(ForcePressDetails details) {
onForcePressStart(ForcePressInfo.fromDetails(this, details));
}

void handleForcePressPeak(ForcePressDetails details) {
onForcePressPeak(ForcePressInfo.fromDetails(this, details));
}

void handleForcePressUpdate(ForcePressDetails details) {
onForcePressUpdate(ForcePressInfo.fromDetails(this, details));
}

void handleForcePressEnd(ForcePressDetails details) {
onForcePressEnd(ForcePressInfo.fromDetails(this, details));
}
}

mixin PanDetector on Game {
void onPanDown(DragDownInfo info) {}
void onPanStart(DragStartInfo info) {}
Expand Down
9 changes: 0 additions & 9 deletions packages/flame/lib/src/gestures/events.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,6 @@ class TapUpInfo extends PositionInfo<TapUpDetails> {
) : super(game, raw.globalPosition, raw);
}

class ForcePressInfo extends PositionInfo<ForcePressDetails> {
late final double pressure = raw.pressure;

ForcePressInfo.fromDetails(
Game game,
ForcePressDetails raw,
) : super(game, raw.globalPosition, raw);
}

class PointerScrollInfo extends PositionInfo<PointerScrollEvent> {
late final EventDelta scrollDelta = EventDelta(raw.scrollDelta);

Expand Down
165 changes: 0 additions & 165 deletions packages/flame/test/gestures/detectors_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -155,144 +155,6 @@ void main() {
);
});

group('ForcePressDetector', () {
final forcePressGame = FlameTester(_ForcePressDetectorGame.new);

forcePressGame.testGameWidget(
'can register forcePress',
verify: (game, tester) async {
const forcePressOffset = Offset(10, 10);

final pointerValue = tester.nextPointer;

final gesture = await tester.createGesture();
await gesture.downWithCustomEvent(
forcePressOffset,
PointerDownEvent(
pointer: pointerValue,
position: forcePressOffset,
pressure: 0.0,
pressureMax: 6.0,
pressureMin: 0.0,
),
);

await gesture.updateWithCustomEvent(
PointerMoveEvent(
pointer: pointerValue,
pressure: 0.3,
pressureMin: 0,
),
);

expect(game.forcePressStart, equals(0));
expect(game.forcePressPeaked, equals(0));
expect(game.forcePressUpdate, equals(0));
expect(game.forcePressEnded, equals(0));

await gesture.updateWithCustomEvent(
PointerMoveEvent(
pointer: pointerValue,
pressure: 0.5,
pressureMin: 0,
),
);

expect(game.forcePressStart, equals(1));
expect(game.forcePressPeaked, equals(0));
expect(game.forcePressUpdate, equals(1));
expect(game.forcePressEnded, equals(0));

await gesture.updateWithCustomEvent(
PointerMoveEvent(
pointer: pointerValue,
pressure: 0.9,
pressureMin: 0,
),
);

expect(game.forcePressStart, equals(1));
expect(game.forcePressPeaked, equals(1));
expect(game.forcePressUpdate, equals(2));
expect(game.forcePressEnded, equals(0));

await gesture.up();

expect(game.forcePressStart, equals(1));
expect(game.forcePressPeaked, equals(1));
expect(game.forcePressUpdate, equals(2));
expect(game.forcePressEnded, equals(1));
},
);

testWithGame<_ForcePressDetectorGame>(
'can be Force Press started',
_ForcePressDetectorGame.new,
(game) async {
await game.ready();

game.handleForcePressStart(
ForcePressDetails(
globalPosition: const Offset(10, 10),
pressure: 0.4,
),
);

expect(game.forcePressStart, equals(1));
},
);

testWithGame<_ForcePressDetectorGame>(
'can be Force Press Updated',
_ForcePressDetectorGame.new,
(game) async {
await game.ready();

game.handleForcePressUpdate(
ForcePressDetails(
globalPosition: const Offset(10, 10),
pressure: 0.7,
),
);

expect(game.forcePressUpdate, equals(1));
},
);

testWithGame<_ForcePressDetectorGame>(
'can be Force Press peaked',
_ForcePressDetectorGame.new,
(game) async {
await game.ready();

game.handleForcePressPeak(
ForcePressDetails(
globalPosition: const Offset(10, 10),
pressure: 0.9,
),
);

expect(game.forcePressPeaked, equals(1));
},
);

testWithGame<_ForcePressDetectorGame>(
'can be Force Press Ended',
_ForcePressDetectorGame.new,
(game) async {
await game.ready();

game.handleForcePressEnd(
ForcePressDetails(
globalPosition: const Offset(10, 10),
pressure: 0.2,
),
);
expect(game.forcePressEnded, equals(1));
},
);
});

group('PanDetector', () {
final panGame = FlameTester(_PanDetectorGame.new);

Expand Down Expand Up @@ -518,33 +380,6 @@ class _VerticalDragDetectorGame extends FlameGame with VerticalDragDetector {
}
}

class _ForcePressDetectorGame extends FlameGame with ForcePressDetector {
int forcePressStart = 0;
int forcePressPeaked = 0;
int forcePressUpdate = 0;
int forcePressEnded = 0;

@override
void onForcePressStart(ForcePressInfo info) {
forcePressStart++;
}

@override
void onForcePressEnd(ForcePressInfo info) {
forcePressEnded++;
}

@override
void onForcePressUpdate(ForcePressInfo info) {
forcePressUpdate++;
}

@override
void onForcePressPeak(ForcePressInfo info) {
forcePressPeaked++;
}
}

class _PanDetectorGame extends FlameGame with PanDetector {
bool hasPanDown = false;
bool hasPanCancel = false;
Expand Down
Loading