Unverified Commit 3e1a124e authored by Gary Qian's avatar Gary Qian Committed by GitHub

Expose selectionHeightStyle and selectionWidthStyle on TextFields (#48917)

parent 3aa7a800
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
...@@ -196,10 +198,15 @@ class CupertinoTextField extends StatefulWidget { ...@@ -196,10 +198,15 @@ class CupertinoTextField extends StatefulWidget {
/// ///
/// If specified, the [maxLength] property must be greater than zero. /// 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], /// The [autocorrect], [autofocus], [clearButtonMode], [dragStartBehavior],
/// [expands], [maxLengthEnforced], [obscureText], [prefixMode], [readOnly], /// [expands], [maxLengthEnforced], [obscureText], [prefixMode], [readOnly],
/// [scrollPadding], [suffixMode], [textAlign], and [enableSuggestions] /// [scrollPadding], [suffixMode], [textAlign], [selectionHeightStyle],
/// properties must not be null. /// [selectionWidthStyle], and [enableSuggestions] properties must not be null.
/// ///
/// See also: /// See also:
/// ///
...@@ -252,6 +259,8 @@ class CupertinoTextField extends StatefulWidget { ...@@ -252,6 +259,8 @@ class CupertinoTextField extends StatefulWidget {
this.cursorWidth = 2.0, this.cursorWidth = 2.0,
this.cursorRadius = const Radius.circular(2.0), this.cursorRadius = const Radius.circular(2.0),
this.cursorColor, this.cursorColor,
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
this.keyboardAppearance, this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0), this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.start, this.dragStartBehavior = DragStartBehavior.start,
...@@ -270,6 +279,8 @@ class CupertinoTextField extends StatefulWidget { ...@@ -270,6 +279,8 @@ class CupertinoTextField extends StatefulWidget {
assert(maxLengthEnforced != null), assert(maxLengthEnforced != null),
assert(scrollPadding != null), assert(scrollPadding != null),
assert(dragStartBehavior != null), assert(dragStartBehavior != null),
assert(selectionHeightStyle != null),
assert(selectionWidthStyle != null),
assert(maxLines == null || maxLines > 0), assert(maxLines == null || maxLines > 0),
assert(minLines == null || minLines > 0), assert(minLines == null || minLines > 0),
assert( assert(
...@@ -530,6 +541,16 @@ class CupertinoTextField extends StatefulWidget { ...@@ -530,6 +541,16 @@ class CupertinoTextField extends StatefulWidget {
/// and [CupertinoColors.activeOrange] in the dark theme. /// and [CupertinoColors.activeOrange] in the dark theme.
final Color cursorColor; 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. /// The appearance of the keyboard.
/// ///
/// This setting is only honored on iOS devices. /// This setting is only honored on iOS devices.
...@@ -918,6 +939,8 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK ...@@ -918,6 +939,8 @@ class _CupertinoTextFieldState extends State<CupertinoTextField> with AutomaticK
cursorOffset: cursorOffset, cursorOffset: cursorOffset,
paintCursorAboveText: true, paintCursorAboveText: true,
backgroundCursorColor: CupertinoDynamicColor.resolve(CupertinoColors.inactiveGray, context), backgroundCursorColor: CupertinoDynamicColor.resolve(CupertinoColors.inactiveGray, context),
selectionHeightStyle: widget.selectionHeightStyle,
selectionWidthStyle: widget.selectionWidthStyle,
scrollPadding: widget.scrollPadding, scrollPadding: widget.scrollPadding,
keyboardAppearance: keyboardAppearance, keyboardAppearance: keyboardAppearance,
dragStartBehavior: widget.dragStartBehavior, dragStartBehavior: widget.dragStartBehavior,
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
// 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 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle;
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
...@@ -279,9 +281,15 @@ class TextField extends StatefulWidget { ...@@ -279,9 +281,15 @@ class TextField extends StatefulWidget {
/// The text cursor is not shown if [showCursor] is false or if [showCursor] /// The text cursor is not shown if [showCursor] is false or if [showCursor]
/// is null (the default) and [readOnly] is true. /// 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], /// The [textAlign], [autofocus], [obscureText], [readOnly], [autocorrect],
/// [maxLengthEnforced], [scrollPadding], [maxLines], [maxLength], /// [maxLengthEnforced], [scrollPadding], [maxLines], [maxLength],
/// and [enableSuggestions] arguments must not be null. /// [selectionHeightStyle], [selectionWidthStyle], and [enableSuggestions]
/// arguments must not be null.
/// ///
/// See also: /// See also:
/// ///
...@@ -322,6 +330,8 @@ class TextField extends StatefulWidget { ...@@ -322,6 +330,8 @@ class TextField extends StatefulWidget {
this.cursorWidth = 2.0, this.cursorWidth = 2.0,
this.cursorRadius, this.cursorRadius,
this.cursorColor, this.cursorColor,
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
this.keyboardAppearance, this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0), this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.start, this.dragStartBehavior = DragStartBehavior.start,
...@@ -342,6 +352,8 @@ class TextField extends StatefulWidget { ...@@ -342,6 +352,8 @@ class TextField extends StatefulWidget {
assert(maxLengthEnforced != null), assert(maxLengthEnforced != null),
assert(scrollPadding != null), assert(scrollPadding != null),
assert(dragStartBehavior != null), assert(dragStartBehavior != null),
assert(selectionHeightStyle != null),
assert(selectionWidthStyle != null),
assert(maxLines == null || maxLines > 0), assert(maxLines == null || maxLines > 0),
assert(minLines == null || minLines > 0), assert(minLines == null || minLines > 0),
assert( assert(
...@@ -603,6 +615,16 @@ class TextField extends StatefulWidget { ...@@ -603,6 +615,16 @@ class TextField extends StatefulWidget {
/// depending on [ThemeData.platform]. /// depending on [ThemeData.platform].
final Color cursorColor; 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. /// The appearance of the keyboard.
/// ///
/// This setting is only honored on iOS devices. /// This setting is only honored on iOS devices.
...@@ -1003,6 +1025,8 @@ class _TextFieldState extends State<TextField> implements TextSelectionGestureDe ...@@ -1003,6 +1025,8 @@ class _TextFieldState extends State<TextField> implements TextSelectionGestureDe
cursorWidth: widget.cursorWidth, cursorWidth: widget.cursorWidth,
cursorRadius: cursorRadius, cursorRadius: cursorRadius,
cursorColor: cursorColor, cursorColor: cursorColor,
selectionHeightStyle: widget.selectionHeightStyle,
selectionWidthStyle: widget.selectionWidthStyle,
cursorOpacityAnimates: cursorOpacityAnimates, cursorOpacityAnimates: cursorOpacityAnimates,
cursorOffset: cursorOffset, cursorOffset: cursorOffset,
paintCursorAboveText: paintCursorAboveText, paintCursorAboveText: paintCursorAboveText,
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:math' show min, max; 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/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
...@@ -808,12 +808,28 @@ class TextPainter { ...@@ -808,12 +808,28 @@ class TextPainter {
/// Returns a list of rects that bound the given selection. /// 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 /// A given selection might have more than one rect if this text painter
/// contains bidirectional text because logically contiguous text might not be /// contains bidirectional text because logically contiguous text might not be
/// visually contiguous. /// 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); 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. /// Returns the position within the text for the given pixel offset.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:math' as math; 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/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
...@@ -208,6 +208,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -208,6 +208,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
bool paintCursorAboveText = false, bool paintCursorAboveText = false,
Offset cursorOffset, Offset cursorOffset,
double devicePixelRatio = 1.0, double devicePixelRatio = 1.0,
ui.BoxHeightStyle selectionHeightStyle = ui.BoxHeightStyle.tight,
ui.BoxWidthStyle selectionWidthStyle = ui.BoxWidthStyle.tight,
bool enableInteractiveSelection, bool enableInteractiveSelection,
EdgeInsets floatingCursorAddedMargin = const EdgeInsets.fromLTRB(4, 4, 4, 5), EdgeInsets floatingCursorAddedMargin = const EdgeInsets.fromLTRB(4, 4, 4, 5),
@required this.textSelectionDelegate, @required this.textSelectionDelegate,
...@@ -237,6 +239,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -237,6 +239,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
assert(readOnly != null), assert(readOnly != null),
assert(forceLine != null), assert(forceLine != null),
assert(devicePixelRatio != null), assert(devicePixelRatio != null),
assert(selectionHeightStyle != null),
assert(selectionWidthStyle != null),
_textPainter = TextPainter( _textPainter = TextPainter(
text: text, text: text,
textAlign: textAlign, textAlign: textAlign,
...@@ -262,6 +266,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -262,6 +266,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
_floatingCursorAddedMargin = floatingCursorAddedMargin, _floatingCursorAddedMargin = floatingCursorAddedMargin,
_enableInteractiveSelection = enableInteractiveSelection, _enableInteractiveSelection = enableInteractiveSelection,
_devicePixelRatio = devicePixelRatio, _devicePixelRatio = devicePixelRatio,
_selectionHeightStyle = selectionHeightStyle,
_selectionWidthStyle = selectionWidthStyle,
_startHandleLayerLink = startHandleLayerLink, _startHandleLayerLink = startHandleLayerLink,
_endHandleLayerLink = endHandleLayerLink, _endHandleLayerLink = endHandleLayerLink,
_obscureText = obscureText, _obscureText = obscureText,
...@@ -1094,6 +1100,32 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -1094,6 +1100,32 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
Offset _floatingCursorOffset; Offset _floatingCursorOffset;
TextPosition _floatingCursorTextPosition; 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 /// If false, [describeSemanticsConfiguration] will not set the
/// configuration's cursor motion or set selection callbacks. /// configuration's cursor motion or set selection callbacks.
/// ///
...@@ -1941,7 +1973,7 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -1941,7 +1973,7 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
} }
if (showSelection) { if (showSelection) {
_selectionRects ??= _textPainter.getBoxesForSelection(_selection); _selectionRects ??= _textPainter.getBoxesForSelection(_selection, boxHeightStyle: _selectionHeightStyle, boxWidthStyle: _selectionWidthStyle);
_paintSelection(context.canvas, effectiveOffset); _paintSelection(context.canvas, effectiveOffset);
} }
......
...@@ -342,10 +342,10 @@ class EditableText extends StatefulWidget { ...@@ -342,10 +342,10 @@ class EditableText extends StatefulWidget {
/// The [controller], [focusNode], [obscureText], [autocorrect], [autofocus], /// The [controller], [focusNode], [obscureText], [autocorrect], [autofocus],
/// [showSelectionHandles], [enableInteractiveSelection], [forceLine], /// [showSelectionHandles], [enableInteractiveSelection], [forceLine],
/// [style], [cursorColor], [cursorOpacityAnimates],[backgroundCursorColor], /// [style], [cursorColor], [cursorOpacityAnimates],[backgroundCursorColor],
/// [enableSuggestions], [paintCursorAboveText], [textAlign], /// [enableSuggestions], [paintCursorAboveText], [selectionHeightStyle],
/// [dragStartBehavior], [scrollPadding], [dragStartBehavior], /// [selectionWidthStyle], [textAlign], [dragStartBehavior], [scrollPadding],
/// [toolbarOptions], [rendererIgnoresPointer], and [readOnly] arguments must /// [dragStartBehavior], [toolbarOptions], [rendererIgnoresPointer], and
/// not be null. /// [readOnly] arguments must not be null.
EditableText({ EditableText({
Key key, Key key,
@required this.controller, @required this.controller,
...@@ -389,6 +389,8 @@ class EditableText extends StatefulWidget { ...@@ -389,6 +389,8 @@ class EditableText extends StatefulWidget {
this.cursorOpacityAnimates = false, this.cursorOpacityAnimates = false,
this.cursorOffset, this.cursorOffset,
this.paintCursorAboveText = false, this.paintCursorAboveText = false,
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
this.scrollPadding = const EdgeInsets.all(20.0), this.scrollPadding = const EdgeInsets.all(20.0),
this.keyboardAppearance = Brightness.light, this.keyboardAppearance = Brightness.light,
this.dragStartBehavior = DragStartBehavior.start, this.dragStartBehavior = DragStartBehavior.start,
...@@ -417,6 +419,8 @@ class EditableText extends StatefulWidget { ...@@ -417,6 +419,8 @@ class EditableText extends StatefulWidget {
assert(cursorOpacityAnimates != null), assert(cursorOpacityAnimates != null),
assert(paintCursorAboveText != null), assert(paintCursorAboveText != null),
assert(backgroundCursorColor != null), assert(backgroundCursorColor != null),
assert(selectionHeightStyle != null),
assert(selectionWidthStyle != null),
assert(textAlign != null), assert(textAlign != null),
assert(maxLines == null || maxLines > 0), assert(maxLines == null || maxLines > 0),
assert(minLines == null || minLines > 0), assert(minLines == null || minLines > 0),
...@@ -979,6 +983,16 @@ class EditableText extends StatefulWidget { ...@@ -979,6 +983,16 @@ class EditableText extends StatefulWidget {
///{@macro flutter.rendering.editable.paintCursorOnTop} ///{@macro flutter.rendering.editable.paintCursorOnTop}
final bool paintCursorAboveText; 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. /// The appearance of the keyboard.
/// ///
/// This setting is only honored on iOS devices. /// This setting is only honored on iOS devices.
...@@ -1894,6 +1908,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien ...@@ -1894,6 +1908,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
cursorWidth: widget.cursorWidth, cursorWidth: widget.cursorWidth,
cursorRadius: widget.cursorRadius, cursorRadius: widget.cursorRadius,
cursorOffset: widget.cursorOffset, cursorOffset: widget.cursorOffset,
selectionHeightStyle: widget.selectionHeightStyle,
selectionWidthStyle: widget.selectionWidthStyle,
paintCursorAboveText: widget.paintCursorAboveText, paintCursorAboveText: widget.paintCursorAboveText,
enableInteractiveSelection: widget.enableInteractiveSelection, enableInteractiveSelection: widget.enableInteractiveSelection,
textSelectionDelegate: this, textSelectionDelegate: this,
...@@ -1962,9 +1978,11 @@ class _Editable extends LeafRenderObjectWidget { ...@@ -1962,9 +1978,11 @@ class _Editable extends LeafRenderObjectWidget {
this.cursorWidth, this.cursorWidth,
this.cursorRadius, this.cursorRadius,
this.cursorOffset, this.cursorOffset,
this.paintCursorAboveText,
this.selectionHeightStyle = ui.BoxHeightStyle.tight,
this.selectionWidthStyle = ui.BoxWidthStyle.tight,
this.enableInteractiveSelection = true, this.enableInteractiveSelection = true,
this.textSelectionDelegate, this.textSelectionDelegate,
this.paintCursorAboveText,
this.devicePixelRatio, this.devicePixelRatio,
}) : assert(textDirection != null), }) : assert(textDirection != null),
assert(rendererIgnoresPointer != null), assert(rendererIgnoresPointer != null),
...@@ -2002,10 +2020,12 @@ class _Editable extends LeafRenderObjectWidget { ...@@ -2002,10 +2020,12 @@ class _Editable extends LeafRenderObjectWidget {
final double cursorWidth; final double cursorWidth;
final Radius cursorRadius; final Radius cursorRadius;
final Offset cursorOffset; final Offset cursorOffset;
final bool paintCursorAboveText;
final ui.BoxHeightStyle selectionHeightStyle;
final ui.BoxWidthStyle selectionWidthStyle;
final bool enableInteractiveSelection; final bool enableInteractiveSelection;
final TextSelectionDelegate textSelectionDelegate; final TextSelectionDelegate textSelectionDelegate;
final double devicePixelRatio; final double devicePixelRatio;
final bool paintCursorAboveText;
@override @override
RenderEditable createRenderObject(BuildContext context) { RenderEditable createRenderObject(BuildContext context) {
...@@ -2039,6 +2059,8 @@ class _Editable extends LeafRenderObjectWidget { ...@@ -2039,6 +2059,8 @@ class _Editable extends LeafRenderObjectWidget {
cursorRadius: cursorRadius, cursorRadius: cursorRadius,
cursorOffset: cursorOffset, cursorOffset: cursorOffset,
paintCursorAboveText: paintCursorAboveText, paintCursorAboveText: paintCursorAboveText,
selectionHeightStyle: selectionHeightStyle,
selectionWidthStyle: selectionWidthStyle,
enableInteractiveSelection: enableInteractiveSelection, enableInteractiveSelection: enableInteractiveSelection,
textSelectionDelegate: textSelectionDelegate, textSelectionDelegate: textSelectionDelegate,
devicePixelRatio: devicePixelRatio, devicePixelRatio: devicePixelRatio,
...@@ -2075,6 +2097,8 @@ class _Editable extends LeafRenderObjectWidget { ...@@ -2075,6 +2097,8 @@ class _Editable extends LeafRenderObjectWidget {
..cursorWidth = cursorWidth ..cursorWidth = cursorWidth
..cursorRadius = cursorRadius ..cursorRadius = cursorRadius
..cursorOffset = cursorOffset ..cursorOffset = cursorOffset
..selectionHeightStyle = selectionHeightStyle
..selectionWidthStyle = selectionWidthStyle
..textSelectionDelegate = textSelectionDelegate ..textSelectionDelegate = textSelectionDelegate
..devicePixelRatio = devicePixelRatio ..devicePixelRatio = devicePixelRatio
..paintCursorAboveText = paintCursorAboveText; ..paintCursorAboveText = paintCursorAboveText;
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async'; import 'dart:async';
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, Color;
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
...@@ -3989,4 +3990,96 @@ void main() { ...@@ -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 @@ ...@@ -5,7 +5,7 @@
@TestOn('!chrome') // This whole test suite needs triage. @TestOn('!chrome') // This whole test suite needs triage.
import 'dart:async'; import 'dart:async';
import 'dart:math' as math; 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/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
...@@ -489,21 +489,21 @@ void main() { ...@@ -489,21 +489,21 @@ void main() {
testWidgets('text field toolbar options correctly changes options', testWidgets('text field toolbar options correctly changes options',
(WidgetTester tester) async { (WidgetTester tester) async {
final TextEditingController controller = TextEditingController( final TextEditingController controller = TextEditingController(
text: 'Atwater Peel Sherbrooke Bonaventure', text: 'Atwater Peel Sherbrooke Bonaventure',
); );
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material( home: Material(
child: Center( child: Center(
child: TextField( child: TextField(
controller: controller, controller: controller,
toolbarOptions: const ToolbarOptions(copy: true), toolbarOptions: const ToolbarOptions(copy: true),
),
), ),
), ),
), ),
); ),
);
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField)); final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
...@@ -536,6 +536,102 @@ void main() { ...@@ -536,6 +536,102 @@ void main() {
expect(find.text('Select All'), findsNothing); expect(find.text('Select All'), findsNothing);
}, skip: isBrowser, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS })); }, 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', testWidgets('text field toolbar options correctly changes options',
(WidgetTester tester) async { (WidgetTester tester) async {
final TextEditingController controller = TextEditingController( final TextEditingController controller = TextEditingController(
......
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