Added onSecondaryTap in InkWell. (#119058)
Exposes onSecondaryTap in InkWell.
This commit is contained in:
parent
055769e63a
commit
e1eb1b9ecf
@ -294,6 +294,10 @@ class InkResponse extends StatelessWidget {
|
|||||||
this.onTapCancel,
|
this.onTapCancel,
|
||||||
this.onDoubleTap,
|
this.onDoubleTap,
|
||||||
this.onLongPress,
|
this.onLongPress,
|
||||||
|
this.onSecondaryTap,
|
||||||
|
this.onSecondaryTapUp,
|
||||||
|
this.onSecondaryTapDown,
|
||||||
|
this.onSecondaryTapCancel,
|
||||||
this.onHighlightChanged,
|
this.onHighlightChanged,
|
||||||
this.onHover,
|
this.onHover,
|
||||||
this.mouseCursor,
|
this.mouseCursor,
|
||||||
@ -342,6 +346,21 @@ class InkResponse extends StatelessWidget {
|
|||||||
/// Called when the user long-presses on this part of the material.
|
/// Called when the user long-presses on this part of the material.
|
||||||
final GestureLongPressCallback? onLongPress;
|
final GestureLongPressCallback? onLongPress;
|
||||||
|
|
||||||
|
/// Called when the user taps this part of the material with a secondary button.
|
||||||
|
final GestureTapCallback? onSecondaryTap;
|
||||||
|
|
||||||
|
/// Called when the user taps down on this part of the material with a
|
||||||
|
/// secondary button.
|
||||||
|
final GestureTapDownCallback? onSecondaryTapDown;
|
||||||
|
|
||||||
|
/// Called when the user releases a secondary button tap that was started on
|
||||||
|
/// this part of the material. [onSecondaryTap] is called immediately after.
|
||||||
|
final GestureTapUpCallback? onSecondaryTapUp;
|
||||||
|
|
||||||
|
/// Called when the user cancels a secondary button tap that was started on
|
||||||
|
/// this part of the material.
|
||||||
|
final GestureTapCallback? onSecondaryTapCancel;
|
||||||
|
|
||||||
/// Called when this part of the material either becomes highlighted or stops
|
/// Called when this part of the material either becomes highlighted or stops
|
||||||
/// being highlighted.
|
/// being highlighted.
|
||||||
///
|
///
|
||||||
@ -599,6 +618,10 @@ class InkResponse extends StatelessWidget {
|
|||||||
onTapCancel: onTapCancel,
|
onTapCancel: onTapCancel,
|
||||||
onDoubleTap: onDoubleTap,
|
onDoubleTap: onDoubleTap,
|
||||||
onLongPress: onLongPress,
|
onLongPress: onLongPress,
|
||||||
|
onSecondaryTap: onSecondaryTap,
|
||||||
|
onSecondaryTapUp: onSecondaryTapUp,
|
||||||
|
onSecondaryTapDown: onSecondaryTapDown,
|
||||||
|
onSecondaryTapCancel: onSecondaryTapCancel,
|
||||||
onHighlightChanged: onHighlightChanged,
|
onHighlightChanged: onHighlightChanged,
|
||||||
onHover: onHover,
|
onHover: onHover,
|
||||||
mouseCursor: mouseCursor,
|
mouseCursor: mouseCursor,
|
||||||
@ -651,6 +674,10 @@ class _InkResponseStateWidget extends StatefulWidget {
|
|||||||
this.onTapCancel,
|
this.onTapCancel,
|
||||||
this.onDoubleTap,
|
this.onDoubleTap,
|
||||||
this.onLongPress,
|
this.onLongPress,
|
||||||
|
this.onSecondaryTap,
|
||||||
|
this.onSecondaryTapUp,
|
||||||
|
this.onSecondaryTapDown,
|
||||||
|
this.onSecondaryTapCancel,
|
||||||
this.onHighlightChanged,
|
this.onHighlightChanged,
|
||||||
this.onHover,
|
this.onHover,
|
||||||
this.mouseCursor,
|
this.mouseCursor,
|
||||||
@ -684,6 +711,10 @@ class _InkResponseStateWidget extends StatefulWidget {
|
|||||||
final GestureTapCallback? onTapCancel;
|
final GestureTapCallback? onTapCancel;
|
||||||
final GestureTapCallback? onDoubleTap;
|
final GestureTapCallback? onDoubleTap;
|
||||||
final GestureLongPressCallback? onLongPress;
|
final GestureLongPressCallback? onLongPress;
|
||||||
|
final GestureTapCallback? onSecondaryTap;
|
||||||
|
final GestureTapUpCallback? onSecondaryTapUp;
|
||||||
|
final GestureTapDownCallback? onSecondaryTapDown;
|
||||||
|
final GestureTapCallback? onSecondaryTapCancel;
|
||||||
final ValueChanged<bool>? onHighlightChanged;
|
final ValueChanged<bool>? onHighlightChanged;
|
||||||
final ValueChanged<bool>? onHover;
|
final ValueChanged<bool>? onHover;
|
||||||
final MouseCursor? mouseCursor;
|
final MouseCursor? mouseCursor;
|
||||||
@ -722,6 +753,10 @@ class _InkResponseStateWidget extends StatefulWidget {
|
|||||||
if (onTapDown != null) 'tap down',
|
if (onTapDown != null) 'tap down',
|
||||||
if (onTapUp != null) 'tap up',
|
if (onTapUp != null) 'tap up',
|
||||||
if (onTapCancel != null) 'tap cancel',
|
if (onTapCancel != null) 'tap cancel',
|
||||||
|
if (onSecondaryTap != null) 'secondary tap',
|
||||||
|
if (onSecondaryTapUp != null) 'secondary tap up',
|
||||||
|
if (onSecondaryTapDown != null) 'secondary tap down',
|
||||||
|
if (onSecondaryTapCancel != null) 'secondary tap cancel'
|
||||||
];
|
];
|
||||||
properties.add(IterableProperty<String>('gestures', gestures, ifEmpty: '<none>'));
|
properties.add(IterableProperty<String>('gestures', gestures, ifEmpty: '<none>'));
|
||||||
properties.add(DiagnosticsProperty<MouseCursor>('mouseCursor', mouseCursor));
|
properties.add(DiagnosticsProperty<MouseCursor>('mouseCursor', mouseCursor));
|
||||||
@ -1040,11 +1075,15 @@ class _InkResponseState extends State<_InkResponseStateWidget>
|
|||||||
widget.onFocusChange?.call(hasFocus);
|
widget.onFocusChange?.call(hasFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleTapDown(TapDownDetails details) {
|
void handleAnyTapDown(TapDownDetails details) {
|
||||||
if (_anyChildInkResponsePressed) {
|
if (_anyChildInkResponsePressed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_startNewSplash(details: details);
|
_startNewSplash(details: details);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleTapDown(TapDownDetails details) {
|
||||||
|
handleAnyTapDown(details);
|
||||||
widget.onTapDown?.call(details);
|
widget.onTapDown?.call(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1052,6 +1091,15 @@ class _InkResponseState extends State<_InkResponseStateWidget>
|
|||||||
widget.onTapUp?.call(details);
|
widget.onTapUp?.call(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleSecondaryTapDown(TapDownDetails details) {
|
||||||
|
handleAnyTapDown(details);
|
||||||
|
widget.onSecondaryTapDown?.call(details);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleSecondaryTapUp(TapUpDetails details) {
|
||||||
|
widget.onSecondaryTapUp?.call(details);
|
||||||
|
}
|
||||||
|
|
||||||
void _startNewSplash({TapDownDetails? details, BuildContext? context}) {
|
void _startNewSplash({TapDownDetails? details, BuildContext? context}) {
|
||||||
assert(details != null || context != null);
|
assert(details != null || context != null);
|
||||||
|
|
||||||
@ -1110,6 +1158,20 @@ class _InkResponseState extends State<_InkResponseStateWidget>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleSecondaryTap() {
|
||||||
|
_currentSplash?.confirm();
|
||||||
|
_currentSplash = null;
|
||||||
|
updateHighlight(_HighlightType.pressed, value: false);
|
||||||
|
widget.onSecondaryTap?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleSecondaryTapCancel() {
|
||||||
|
_currentSplash?.cancel();
|
||||||
|
_currentSplash = null;
|
||||||
|
widget.onSecondaryTapCancel?.call();
|
||||||
|
updateHighlight(_HighlightType.pressed, value: false);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void deactivate() {
|
void deactivate() {
|
||||||
if (_splashes != null) {
|
if (_splashes != null) {
|
||||||
@ -1130,7 +1192,14 @@ class _InkResponseState extends State<_InkResponseStateWidget>
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isWidgetEnabled(_InkResponseStateWidget widget) {
|
bool isWidgetEnabled(_InkResponseStateWidget widget) {
|
||||||
return widget.onTap != null || widget.onDoubleTap != null || widget.onLongPress != null || widget.onTapDown != null;
|
return widget.onTap != null
|
||||||
|
|| widget.onDoubleTap != null
|
||||||
|
|| widget.onLongPress != null
|
||||||
|
|| widget.onTapUp != null
|
||||||
|
|| widget.onTapDown != null
|
||||||
|
|| widget.onSecondaryTap != null
|
||||||
|
|| widget.onSecondaryTapUp != null
|
||||||
|
|| widget.onSecondaryTapDown != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get enabled => isWidgetEnabled(widget);
|
bool get enabled => isWidgetEnabled(widget);
|
||||||
@ -1220,6 +1289,10 @@ class _InkResponseState extends State<_InkResponseStateWidget>
|
|||||||
onTapCancel: enabled ? handleTapCancel : null,
|
onTapCancel: enabled ? handleTapCancel : null,
|
||||||
onDoubleTap: widget.onDoubleTap != null ? handleDoubleTap : null,
|
onDoubleTap: widget.onDoubleTap != null ? handleDoubleTap : null,
|
||||||
onLongPress: widget.onLongPress != null ? handleLongPress : null,
|
onLongPress: widget.onLongPress != null ? handleLongPress : null,
|
||||||
|
onSecondaryTapDown: enabled ? handleSecondaryTapDown : null,
|
||||||
|
onSecondaryTapUp: enabled ? handleSecondaryTapUp: null,
|
||||||
|
onSecondaryTap: enabled ? handleSecondaryTap : null,
|
||||||
|
onSecondaryTapCancel: enabled ? handleSecondaryTapCancel : null,
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
excludeFromSemantics: true,
|
excludeFromSemantics: true,
|
||||||
child: widget.child,
|
child: widget.child,
|
||||||
@ -1326,6 +1399,10 @@ class InkWell extends InkResponse {
|
|||||||
super.onTapDown,
|
super.onTapDown,
|
||||||
super.onTapUp,
|
super.onTapUp,
|
||||||
super.onTapCancel,
|
super.onTapCancel,
|
||||||
|
super.onSecondaryTap,
|
||||||
|
super.onSecondaryTapUp,
|
||||||
|
super.onSecondaryTapDown,
|
||||||
|
super.onSecondaryTapCancel,
|
||||||
super.onHighlightChanged,
|
super.onHighlightChanged,
|
||||||
super.onHover,
|
super.onHover,
|
||||||
super.mouseCursor,
|
super.mouseCursor,
|
||||||
|
@ -2015,4 +2015,41 @@ testWidgets('InkResponse radius can be updated', (WidgetTester tester) async {
|
|||||||
await tester.pump(const Duration(milliseconds: 25));
|
await tester.pump(const Duration(milliseconds: 25));
|
||||||
expect(inkFeatures, paints..rect(rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), color: const Color(0x8000ff00)));
|
expect(inkFeatures, paints..rect(rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), color: const Color(0x8000ff00)));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('InkWell secondary tap test', (WidgetTester tester) async {
|
||||||
|
final List<String> log = <String>[];
|
||||||
|
|
||||||
|
await tester.pumpWidget(Directionality(
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
child: Material(
|
||||||
|
child: Center(
|
||||||
|
child: InkWell(
|
||||||
|
onSecondaryTap: () {
|
||||||
|
log.add('secondary-tap');
|
||||||
|
},
|
||||||
|
onSecondaryTapDown: (TapDownDetails details) {
|
||||||
|
log.add('secondary-tap-down');
|
||||||
|
},
|
||||||
|
onSecondaryTapUp: (TapUpDetails details) {
|
||||||
|
log.add('secondary-tap-up');
|
||||||
|
},
|
||||||
|
onSecondaryTapCancel: () {
|
||||||
|
log.add('secondary-tap-cancel');
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
await tester.tap(find.byType(InkWell), pointer: 1, buttons: kSecondaryButton);
|
||||||
|
|
||||||
|
expect(log, equals(<String>['secondary-tap-down', 'secondary-tap-up', 'secondary-tap']));
|
||||||
|
log.clear();
|
||||||
|
|
||||||
|
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(InkWell)), pointer: 2, buttons: kSecondaryButton);
|
||||||
|
await gesture.moveTo(const Offset(100, 100));
|
||||||
|
await gesture.up();
|
||||||
|
|
||||||
|
expect(log, equals(<String>['secondary-tap-down', 'secondary-tap-cancel']));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user