InkWell uses MaterialStateMouseCursor and defaults to clickable (#58448)

* Adds support for material state mouse cursor to InkWell and InkResponse
* Set their default cursors to be MaterialStateMouseCursor.clickable.
This commit is contained in:
Tong Mu 2020-06-02 12:27:11 -07:00 committed by GitHub
parent 145d70c197
commit 0bda633509
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 13 deletions

View file

@ -13,6 +13,7 @@ import 'debug.dart';
import 'feedback.dart';
import 'ink_highlight.dart';
import 'material.dart';
import 'material_state.dart';
import 'theme.dart';
/// An ink feature that displays a [color] "splash" in response to a user
@ -296,7 +297,7 @@ class InkResponse extends StatelessWidget {
this.onLongPress,
this.onHighlightChanged,
this.onHover,
this.mouseCursor = MouseCursor.defer,
this.mouseCursor,
this.containedInkWell = false,
this.highlightShape = BoxShape.circle,
this.radius,
@ -313,8 +314,7 @@ class InkResponse extends StatelessWidget {
this.canRequestFocus = true,
this.onFocusChange,
this.autofocus = false,
}) : assert(mouseCursor != null),
assert(containedInkWell != null),
}) : assert(containedInkWell != null),
assert(highlightShape != null),
assert(enableFeedback != null),
assert(excludeFromSemantics != null),
@ -367,8 +367,17 @@ class InkResponse extends StatelessWidget {
/// The cursor for a mouse pointer when it enters or is hovering over the
/// widget.
///
/// The [cursor] defaults to [MouseCursor.defer], deferring the choice of
/// cursor to the next region behing it in hit-test order.
/// If [mouseCursor] is a [MaterialStateProperty<MouseCursor>],
/// [MaterialStateProperty.resolve] is used for the following [MaterialState]s:
///
/// * [MaterialState.hovered].
/// * [MaterialState.focused].
/// * [MaterialState.disabled].
///
/// When [value] is null and [tristate] is true, [MaterialState.selected] is
/// included as a state.
///
/// If this property is null, [MaterialStateMouseCursor.clickable] will be used.
final MouseCursor mouseCursor;
/// Whether this ink response should be clipped its bounds.
@ -601,7 +610,7 @@ class _InkResponseStateWidget extends StatefulWidget {
this.onLongPress,
this.onHighlightChanged,
this.onHover,
this.mouseCursor = MouseCursor.defer,
this.mouseCursor,
this.containedInkWell = false,
this.highlightShape = BoxShape.circle,
this.radius,
@ -626,8 +635,7 @@ class _InkResponseStateWidget extends StatefulWidget {
assert(enableFeedback != null),
assert(excludeFromSemantics != null),
assert(autofocus != null),
assert(canRequestFocus != null),
assert(mouseCursor != null);
assert(canRequestFocus != null);
final Widget child;
final GestureTapCallback onTap;
@ -672,7 +680,7 @@ class _InkResponseStateWidget extends StatefulWidget {
if (onTapCancel != null) 'tap cancel',
];
properties.add(IterableProperty<String>('gestures', gestures, ifEmpty: '<none>'));
properties.add(DiagnosticsProperty<MouseCursor>('mouseCursor', mouseCursor, defaultValue: MouseCursor.defer));
properties.add(DiagnosticsProperty<MouseCursor>('mouseCursor', mouseCursor));
properties.add(DiagnosticsProperty<bool>('containedInkWell', containedInkWell, level: DiagnosticLevel.fine));
properties.add(DiagnosticsProperty<BoxShape>(
'highlightShape',
@ -1025,6 +1033,14 @@ class _InkResponseState extends State<_InkResponseStateWidget>
_highlights[type]?.color = getHighlightColorForType(type);
}
_currentSplash?.color = widget.splashColor ?? Theme.of(context).splashColor;
final MouseCursor effectiveMouseCursor = MaterialStateProperty.resolveAs<MouseCursor>(
widget.mouseCursor ?? MaterialStateMouseCursor.clickable,
<MaterialState>{
if (!enabled) MaterialState.disabled,
if (_hovering) MaterialState.hovered,
if (_hasFocus) MaterialState.focused,
},
);
return _ParentInkResponseProvider(
state: this,
child: Actions(
@ -1035,7 +1051,7 @@ class _InkResponseState extends State<_InkResponseStateWidget>
onFocusChange: _handleFocusUpdate,
autofocus: widget.autofocus,
child: MouseRegion(
cursor: widget.mouseCursor,
cursor: effectiveMouseCursor,
onEnter: enabled ? _handleMouseEnter : null,
onExit: enabled ? _handleMouseExit : null,
child: GestureDetector(
@ -1160,7 +1176,7 @@ class InkWell extends InkResponse {
GestureTapCancelCallback onTapCancel,
ValueChanged<bool> onHighlightChanged,
ValueChanged<bool> onHover,
MouseCursor mouseCursor = MouseCursor.defer,
MouseCursor mouseCursor,
Color focusColor,
Color hoverColor,
Color highlightColor,

View file

@ -227,7 +227,22 @@ void main() {
),
);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
// Test disabled
await tester.pumpWidget(
const Material(
child: Directionality(
textDirection: TextDirection.ltr,
child: MouseRegion(
cursor: SystemMouseCursors.forbidden,
child: InkWell(),
),
),
),
);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
// Test default of InkResponse()
await tester.pumpWidget(
@ -244,7 +259,22 @@ void main() {
),
);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
// Test disabled
await tester.pumpWidget(
const Material(
child: Directionality(
textDirection: TextDirection.ltr,
child: MouseRegion(
cursor: SystemMouseCursors.forbidden,
child: InkResponse(),
),
),
),
);
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
});
group('feedback', () {