- Fix selection handles show/hide after paste, backspace, copy (#769)

pull/783/head
Michael Allen 3 years ago committed by GitHub
parent 67381cf311
commit 2b3fa606ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      lib/src/widgets/delegate.dart
  2. 26
      lib/src/widgets/raw_editor.dart
  3. 2
      lib/src/widgets/raw_editor/raw_editor_state_selection_delegate_mixin.dart
  4. 17
      lib/src/widgets/text_selection.dart

@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import '../../flutter_quill.dart';
import 'text_selection.dart';
@ -252,9 +253,17 @@ class EditorTextSelectionGestureDetectorBuilder {
void onDoubleTapDown(TapDownDetails details) {
if (delegate.selectionEnabled) {
renderEditor!.selectWord(SelectionChangedCause.tap);
if (shouldShowSelectionToolbar) {
editor!.showToolbar();
}
// allow the selection to get updated before trying to bring up
// toolbars.
//
// if double tap happens on an editor that doesn't
// have focus, selection hasn't been set when the toolbars
// get added
SchedulerBinding.instance!.addPostFrameCallback((_) {
if (shouldShowSelectionToolbar) {
editor!.showToolbar();
}
});
}
}

@ -759,10 +759,10 @@ class RawEditorState extends EditorState
void _updateOrDisposeSelectionOverlayIfNeeded() {
if (_selectionOverlay != null) {
if (!_hasFocus) {
if (!_hasFocus || textEditingValue.selection.isCollapsed) {
_selectionOverlay!.dispose();
_selectionOverlay = null;
} else if (!textEditingValue.selection.isCollapsed) {
} else {
_selectionOverlay!.update(textEditingValue);
}
} else if (_hasFocus) {
@ -929,10 +929,6 @@ class RawEditorState extends EditorState
if (cause == SelectionChangedCause.toolbar) {
bringIntoView(textEditingValue.selection.extent);
// on iOS, Safari does not hide the selection after copy
// however, most other iOS apps do as well as other platforms
// so we'll hide toolbar & selection after copy
hideToolbar(false);
// Collapse the selection and hide the toolbar and handles.
userUpdateTextEditingValue(
@ -1008,13 +1004,17 @@ class RawEditorState extends EditorState
_replaceText(
ReplaceTextIntent(textEditingValue, data.text!, selection, cause));
if (cause == SelectionChangedCause.toolbar) {
try {
// ignore exception when paste window is at end of document
bringIntoView(textEditingValue.selection.extent);
} catch (_) {}
hideToolbar();
}
bringIntoView(textEditingValue.selection.extent);
// Collapse the selection and hide the toolbar and handles.
userUpdateTextEditingValue(
TextEditingValue(
text: textEditingValue.text,
selection: TextSelection.collapsed(
offset: textEditingValue.selection.end),
),
cause,
);
}
/// Select the entire text value.

@ -136,7 +136,7 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState
void hideToolbar([bool hideHandles = true]) {
// If the toolbar is currently visible.
if (selectionOverlay?.toolbar != null) {
selectionOverlay?.hideToolbar();
hideHandles ? selectionOverlay?.hide() : selectionOverlay?.hideToolbar();
}
}

@ -4,6 +4,7 @@ import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import '../models/documents/nodes/node.dart';
@ -224,6 +225,11 @@ class EditorTextSelectionOverlay {
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor)!
.insert(toolbar!);
_toolbarController.forward(from: 0);
// make sure handles are visible as well
if (_handles == null) {
showHandles();
}
}
Widget _buildHandle(
@ -308,7 +314,16 @@ class EditorTextSelectionOverlay {
Widget _buildToolbar(BuildContext context) {
// Find the horizontal midpoint, just above the selected text.
final endpoints = renderObject.getEndpointsForSelection(_selection);
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),

Loading…
Cancel
Save