Replace `buildToolbar` with `contextMenuBuilder` (#1106)

pull/1108/head
Adil Hanney 2 years ago committed by GitHub
parent 06d62d61bb
commit 967af17a75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      lib/src/widgets/raw_editor.dart
  2. 84
      lib/src/widgets/text_selection.dart

@ -1050,13 +1050,15 @@ class RawEditorState extends EditorState
value: textEditingValue,
context: context,
debugRequiredFor: widget,
toolbarLayerLink: _toolbarLayerLink,
startHandleLayerLink: _startHandleLayerLink,
endHandleLayerLink: _endHandleLayerLink,
renderObject: renderEditor,
selectionCtrls: widget.selectionCtrls,
selectionDelegate: this,
clipboardStatus: _clipboardStatus,
contextMenuBuilder: widget.contextMenuBuilder == null
? null
: (context) => widget.contextMenuBuilder!(context, this),
);
_selectionOverlay!.handlesVisible = _shouldShowSelectionHandles();
_selectionOverlay!.showHandles();

@ -69,7 +69,6 @@ class EditorTextSelectionOverlay {
EditorTextSelectionOverlay({
required this.value,
required this.context,
required this.toolbarLayerLink,
required this.startHandleLayerLink,
required this.endHandleLayerLink,
required this.renderObject,
@ -77,12 +76,11 @@ class EditorTextSelectionOverlay {
required this.selectionCtrls,
required this.selectionDelegate,
required this.clipboardStatus,
required this.contextMenuBuilder,
this.onSelectionHandleTapped,
this.dragStartBehavior = DragStartBehavior.start,
this.handlesVisible = false,
}) {
final overlay = Overlay.of(context, rootOverlay: true);
// Clipboard status is only checked on first instance of
// ClipboardStatusNotifier
// if state has changed after creation, but prior to
@ -90,9 +88,6 @@ class EditorTextSelectionOverlay {
// we won't know the status unless there is forced update
// i.e. occasionally no paste
clipboardStatus.update();
_toolbarController = AnimationController(
duration: const Duration(milliseconds: 150), vsync: overlay);
}
TextEditingValue value;
@ -122,10 +117,6 @@ class EditorTextSelectionOverlay {
/// Debugging information for explaining why the [Overlay] is required.
final Widget debugRequiredFor;
/// The object supplied to the [CompositedTransformTarget] that wraps the text
/// field.
final LayerLink toolbarLayerLink;
/// The objects supplied to the [CompositedTransformTarget] that wraps the
/// location of start selection handle.
final LayerLink startHandleLayerLink;
@ -144,6 +135,11 @@ class EditorTextSelectionOverlay {
/// text field.
final TextSelectionDelegate selectionDelegate;
/// {@macro flutter.widgets.EditableText.contextMenuBuilder}
///
/// If not provided, no context menu will be built.
final WidgetBuilder? contextMenuBuilder;
/// Determines the way that drag start behavior is handled.
///
/// If set to [DragStartBehavior.start], handle drag behavior will
@ -177,7 +173,6 @@ class EditorTextSelectionOverlay {
/// Useful because the actual value of the clipboard can only be checked
/// asynchronously (see [Clipboard.getData]).
final ClipboardStatusNotifier clipboardStatus;
late AnimationController _toolbarController;
/// A pair of handles. If this is non-null, there are always 2, though the
/// second is hidden when the selection is collapsed.
@ -188,8 +183,6 @@ class EditorTextSelectionOverlay {
TextSelection get _selection => value.selection;
Animation<double> get _toolbarOpacity => _toolbarController.view;
void setHandlesVisible(bool visible) {
if (handlesVisible == visible) {
return;
@ -220,7 +213,6 @@ class EditorTextSelectionOverlay {
/// To hide the whole overlay, see [hide].
void hideToolbar() {
assert(toolbar != null);
_toolbarController.stop();
toolbar!.remove();
toolbar = null;
}
@ -228,10 +220,12 @@ class EditorTextSelectionOverlay {
/// Shows the toolbar by inserting it into the [context]'s overlay.
void showToolbar() {
assert(toolbar == null);
toolbar = OverlayEntry(builder: _buildToolbar);
if (contextMenuBuilder == null) return;
toolbar = OverlayEntry(builder: (context) {
return contextMenuBuilder!(context);
});
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor)
.insert(toolbar!);
_toolbarController.forward(from: 0);
// make sure handles are visible as well
if (_handles == null) {
@ -319,63 +313,6 @@ class EditorTextSelectionOverlay {
..bringIntoView(textPosition);
}
Widget _buildToolbar(BuildContext context) {
// Find the horizontal midpoint, just above the selected text.
List<TextSelectionPoint> endpoints;
try {
// building with an invalid selection with throw an exception
// This happens where the selection has changed, but the toolbar
// hasn't been dismissed yet.
endpoints = renderObject.getEndpointsForSelection(_selection);
} catch (_) {
return Container();
}
final editingRegion = Rect.fromPoints(
renderObject.localToGlobal(Offset.zero),
renderObject.localToGlobal(renderObject.size.bottomRight(Offset.zero)),
);
final baseLineHeight = renderObject.preferredLineHeight(_selection.base);
final extentLineHeight =
renderObject.preferredLineHeight(_selection.extent);
final smallestLineHeight = math.min(baseLineHeight, extentLineHeight);
final isMultiline = endpoints.last.point.dy - endpoints.first.point.dy >
smallestLineHeight / 2;
// If the selected text spans more than 1 line,
// horizontally center the toolbar.
// Derived from both iOS and Android.
final midX = isMultiline
? editingRegion.width / 2
: (endpoints.first.point.dx + endpoints.last.point.dx) / 2;
final midpoint = Offset(
midX,
// The y-coordinate won't be made use of most likely.
endpoints[0].point.dy - baseLineHeight,
);
return FadeTransition(
opacity: _toolbarOpacity,
child: CompositedTransformFollower(
link: toolbarLayerLink,
showWhenUnlinked: false,
offset: -editingRegion.topLeft,
child: selectionCtrls.buildToolbar(
context,
editingRegion,
baseLineHeight,
midpoint,
endpoints,
selectionDelegate,
clipboardStatus,
null),
),
);
}
void markNeedsBuild([Duration? duration]) {
if (_handles != null) {
_handles![0].markNeedsBuild();
@ -399,7 +336,6 @@ class EditorTextSelectionOverlay {
/// Final cleanup.
void dispose() {
hide();
_toolbarController.dispose();
}
/// Builds the handles by inserting them into the [context]'s overlay.

Loading…
Cancel
Save