Unverified Commit 0a178f85 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

`CupertinoContextMenu`/`ContextMenuAction`: Add clickable cursor for web (#99519)

parent 6def1596
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart' show kMinFlingVelocity, kLongPressTimeout; import 'package:flutter/gestures.dart' show kMinFlingVelocity, kLongPressTimeout;
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
...@@ -367,17 +368,20 @@ class _CupertinoContextMenuState extends State<CupertinoContextMenu> with Ticker ...@@ -367,17 +368,20 @@ class _CupertinoContextMenuState extends State<CupertinoContextMenu> with Ticker
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return MouseRegion(
onTapCancel: _onTapCancel, cursor: kIsWeb ? SystemMouseCursors.click : MouseCursor.defer,
onTapDown: _onTapDown, child: GestureDetector(
onTapUp: _onTapUp, onTapCancel: _onTapCancel,
onTap: _onTap, onTapDown: _onTapDown,
child: TickerMode( onTapUp: _onTapUp,
enabled: !_childHidden, onTap: _onTap,
child: Opacity( child: TickerMode(
key: _childGlobalKey, enabled: !_childHidden,
opacity: _childHidden ? 0.0 : 1.0, child: Opacity(
child: widget.child, key: _childGlobalKey,
opacity: _childHidden ? 0.0 : 1.0,
child: widget.child,
),
), ),
), ),
); );
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'colors.dart'; import 'colors.dart';
...@@ -106,43 +107,46 @@ class _CupertinoContextMenuActionState extends State<CupertinoContextMenuAction> ...@@ -106,43 +107,46 @@ class _CupertinoContextMenuActionState extends State<CupertinoContextMenuAction>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return MouseRegion(
key: _globalKey, cursor: widget.onPressed != null && kIsWeb ? SystemMouseCursors.click : MouseCursor.defer,
onTapDown: onTapDown, child: GestureDetector(
onTapUp: onTapUp, key: _globalKey,
onTapCancel: onTapCancel, onTapDown: onTapDown,
onTap: widget.onPressed, onTapUp: onTapUp,
behavior: HitTestBehavior.opaque, onTapCancel: onTapCancel,
child: ConstrainedBox( onTap: widget.onPressed,
constraints: const BoxConstraints( behavior: HitTestBehavior.opaque,
minHeight: _kButtonHeight, child: ConstrainedBox(
), constraints: const BoxConstraints(
child: Semantics( minHeight: _kButtonHeight,
button: true, ),
child: Container( child: Semantics(
decoration: BoxDecoration( button: true,
color: _isPressed child: Container(
? CupertinoDynamicColor.resolve(_kBackgroundColorPressed, context) decoration: BoxDecoration(
: CupertinoDynamicColor.resolve(_kBackgroundColor, context), color: _isPressed
), ? CupertinoDynamicColor.resolve(_kBackgroundColorPressed, context)
padding: const EdgeInsets.symmetric( : CupertinoDynamicColor.resolve(_kBackgroundColor, context),
vertical: 16.0, ),
horizontal: 10.0, padding: const EdgeInsets.symmetric(
), vertical: 16.0,
child: DefaultTextStyle( horizontal: 10.0,
style: _textStyle, ),
child: Row( child: DefaultTextStyle(
mainAxisAlignment: MainAxisAlignment.spaceBetween, style: _textStyle,
children: <Widget>[ child: Row(
Flexible( mainAxisAlignment: MainAxisAlignment.spaceBetween,
child: widget.child, children: <Widget>[
), Flexible(
if (widget.trailingIcon != null) child: widget.child,
Icon(
widget.trailingIcon,
color: _textStyle.color,
), ),
], if (widget.trailingIcon != null)
Icon(
widget.trailingIcon,
color: _textStyle.color,
),
],
),
), ),
), ),
), ),
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
...@@ -122,4 +125,29 @@ void main() { ...@@ -122,4 +125,29 @@ void main() {
expect(_getTextStyle(tester).fontWeight, kDefaultActionWeight); expect(_getTextStyle(tester).fontWeight, kDefaultActionWeight);
}); });
testWidgets(
'Hovering over Cupertino context menu action updates cursor to clickable on Web',
(WidgetTester tester) async {
/// Cupertino context menu action without "onPressed" callback.
await tester.pumpWidget(_getApp());
final Offset contextMenuAction = tester.getCenter(find.text('I am a CupertinoContextMenuAction'));
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
await gesture.addPointer(location: contextMenuAction);
await tester.pumpAndSettle();
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
// / Cupertino context menu action with "onPressed" callback.
await tester.pumpWidget(_getApp(onPressed: (){}));
await gesture.moveTo(const Offset(10, 10));
await tester.pumpAndSettle();
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
await gesture.moveTo(contextMenuAction);
addTearDown(gesture.removePointer);
await tester.pumpAndSettle();
expect(
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
);
});
} }
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
...@@ -193,6 +196,38 @@ void main() { ...@@ -193,6 +196,38 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(_findStatic(), findsOneWidget); expect(_findStatic(), findsOneWidget);
}); });
testWidgets('Hovering over Cupertino context menu updates cursor to clickable on Web', (WidgetTester tester) async {
final Widget child = _getChild();
await tester.pumpWidget(CupertinoApp(
home: CupertinoPageScaffold(
child: Center(
child: CupertinoContextMenu(
actions: const <CupertinoContextMenuAction>[
CupertinoContextMenuAction(
child: Text('CupertinoContextMenuAction One'),
),
],
child: child,
),
),
),
));
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
await gesture.addPointer(location: const Offset(10, 10));
await tester.pumpAndSettle();
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
final Offset contextMenu = tester.getCenter(find.byWidget(child));
await gesture.moveTo(contextMenu);
addTearDown(gesture.removePointer);
await tester.pumpAndSettle();
expect(
RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1),
kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
);
});
}); });
group('CupertinoContextMenu when open', () { group('CupertinoContextMenu when open', () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment