Skip to content

Commit

Permalink
InkResponse highlights can be updated (#115635)
Browse files Browse the repository at this point in the history
Co-authored-by: Bruno Leroux <[email protected]>
  • Loading branch information
bleroux and bleroux authored Nov 18, 2022
1 parent 18c8727 commit 87cb150
Show file tree
Hide file tree
Showing 2 changed files with 206 additions and 0 deletions.
15 changes: 15 additions & 0 deletions packages/flutter/lib/src/material/ink_well.dart
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,21 @@ class _InkResponseState extends State<_InkResponseStateWidget>
}
initStatesController();
}
if (widget.customBorder != oldWidget.customBorder ||
widget.radius != oldWidget.radius ||
widget.borderRadius != oldWidget.borderRadius ||
widget.highlightShape != oldWidget.highlightShape) {
final InkHighlight? hoverHighLight = _highlights[_HighlightType.hover];
if (hoverHighLight != null) {
hoverHighLight.dispose();
updateHighlight(_HighlightType.hover, value: _hovering, callOnHover: false);
}
final InkHighlight? focusHighLight = _highlights[_HighlightType.focus];
if (focusHighLight != null) {
focusHighLight.dispose();
// Do not call updateFocusHighlights() here because it is called below
}
}
if (enabled != isWidgetEnabled(oldWidget)) {
statesController.update(MaterialState.disabled, !enabled);
if (!enabled) {
Expand Down
191 changes: 191 additions & 0 deletions packages/flutter/test/material/ink_well_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,197 @@ void main() {
expect(inkFeatures, paints..circle(radius: 20, color: const Color(0xff0000ff)));
});

testWidgets('InkResponse radius can be updated', (WidgetTester tester) async {
FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
Widget boilerplate(double radius) {
return Material(
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
width: 100,
height: 100,
child: InkResponse(
focusNode: focusNode,
radius: radius,
focusColor: const Color(0xff0000ff),
onTap: () { },
),
),
),
),
);
}
await tester.pumpWidget(boilerplate(10));
await tester.pumpAndSettle();
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));

focusNode.requestFocus();
await tester.pumpAndSettle();
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 1));
expect(inkFeatures, paints..circle(radius: 10, color: const Color(0xff0000ff)));

await tester.pumpWidget(boilerplate(20));
await tester.pumpAndSettle();
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 1));
expect(inkFeatures, paints..circle(radius: 20, color: const Color(0xff0000ff)));
});

testWidgets('InkResponse highlightShape can be updated', (WidgetTester tester) async {
FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
Widget boilerplate(BoxShape shape) {
return Material(
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
width: 100,
height: 100,
child: InkResponse(
focusNode: focusNode,
highlightShape: shape,
borderRadius: BorderRadius.circular(10),
focusColor: const Color(0xff0000ff),
onTap: () { },
),
),
),
),
);
}

await tester.pumpWidget(boilerplate(BoxShape.circle));
await tester.pumpAndSettle();
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 0));

focusNode.requestFocus();
await tester.pumpAndSettle();
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 1));
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 0));

await tester.pumpWidget(boilerplate(BoxShape.rectangle));
await tester.pumpAndSettle();
expect(inkFeatures, paintsExactlyCountTimes(#drawCircle, 0));
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 1));
});

testWidgets('InkWell borderRadius can be updated', (WidgetTester tester) async {
FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
Widget boilerplate(BorderRadius borderRadius) {
return Material(
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
width: 100,
height: 100,
child: InkWell(
focusNode: focusNode,
borderRadius: borderRadius,
focusColor: const Color(0xff0000ff),
onTap: () { },
),
),
),
),
);
}

await tester.pumpWidget(boilerplate(BorderRadius.circular(10)));
await tester.pumpAndSettle();
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 0));

focusNode.requestFocus();
await tester.pumpAndSettle();
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 1));
expect(inkFeatures, paints..rrect(
rrect: RRect.fromLTRBR(350.0, 250.0, 450.0, 350.0, const Radius.circular(10)),
color: const Color(0xff0000ff),
));

await tester.pumpWidget(boilerplate(BorderRadius.circular(30)));
await tester.pumpAndSettle();
expect(inkFeatures, paintsExactlyCountTimes(#drawRRect, 1));
expect(inkFeatures, paints..rrect(
rrect: RRect.fromLTRBR(350.0, 250.0, 450.0, 350.0, const Radius.circular(30)),
color: const Color(0xff0000ff),
));
});

testWidgets('InkWell customBorder can be updated', (WidgetTester tester) async {
FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
Widget boilerplate(BorderRadius borderRadius) {
return Material(
child: Directionality(
textDirection: TextDirection.ltr,
child: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 100,
height: 100,
child: MouseRegion(
child: InkWell(
focusNode: focusNode,
customBorder: RoundedRectangleBorder(borderRadius: borderRadius),
hoverColor: const Color(0xff00ff00),
onTap: () { },
),
),
),
),
),
);
}

await tester.pumpWidget(boilerplate(BorderRadius.circular(20)));
await tester.pumpAndSettle();
final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
expect(inkFeatures, paintsExactlyCountTimes(#clipPath, 0));

focusNode.requestFocus();
await tester.pumpAndSettle();
expect(inkFeatures, paintsExactlyCountTimes(#clipPath, 1));

const Rect expectedClipRect = Rect.fromLTRB(0, 0, 100, 100);
Path expectedClipPath = Path()
..addRRect(RRect.fromRectAndRadius(
expectedClipRect,
const Radius.circular(20),
));
expect(
inkFeatures,
paints..clipPath(pathMatcher: coversSameAreaAs(
expectedClipPath,
areaToCompare: expectedClipRect.inflate(20.0),
sampleSize: 100,
)),
);

await tester.pumpWidget(boilerplate(BorderRadius.circular(40)));
await tester.pumpAndSettle();
expectedClipPath = Path()
..addRRect(RRect.fromRectAndRadius(
expectedClipRect,
const Radius.circular(40),
));
expect(
inkFeatures,
paints..clipPath(pathMatcher: coversSameAreaAs(
expectedClipPath,
areaToCompare: expectedClipRect.inflate(20.0),
sampleSize: 100,
)),
);
});

testWidgets("ink response doesn't change color on focus when on touch device", (WidgetTester tester) async {
FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTouch;
final FocusNode focusNode = FocusNode(debugLabel: 'Ink Focus');
Expand Down

0 comments on commit 87cb150

Please sign in to comment.