Unverified Commit 1f627769 authored by Darren Austin's avatar Darren Austin Committed by GitHub

Reland ##65044 (#66061)

Turn the opt-in default for ThemeData.useTextSelectionTheme to true so that everything uses the new TextSelectionTheme by default.
parent 5024e1ea
...@@ -1098,11 +1098,6 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements ...@@ -1098,11 +1098,6 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
} }
} }
Color _defaultSelectionColor(BuildContext context, Color primary) {
final bool isDark = Theme.of(context).brightness == Brightness.dark;
return primary.withOpacity(isDark ? 0.40 : 0.12);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(debugCheckHasMaterial(context)); assert(debugCheckHasMaterial(context));
...@@ -1136,13 +1131,14 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements ...@@ -1136,13 +1131,14 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
switch (theme.platform) { switch (theme.platform) {
case TargetPlatform.iOS: case TargetPlatform.iOS:
case TargetPlatform.macOS: case TargetPlatform.macOS:
final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context);
forcePressEnabled = true; forcePressEnabled = true;
textSelectionControls = cupertinoTextSelectionControls; textSelectionControls = cupertinoTextSelectionControls;
paintCursorAboveText = true; paintCursorAboveText = true;
cursorOpacityAnimates = true; cursorOpacityAnimates = true;
if (theme.useTextSelectionTheme) { if (theme.useTextSelectionTheme) {
cursorColor ??= selectionTheme.cursorColor ?? CupertinoTheme.of(context).primaryColor; cursorColor ??= selectionTheme.cursorColor ?? cupertinoTheme.primaryColor;
selectionColor = selectionTheme.selectionColor ?? _defaultSelectionColor(context, CupertinoTheme.of(context).primaryColor); selectionColor = selectionTheme.selectionColor ?? cupertinoTheme.primaryColor.withOpacity(0.40);
} else { } else {
cursorColor ??= CupertinoTheme.of(context).primaryColor; cursorColor ??= CupertinoTheme.of(context).primaryColor;
selectionColor = theme.textSelectionColor; selectionColor = theme.textSelectionColor;
...@@ -1162,7 +1158,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements ...@@ -1162,7 +1158,7 @@ class _TextFieldState extends State<TextField> with RestorationMixin implements
cursorOpacityAnimates = false; cursorOpacityAnimates = false;
if (theme.useTextSelectionTheme) { if (theme.useTextSelectionTheme) {
cursorColor ??= selectionTheme.cursorColor ?? theme.colorScheme.primary; cursorColor ??= selectionTheme.cursorColor ?? theme.colorScheme.primary;
selectionColor = selectionTheme.selectionColor ?? _defaultSelectionColor(context, theme.colorScheme.primary); selectionColor = selectionTheme.selectionColor ?? theme.colorScheme.primary.withOpacity(0.40);
} else { } else {
cursorColor ??= theme.cursorColor; cursorColor ??= theme.cursorColor;
selectionColor = theme.textSelectionColor; selectionColor = theme.textSelectionColor;
......
...@@ -405,7 +405,7 @@ class ThemeData with Diagnosticable { ...@@ -405,7 +405,7 @@ class ThemeData with Diagnosticable {
dataTableTheme ??= const DataTableThemeData(); dataTableTheme ??= const DataTableThemeData();
fixTextFieldOutlineLabel ??= false; fixTextFieldOutlineLabel ??= false;
useTextSelectionTheme ??= false; useTextSelectionTheme ??= true;
return ThemeData.raw( return ThemeData.raw(
visualDensity: visualDensity, visualDensity: visualDensity,
...@@ -883,12 +883,21 @@ class ThemeData with Diagnosticable { ...@@ -883,12 +883,21 @@ class ThemeData with Diagnosticable {
final Color secondaryHeaderColor; final Color secondaryHeaderColor;
/// The color of text selections in text fields, such as [TextField]. /// The color of text selections in text fields, such as [TextField].
///
/// By default this property is no longer used. It has been replaced with
/// [TextSelectionThemeData.selectionColor] and will soon be deprecated.
final Color textSelectionColor; final Color textSelectionColor;
/// The color of cursors in Material-style text fields, such as [TextField]. /// The color of cursors in Material-style text fields, such as [TextField].
///
/// By default this property is no longer used. It has been replaced with
/// [TextSelectionThemeData.cursorColor] and will soon be deprecated.
final Color cursorColor; final Color cursorColor;
/// The color of the handles used to adjust what part of the text is currently selected. /// The color of the handles used to adjust what part of the text is currently selected.
///
/// By default this property is no longer used. It has been replaced with
/// [TextSelectionThemeData.selectionHandleColor] and will soon be deprecated.
final Color textSelectionHandleColor; final Color textSelectionHandleColor;
/// A color that contrasts with the [primaryColor], e.g. used as the /// A color that contrasts with the [primaryColor], e.g. used as the
......
...@@ -554,7 +554,9 @@ void main() { ...@@ -554,7 +554,9 @@ void main() {
await tester.pumpWidget(RepaintBoundary( await tester.pumpWidget(RepaintBoundary(
child: Theme( child: Theme(
data: ThemeData( data: ThemeData(
textSelectionHandleColor: const Color(0x550000AA), textSelectionTheme: const TextSelectionThemeData(
selectionHandleColor: Color(0x550000AA),
),
), ),
isMaterialAppTheme: true, isMaterialAppTheme: true,
child: Builder( child: Builder(
......
...@@ -58,6 +58,10 @@ void main() { ...@@ -58,6 +58,10 @@ void main() {
}); });
testWidgets('Empty textSelectionTheme will use defaults', (WidgetTester tester) async { testWidgets('Empty textSelectionTheme will use defaults', (WidgetTester tester) async {
const Color defaultCursorColor = Color(0x002196f3);
const Color defaultSelectionColor = Color(0x662196f3);
const Color defaultSelectionHandleColor = Color(0xff2196f3);
// Test TextField's cursor & selection color. // Test TextField's cursor & selection color.
await tester.pumpWidget( await tester.pumpWidget(
const MaterialApp( const MaterialApp(
...@@ -69,52 +73,12 @@ void main() { ...@@ -69,52 +73,12 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final EditableTextState editableTextState = tester.firstState(find.byType(EditableText)); final EditableTextState editableTextState = tester.firstState(find.byType(EditableText));
final RenderEditable renderEditable = editableTextState.renderEditable; final RenderEditable renderEditable = editableTextState.renderEditable;
expect(renderEditable.cursorColor, const Color(0x004285f4)); expect(renderEditable.cursorColor, defaultCursorColor);
expect(renderEditable.selectionColor, const Color(0xFF90CAF9)); expect(Color(renderEditable.selectionColor.value), defaultSelectionColor);
// Test the selection handle color. // Test the selection handle color.
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material(
child: Builder(
builder: (BuildContext context) {
return materialTextSelectionControls.buildHandle(
context, TextSelectionHandleType.left, 10.0
);
},
),
),
),
);
await tester.pumpAndSettle();
final RenderBox handle = tester.firstRenderObject<RenderBox>(find.byType(CustomPaint));
expect(handle, paints..path(color: Colors.blue[300]));
});
testWidgets('Empty textSelectionTheme with useTextSelectionTheme set will use new defaults', (WidgetTester tester) async {
final ThemeData theme = ThemeData.fallback().copyWith(useTextSelectionTheme: true);
final Color primaryColor = Color(theme.colorScheme.primary.value);
// Test TextField's cursor & selection color.
await tester.pumpWidget(
MaterialApp(
theme: theme,
home: const Material(
child: TextField(),
),
),
);
await tester.pumpAndSettle();
final EditableTextState editableTextState = tester.firstState(find.byType(EditableText));
final RenderEditable renderEditable = editableTextState.renderEditable;
expect(renderEditable.cursorColor, primaryColor.withAlpha(0));
expect(Color(renderEditable.selectionColor.value), primaryColor.withOpacity(0.12));
// Test the selection handle color.
await tester.pumpWidget(
MaterialApp(
theme: theme,
home: Material( home: Material(
child: Builder( child: Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
...@@ -128,7 +92,7 @@ void main() { ...@@ -128,7 +92,7 @@ void main() {
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final RenderBox handle = tester.firstRenderObject<RenderBox>(find.byType(CustomPaint)); final RenderBox handle = tester.firstRenderObject<RenderBox>(find.byType(CustomPaint));
expect(handle, paints..path(color: primaryColor)); expect(handle, paints..path(color: defaultSelectionHandleColor));
}); });
testWidgets('ThemeDate.textSelectionTheme will be used if provided', (WidgetTester tester) async { testWidgets('ThemeDate.textSelectionTheme will be used if provided', (WidgetTester tester) async {
...@@ -138,7 +102,6 @@ void main() { ...@@ -138,7 +102,6 @@ void main() {
selectionHandleColor: Color(0x00ccbbaa), selectionHandleColor: Color(0x00ccbbaa),
); );
final ThemeData theme = ThemeData.fallback().copyWith( final ThemeData theme = ThemeData.fallback().copyWith(
useTextSelectionTheme: true,
textSelectionTheme: textSelectionTheme, textSelectionTheme: textSelectionTheme,
); );
...@@ -184,7 +147,6 @@ void main() { ...@@ -184,7 +147,6 @@ void main() {
selectionHandleColor: Color(0x00ccbbaa), selectionHandleColor: Color(0x00ccbbaa),
); );
final ThemeData theme = ThemeData.fallback().copyWith( final ThemeData theme = ThemeData.fallback().copyWith(
useTextSelectionTheme: true,
textSelectionTheme: defaultTextSelectionTheme, textSelectionTheme: defaultTextSelectionTheme,
); );
const TextSelectionThemeData widgetTextSelectionTheme = TextSelectionThemeData( const TextSelectionThemeData widgetTextSelectionTheme = TextSelectionThemeData(
...@@ -240,7 +202,6 @@ void main() { ...@@ -240,7 +202,6 @@ void main() {
selectionHandleColor: Color(0x00ccbbaa), selectionHandleColor: Color(0x00ccbbaa),
); );
final ThemeData theme = ThemeData.fallback().copyWith( final ThemeData theme = ThemeData.fallback().copyWith(
useTextSelectionTheme: true,
textSelectionTheme: defaultTextSelectionTheme, textSelectionTheme: defaultTextSelectionTheme,
); );
const TextSelectionThemeData widgetTextSelectionTheme = TextSelectionThemeData( const TextSelectionThemeData widgetTextSelectionTheme = TextSelectionThemeData(
......
...@@ -208,6 +208,7 @@ void main() { ...@@ -208,6 +208,7 @@ void main() {
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Cursor does not animate on Android', (WidgetTester tester) async { testWidgets('Cursor does not animate on Android', (WidgetTester tester) async {
final Color defaultCursorColor = Color(ThemeData.fallback().colorScheme.primary.value);
const Widget widget = MaterialApp( const Widget widget = MaterialApp(
home: Material( home: Material(
child: TextField( child: TextField(
...@@ -225,12 +226,12 @@ void main() { ...@@ -225,12 +226,12 @@ void main() {
await tester.pump(); await tester.pump();
expect(renderEditable.cursorColor.alpha, 255); expect(renderEditable.cursorColor.alpha, 255);
expect(renderEditable, paints..rect(color: const Color(0xff4285f4))); expect(renderEditable, paints..rect(color: defaultCursorColor));
// Android cursor goes from exactly on to exactly off on the 500ms dot. // Android cursor goes from exactly on to exactly off on the 500ms dot.
await tester.pump(const Duration(milliseconds: 499)); await tester.pump(const Duration(milliseconds: 499));
expect(renderEditable.cursorColor.alpha, 255); expect(renderEditable.cursorColor.alpha, 255);
expect(renderEditable, paints..rect(color: const Color(0xff4285f4))); expect(renderEditable, paints..rect(color: defaultCursorColor));
await tester.pump(const Duration(milliseconds: 1)); await tester.pump(const Duration(milliseconds: 1));
expect(renderEditable.cursorColor.alpha, 0); expect(renderEditable.cursorColor.alpha, 0);
...@@ -239,7 +240,7 @@ void main() { ...@@ -239,7 +240,7 @@ void main() {
await tester.pump(const Duration(milliseconds: 500)); await tester.pump(const Duration(milliseconds: 500));
expect(renderEditable.cursorColor.alpha, 255); expect(renderEditable.cursorColor.alpha, 255);
expect(renderEditable, paints..rect(color: const Color(0xff4285f4))); expect(renderEditable, paints..rect(color: defaultCursorColor));
await tester.pump(const Duration(milliseconds: 500)); await tester.pump(const Duration(milliseconds: 500));
expect(renderEditable.cursorColor.alpha, 0); expect(renderEditable.cursorColor.alpha, 0);
...@@ -248,6 +249,7 @@ void main() { ...@@ -248,6 +249,7 @@ void main() {
testWidgets('Cursor does not animates when debugDeterministicCursor is set', (WidgetTester tester) async { testWidgets('Cursor does not animates when debugDeterministicCursor is set', (WidgetTester tester) async {
EditableText.debugDeterministicCursor = true; EditableText.debugDeterministicCursor = true;
final Color defaultCursorColor = Color(ThemeData.fallback().colorScheme.primary.value);
const Widget widget = MaterialApp( const Widget widget = MaterialApp(
home: Material( home: Material(
child: TextField( child: TextField(
...@@ -268,24 +270,24 @@ void main() { ...@@ -268,24 +270,24 @@ void main() {
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 200)); await tester.pump(const Duration(milliseconds: 200));
expect(renderEditable.cursorColor.alpha, 255); expect(renderEditable.cursorColor.alpha, 255);
expect(renderEditable, paints..rrect(color: const Color(0xff2196f3))); expect(renderEditable, paints..rrect(color: defaultCursorColor));
// Cursor draw never changes. // Cursor draw never changes.
await tester.pump(const Duration(milliseconds: 200)); await tester.pump(const Duration(milliseconds: 200));
expect(renderEditable.cursorColor.alpha, 255); expect(renderEditable.cursorColor.alpha, 255);
expect(renderEditable, paints..rrect(color: const Color(0xff2196f3))); expect(renderEditable, paints..rrect(color: defaultCursorColor));
// No more transient calls. // No more transient calls.
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(renderEditable.cursorColor.alpha, 255); expect(renderEditable.cursorColor.alpha, 255);
expect(renderEditable, paints..rrect(color: const Color(0xff2196f3))); expect(renderEditable, paints..rrect(color: defaultCursorColor));
EditableText.debugDeterministicCursor = false; EditableText.debugDeterministicCursor = false;
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Cursor does not animate on Android when debugDeterministicCursor is set', (WidgetTester tester) async { testWidgets('Cursor does not animate on Android when debugDeterministicCursor is set', (WidgetTester tester) async {
final Color defaultCursorColor = Color(ThemeData.fallback().colorScheme.primary.value);
EditableText.debugDeterministicCursor = true; EditableText.debugDeterministicCursor = true;
const Widget widget = MaterialApp( const Widget widget = MaterialApp(
home: Material( home: Material(
child: TextField( child: TextField(
...@@ -303,21 +305,21 @@ void main() { ...@@ -303,21 +305,21 @@ void main() {
await tester.pump(); await tester.pump();
expect(renderEditable.cursorColor.alpha, 255); expect(renderEditable.cursorColor.alpha, 255);
expect(renderEditable, paints..rect(color: const Color(0xff4285f4))); expect(renderEditable, paints..rect(color: defaultCursorColor));
await tester.pump(const Duration(milliseconds: 500)); await tester.pump(const Duration(milliseconds: 500));
expect(renderEditable.cursorColor.alpha, 255); expect(renderEditable.cursorColor.alpha, 255);
expect(renderEditable, paints..rect(color: const Color(0xff4285f4))); expect(renderEditable, paints..rect(color: defaultCursorColor));
// Cursor draw never changes. // Cursor draw never changes.
await tester.pump(const Duration(milliseconds: 500)); await tester.pump(const Duration(milliseconds: 500));
expect(renderEditable.cursorColor.alpha, 255); expect(renderEditable.cursorColor.alpha, 255);
expect(renderEditable, paints..rect(color: const Color(0xff4285f4))); expect(renderEditable, paints..rect(color: defaultCursorColor));
// No more transient calls. // No more transient calls.
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(renderEditable.cursorColor.alpha, 255); expect(renderEditable.cursorColor.alpha, 255);
expect(renderEditable, paints..rect(color: const Color(0xff4285f4))); expect(renderEditable, paints..rect(color: defaultCursorColor));
EditableText.debugDeterministicCursor = false; EditableText.debugDeterministicCursor = false;
}); });
......
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