mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
Expose selectionHeightStyle and selectionWidthStyle on TextFields (#48917)
This commit is contained in:
parent
3aa7a80053
commit
3e1a124e0e
|
@ -2,6 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
@ -196,10 +198,15 @@ class CupertinoTextField extends StatefulWidget {
|
|||
///
|
||||
/// If specified, the [maxLength] property must be greater than zero.
|
||||
///
|
||||
/// The [selectionHeightStyle] and [selectionWidthStyle] properties allow
|
||||
/// changing the shape of the selection highlighting. These properties default
|
||||
/// to [ui.BoxHeightStyle.tight] and [ui.BoxWidthStyle.tight] respectively and
|
||||
/// must not be null.
|
||||
///
|
||||
/// The [autocorrect], [autofocus], [clearButtonMode], [dragStartBehavior],
|
||||
/// [expands], [maxLengthEnforced], [obscureText], [prefixMode], [readOnly],
|
||||
/// [scrollPadding], [suffixMode], [textAlign], and [enableSuggestions]
|
||||
/// properties must not be null.
|
||||
/// [scrollPadding], [suffixMode], [textAlign], [selectionHeightStyle],
|
||||
/// [selectionWidthStyle], and [enableSuggestions] properties must not be null.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
|
@ -252,6 +259,8 @@ class CupertinoTextField extends StatefulWidget {
|
|||
this.cursorWidth = 2.0,
|
||||
this.cursorRadius = const Radius.circular(2.0),
|
||||
this.cursorColor,
|
||||
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
|
||||
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
|
||||
this.keyboardAppearance,
|
||||
this.scrollPadding = const EdgeInsets.all(20.0),
|
||||
this.dragStartBehavior = DragStartBehavior.start,
|
||||
|
@ -270,6 +279,8 @@ class CupertinoTextField extends StatefulWidget {
|
|||
assert(maxLengthEnforced != null),
|
||||
assert(scrollPadding != null),
|
||||
assert(dragStartBehavior != null),
|
||||
assert(selectionHeightStyle != null),
|
||||
assert(selectionWidthStyle != null),
|
||||
assert(maxLines == null || maxLines > 0),
|
||||
assert(minLines == null || minLines > 0),
|
||||
assert(
|
||||
|
@ -530,6 +541,16 @@ class CupertinoTextField extends StatefulWidget {
|
|||
/// and [CupertinoColors.activeOrange] in the dark theme.
|
||||
final Color cursorColor;
|
||||
|
||||
/// Controls how tall the selection highlight boxes are computed to be.
|
||||
///
|
||||
/// See [ui.BoxHeightStyle] for details on available styles.
|
||||
final ui.BoxHeightStyle selectionHeightStyle;
|
||||
|
||||
/// Controls how wide the selection highlight boxes are computed to be.
|
||||
///
|
||||
/// See [ui.BoxWidthStyle] for details on available styles.
|
||||
final ui.BoxWidthStyle selectionWidthStyle;
|
||||
|
||||
/// The appearance of the keyboard.
|
||||
///
|
||||
/// This setting is only honored on iOS devices.
|
||||
|
@ -918,6 +939,8 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
|
|||
cursorOffset: cursorOffset,
|
||||
paintCursorAboveText: true,
|
||||
backgroundCursorColor: CupertinoDynamicColor.resolve(CupertinoColors.inactiveGray, context),
|
||||
selectionHeightStyle: widget.selectionHeightStyle,
|
||||
selectionWidthStyle: widget.selectionWidthStyle,
|
||||
scrollPadding: widget.scrollPadding,
|
||||
keyboardAppearance: keyboardAppearance,
|
||||
dragStartBehavior: widget.dragStartBehavior,
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
@ -279,9 +281,15 @@ class TextField extends StatefulWidget {
|
|||
/// The text cursor is not shown if [showCursor] is false or if [showCursor]
|
||||
/// is null (the default) and [readOnly] is true.
|
||||
///
|
||||
/// The [selectionHeightStyle] and [selectionWidthStyle] properties allow
|
||||
/// changing the shape of the selection highlighting. These properties default
|
||||
/// to [ui.BoxHeightStyle.tight] and [ui.BoxWidthStyle.tight] respectively and
|
||||
/// must not be null.
|
||||
///
|
||||
/// The [textAlign], [autofocus], [obscureText], [readOnly], [autocorrect],
|
||||
/// [maxLengthEnforced], [scrollPadding], [maxLines], [maxLength],
|
||||
/// and [enableSuggestions] arguments must not be null.
|
||||
/// [selectionHeightStyle], [selectionWidthStyle], and [enableSuggestions]
|
||||
/// arguments must not be null.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
|
@ -322,6 +330,8 @@ class TextField extends StatefulWidget {
|
|||
this.cursorWidth = 2.0,
|
||||
this.cursorRadius,
|
||||
this.cursorColor,
|
||||
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
|
||||
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
|
||||
this.keyboardAppearance,
|
||||
this.scrollPadding = const EdgeInsets.all(20.0),
|
||||
this.dragStartBehavior = DragStartBehavior.start,
|
||||
|
@ -342,6 +352,8 @@ class TextField extends StatefulWidget {
|
|||
assert(maxLengthEnforced != null),
|
||||
assert(scrollPadding != null),
|
||||
assert(dragStartBehavior != null),
|
||||
assert(selectionHeightStyle != null),
|
||||
assert(selectionWidthStyle != null),
|
||||
assert(maxLines == null || maxLines > 0),
|
||||
assert(minLines == null || minLines > 0),
|
||||
assert(
|
||||
|
@ -603,6 +615,16 @@ class TextField extends StatefulWidget {
|
|||
/// depending on [ThemeData.platform].
|
||||
final Color cursorColor;
|
||||
|
||||
/// Controls how tall the selection highlight boxes are computed to be.
|
||||
///
|
||||
/// See [ui.BoxHeightStyle] for details on available styles.
|
||||
final ui.BoxHeightStyle selectionHeightStyle;
|
||||
|
||||
/// Controls how wide the selection highlight boxes are computed to be.
|
||||
///
|
||||
/// See [ui.BoxWidthStyle] for details on available styles.
|
||||
final ui.BoxWidthStyle selectionWidthStyle;
|
||||
|
||||
/// The appearance of the keyboard.
|
||||
///
|
||||
/// This setting is only honored on iOS devices.
|
||||
|
@ -1003,6 +1025,8 @@ class _TextFieldState extends State<TextField> implements TextSelectionGestureDe
|
|||
cursorWidth: widget.cursorWidth,
|
||||
cursorRadius: cursorRadius,
|
||||
cursorColor: cursorColor,
|
||||
selectionHeightStyle: widget.selectionHeightStyle,
|
||||
selectionWidthStyle: widget.selectionWidthStyle,
|
||||
cursorOpacityAnimates: cursorOpacityAnimates,
|
||||
cursorOffset: cursorOffset,
|
||||
paintCursorAboveText: paintCursorAboveText,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:math' show min, max;
|
||||
import 'dart:ui' as ui show Paragraph, ParagraphBuilder, ParagraphConstraints, ParagraphStyle, PlaceholderAlignment, LineMetrics, TextHeightBehavior;
|
||||
import 'dart:ui' as ui show Paragraph, ParagraphBuilder, ParagraphConstraints, ParagraphStyle, PlaceholderAlignment, LineMetrics, TextHeightBehavior, BoxHeightStyle, BoxWidthStyle;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
@ -808,12 +808,28 @@ class TextPainter {
|
|||
|
||||
/// Returns a list of rects that bound the given selection.
|
||||
///
|
||||
/// The [boxHeightStyle] and [boxWidthStyle] arguments may be used to select
|
||||
/// the shape of the [TextBox]s. These properties default to
|
||||
/// [ui.BoxHeightStyle.tight] and [ui.BoxWidthStyle.tight] respectively and
|
||||
/// must not be null.
|
||||
///
|
||||
/// A given selection might have more than one rect if this text painter
|
||||
/// contains bidirectional text because logically contiguous text might not be
|
||||
/// visually contiguous.
|
||||
List<TextBox> getBoxesForSelection(TextSelection selection) {
|
||||
List<TextBox> getBoxesForSelection(
|
||||
TextSelection selection, {
|
||||
ui.BoxHeightStyle boxHeightStyle = ui.BoxHeightStyle.tight,
|
||||
ui.BoxWidthStyle boxWidthStyle = ui.BoxWidthStyle.tight,
|
||||
}) {
|
||||
assert(!_needsLayout);
|
||||
return _paragraph.getBoxesForRange(selection.start, selection.end);
|
||||
assert(boxHeightStyle != null);
|
||||
assert(boxWidthStyle != null);
|
||||
return _paragraph.getBoxesForRange(
|
||||
selection.start,
|
||||
selection.end,
|
||||
boxHeightStyle: boxHeightStyle,
|
||||
boxWidthStyle: boxWidthStyle
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the position within the text for the given pixel offset.
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:math' as math;
|
||||
import 'dart:ui' as ui show TextBox, lerpDouble;
|
||||
import 'dart:ui' as ui show TextBox, lerpDouble, BoxHeightStyle, BoxWidthStyle;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
|
@ -208,6 +208,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
|||
bool paintCursorAboveText = false,
|
||||
Offset cursorOffset,
|
||||
double devicePixelRatio = 1.0,
|
||||
ui.BoxHeightStyle selectionHeightStyle = ui.BoxHeightStyle.tight,
|
||||
ui.BoxWidthStyle selectionWidthStyle = ui.BoxWidthStyle.tight,
|
||||
bool enableInteractiveSelection,
|
||||
EdgeInsets floatingCursorAddedMargin = const EdgeInsets.fromLTRB(4, 4, 4, 5),
|
||||
@required this.textSelectionDelegate,
|
||||
|
@ -237,6 +239,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
|||
assert(readOnly != null),
|
||||
assert(forceLine != null),
|
||||
assert(devicePixelRatio != null),
|
||||
assert(selectionHeightStyle != null),
|
||||
assert(selectionWidthStyle != null),
|
||||
_textPainter = TextPainter(
|
||||
text: text,
|
||||
textAlign: textAlign,
|
||||
|
@ -262,6 +266,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
|||
_floatingCursorAddedMargin = floatingCursorAddedMargin,
|
||||
_enableInteractiveSelection = enableInteractiveSelection,
|
||||
_devicePixelRatio = devicePixelRatio,
|
||||
_selectionHeightStyle = selectionHeightStyle,
|
||||
_selectionWidthStyle = selectionWidthStyle,
|
||||
_startHandleLayerLink = startHandleLayerLink,
|
||||
_endHandleLayerLink = endHandleLayerLink,
|
||||
_obscureText = obscureText,
|
||||
|
@ -1094,6 +1100,32 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
|||
Offset _floatingCursorOffset;
|
||||
TextPosition _floatingCursorTextPosition;
|
||||
|
||||
/// Controls how tall the selection highlight boxes are computed to be.
|
||||
///
|
||||
/// See [ui.BoxHeightStyle] for details on available styles.
|
||||
ui.BoxHeightStyle get selectionHeightStyle => _selectionHeightStyle;
|
||||
ui.BoxHeightStyle _selectionHeightStyle;
|
||||
set selectionHeightStyle(ui.BoxHeightStyle value) {
|
||||
assert(value != null);
|
||||
if (_selectionHeightStyle == value)
|
||||
return;
|
||||
_selectionHeightStyle = value;
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
/// Controls how wide the selection highlight boxes are computed to be.
|
||||
///
|
||||
/// See [ui.BoxWidthStyle] for details on available styles.
|
||||
ui.BoxWidthStyle get selectionWidthStyle => _selectionWidthStyle;
|
||||
ui.BoxWidthStyle _selectionWidthStyle;
|
||||
set selectionWidthStyle(ui.BoxWidthStyle value) {
|
||||
assert(value != null);
|
||||
if (_selectionWidthStyle == value)
|
||||
return;
|
||||
_selectionWidthStyle = value;
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
/// If false, [describeSemanticsConfiguration] will not set the
|
||||
/// configuration's cursor motion or set selection callbacks.
|
||||
///
|
||||
|
@ -1941,7 +1973,7 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
|
|||
}
|
||||
|
||||
if (showSelection) {
|
||||
_selectionRects ??= _textPainter.getBoxesForSelection(_selection);
|
||||
_selectionRects ??= _textPainter.getBoxesForSelection(_selection, boxHeightStyle: _selectionHeightStyle, boxWidthStyle: _selectionWidthStyle);
|
||||
_paintSelection(context.canvas, effectiveOffset);
|
||||
}
|
||||
|
||||
|
|
|
@ -342,10 +342,10 @@ class EditableText extends StatefulWidget {
|
|||
/// The [controller], [focusNode], [obscureText], [autocorrect], [autofocus],
|
||||
/// [showSelectionHandles], [enableInteractiveSelection], [forceLine],
|
||||
/// [style], [cursorColor], [cursorOpacityAnimates],[backgroundCursorColor],
|
||||
/// [enableSuggestions], [paintCursorAboveText], [textAlign],
|
||||
/// [dragStartBehavior], [scrollPadding], [dragStartBehavior],
|
||||
/// [toolbarOptions], [rendererIgnoresPointer], and [readOnly] arguments must
|
||||
/// not be null.
|
||||
/// [enableSuggestions], [paintCursorAboveText], [selectionHeightStyle],
|
||||
/// [selectionWidthStyle], [textAlign], [dragStartBehavior], [scrollPadding],
|
||||
/// [dragStartBehavior], [toolbarOptions], [rendererIgnoresPointer], and
|
||||
/// [readOnly] arguments must not be null.
|
||||
EditableText({
|
||||
Key key,
|
||||
@required this.controller,
|
||||
|
@ -389,6 +389,8 @@ class EditableText extends StatefulWidget {
|
|||
this.cursorOpacityAnimates = false,
|
||||
this.cursorOffset,
|
||||
this.paintCursorAboveText = false,
|
||||
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
|
||||
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
|
||||
this.scrollPadding = const EdgeInsets.all(20.0),
|
||||
this.keyboardAppearance = Brightness.light,
|
||||
this.dragStartBehavior = DragStartBehavior.start,
|
||||
|
@ -417,6 +419,8 @@ class EditableText extends StatefulWidget {
|
|||
assert(cursorOpacityAnimates != null),
|
||||
assert(paintCursorAboveText != null),
|
||||
assert(backgroundCursorColor != null),
|
||||
assert(selectionHeightStyle != null),
|
||||
assert(selectionWidthStyle != null),
|
||||
assert(textAlign != null),
|
||||
assert(maxLines == null || maxLines > 0),
|
||||
assert(minLines == null || minLines > 0),
|
||||
|
@ -979,6 +983,16 @@ class EditableText extends StatefulWidget {
|
|||
///{@macro flutter.rendering.editable.paintCursorOnTop}
|
||||
final bool paintCursorAboveText;
|
||||
|
||||
/// Controls how tall the selection highlight boxes are computed to be.
|
||||
///
|
||||
/// See [ui.BoxHeightStyle] for details on available styles.
|
||||
final ui.BoxHeightStyle selectionHeightStyle;
|
||||
|
||||
/// Controls how wide the selection highlight boxes are computed to be.
|
||||
///
|
||||
/// See [ui.BoxWidthStyle] for details on available styles.
|
||||
final ui.BoxWidthStyle selectionWidthStyle;
|
||||
|
||||
/// The appearance of the keyboard.
|
||||
///
|
||||
/// This setting is only honored on iOS devices.
|
||||
|
@ -1894,6 +1908,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
|
|||
cursorWidth: widget.cursorWidth,
|
||||
cursorRadius: widget.cursorRadius,
|
||||
cursorOffset: widget.cursorOffset,
|
||||
selectionHeightStyle: widget.selectionHeightStyle,
|
||||
selectionWidthStyle: widget.selectionWidthStyle,
|
||||
paintCursorAboveText: widget.paintCursorAboveText,
|
||||
enableInteractiveSelection: widget.enableInteractiveSelection,
|
||||
textSelectionDelegate: this,
|
||||
|
@ -1962,9 +1978,11 @@ class _Editable extends LeafRenderObjectWidget {
|
|||
this.cursorWidth,
|
||||
this.cursorRadius,
|
||||
this.cursorOffset,
|
||||
this.paintCursorAboveText,
|
||||
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
|
||||
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
|
||||
this.enableInteractiveSelection = true,
|
||||
this.textSelectionDelegate,
|
||||
this.paintCursorAboveText,
|
||||
this.devicePixelRatio,
|
||||
}) : assert(textDirection != null),
|
||||
assert(rendererIgnoresPointer != null),
|
||||
|
@ -2002,10 +2020,12 @@ class _Editable extends LeafRenderObjectWidget {
|
|||
final double cursorWidth;
|
||||
final Radius cursorRadius;
|
||||
final Offset cursorOffset;
|
||||
final bool paintCursorAboveText;
|
||||
final ui.BoxHeightStyle selectionHeightStyle;
|
||||
final ui.BoxWidthStyle selectionWidthStyle;
|
||||
final bool enableInteractiveSelection;
|
||||
final TextSelectionDelegate textSelectionDelegate;
|
||||
final double devicePixelRatio;
|
||||
final bool paintCursorAboveText;
|
||||
|
||||
@override
|
||||
RenderEditable createRenderObject(BuildContext context) {
|
||||
|
@ -2039,6 +2059,8 @@ class _Editable extends LeafRenderObjectWidget {
|
|||
cursorRadius: cursorRadius,
|
||||
cursorOffset: cursorOffset,
|
||||
paintCursorAboveText: paintCursorAboveText,
|
||||
selectionHeightStyle: selectionHeightStyle,
|
||||
selectionWidthStyle: selectionWidthStyle,
|
||||
enableInteractiveSelection: enableInteractiveSelection,
|
||||
textSelectionDelegate: textSelectionDelegate,
|
||||
devicePixelRatio: devicePixelRatio,
|
||||
|
@ -2075,6 +2097,8 @@ class _Editable extends LeafRenderObjectWidget {
|
|||
..cursorWidth = cursorWidth
|
||||
..cursorRadius = cursorRadius
|
||||
..cursorOffset = cursorOffset
|
||||
..selectionHeightStyle = selectionHeightStyle
|
||||
..selectionWidthStyle = selectionWidthStyle
|
||||
..textSelectionDelegate = textSelectionDelegate
|
||||
..devicePixelRatio = devicePixelRatio
|
||||
..paintCursorAboveText = paintCursorAboveText;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, Color;
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
@ -3989,4 +3990,96 @@ void main() {
|
|||
),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('text selection style 1', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure\nhi\nwassssup!',
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Center(
|
||||
child: RepaintBoundary(
|
||||
child: Container(
|
||||
width: 650.0,
|
||||
height: 600.0,
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xff00ff00),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
CupertinoTextField(
|
||||
key: const Key('field0'),
|
||||
controller: controller,
|
||||
style: const TextStyle(height: 4, color: ui.Color.fromARGB(100, 0, 0, 0)),
|
||||
toolbarOptions: const ToolbarOptions(selectAll: true),
|
||||
selectionHeightStyle: ui.BoxHeightStyle.includeLineSpacingTop,
|
||||
selectionWidthStyle: ui.BoxWidthStyle.max,
|
||||
maxLines: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byKey(const Key('field0')));
|
||||
|
||||
await tester.longPressAt(textfieldStart + const Offset(50.0, 2.0));
|
||||
await tester.pump(const Duration(milliseconds: 150));
|
||||
await tester.tapAt(textfieldStart + const Offset(20.0, 146.0));
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
|
||||
await expectLater(
|
||||
find.byType(CupertinoApp),
|
||||
matchesGoldenFile('text_field_golden.TextSelectionStyle.1.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('text selection style 2', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure\nhi\nwassssup!',
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Center(
|
||||
child: RepaintBoundary(
|
||||
child: Container(
|
||||
width: 650.0,
|
||||
height: 600.0,
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xff00ff00),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
CupertinoTextField(
|
||||
key: const Key('field0'),
|
||||
controller: controller,
|
||||
style: const TextStyle(height: 4, color: ui.Color.fromARGB(100, 0, 0, 0)),
|
||||
toolbarOptions: const ToolbarOptions(selectAll: true),
|
||||
selectionHeightStyle: ui.BoxHeightStyle.includeLineSpacingBottom,
|
||||
selectionWidthStyle: ui.BoxWidthStyle.tight,
|
||||
maxLines: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byKey(const Key('field0')));
|
||||
|
||||
await tester.longPressAt(textfieldStart + const Offset(50.0, 2.0));
|
||||
await tester.pump(const Duration(milliseconds: 150));
|
||||
await tester.tapAt(textfieldStart + const Offset(20.0, 146.0));
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
|
||||
await expectLater(
|
||||
find.byType(CupertinoApp),
|
||||
matchesGoldenFile('text_field_golden.TextSelectionStyle.2.png'),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@TestOn('!chrome') // This whole test suite needs triage.
|
||||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
import 'dart:ui' as ui show window;
|
||||
import 'dart:ui' as ui show window, BoxHeightStyle, BoxWidthStyle;
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -489,21 +489,21 @@ void main() {
|
|||
|
||||
testWidgets('text field toolbar options correctly changes options',
|
||||
(WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
toolbarOptions: const ToolbarOptions(copy: true),
|
||||
),
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
toolbarOptions: const ToolbarOptions(copy: true),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
),
|
||||
);
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
|
||||
|
||||
|
@ -536,6 +536,102 @@ void main() {
|
|||
expect(find.text('Select All'), findsNothing);
|
||||
}, skip: isBrowser, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('text selection style 1', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure\nhi\nwasssup!',
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: RepaintBoundary(
|
||||
child: Container(
|
||||
width: 650.0,
|
||||
height: 600.0,
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xff00ff00),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextField(
|
||||
key: const Key('field0'),
|
||||
controller: controller,
|
||||
style: const TextStyle(height: 4, color: Colors.black45),
|
||||
toolbarOptions: const ToolbarOptions(copy: true, selectAll: true),
|
||||
selectionHeightStyle: ui.BoxHeightStyle.includeLineSpacingTop,
|
||||
selectionWidthStyle: ui.BoxWidthStyle.max,
|
||||
maxLines: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byKey(const Key('field0')));
|
||||
|
||||
await tester.longPressAt(textfieldStart + const Offset(50.0, 2.0));
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.tapAt(textfieldStart + const Offset(100.0, 107.0));
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
|
||||
await expectLater(
|
||||
find.byType(MaterialApp),
|
||||
matchesGoldenFile('text_field_golden.TextSelectionStyle.1.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('text selection style 2', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure\nhi\nwasssup!',
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: RepaintBoundary(
|
||||
child: Container(
|
||||
width: 650.0,
|
||||
height: 600.0,
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xff00ff00),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextField(
|
||||
key: const Key('field0'),
|
||||
controller: controller,
|
||||
style: const TextStyle(height: 4, color: Colors.black45),
|
||||
toolbarOptions: const ToolbarOptions(copy: true, selectAll: true),
|
||||
selectionHeightStyle: ui.BoxHeightStyle.includeLineSpacingBottom,
|
||||
selectionWidthStyle: ui.BoxWidthStyle.tight,
|
||||
maxLines: 3,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byKey(const Key('field0')));
|
||||
|
||||
await tester.longPressAt(textfieldStart + const Offset(50.0, 2.0));
|
||||
await tester.pump(const Duration(milliseconds: 50));
|
||||
await tester.tapAt(textfieldStart + const Offset(100.0, 107.0));
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
|
||||
await expectLater(
|
||||
find.byType(MaterialApp),
|
||||
matchesGoldenFile('text_field_golden.TextSelectionStyle.2.png'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('text field toolbar options correctly changes options',
|
||||
(WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
|
|
Loading…
Reference in a new issue