Rich text editor for Flutter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

128 lines
3.3 KiB

import 'dart:math' as math;
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_quill/models/documents/nodes/node.dart';
import 'editor.dart';
TextSelection localSelection(Node node, TextSelection selection, fromParent) {
int base = fromParent ? node.getOffset() : node.getDocumentOffset();
assert(base <= selection.end && selection.start <= base + node.length - 1);
int offset = fromParent ? node.getOffset() : node.getDocumentOffset();
return selection.copyWith(
baseOffset: math.max(selection.start - offset, 0),
extentOffset: math.min(selection.end - offset, node.length - 1));
}
class EditorTextSelectionOverlay {
TextEditingValue value;
bool handlesVisible = false;
final BuildContext context;
final Widget debugRequiredFor;
final LayerLink toolbarLayerLink;
final LayerLink startHandleLayerLink;
final LayerLink endHandleLayerLink;
final RenderEditor renderObject;
final TextSelectionControls selectionCtrls;
final TextSelectionDelegate selectionDelegate;
final DragStartBehavior dragStartBehavior;
final VoidCallback onSelectionHandleTapped;
final ClipboardStatusNotifier clipboardStatus;
AnimationController _toolbarController;
List<OverlayEntry> _handles;
OverlayEntry toolbar;
EditorTextSelectionOverlay(
this.value,
this.handlesVisible,
this.context,
this.debugRequiredFor,
this.toolbarLayerLink,
this.startHandleLayerLink,
this.endHandleLayerLink,
this.renderObject,
this.selectionCtrls,
this.selectionDelegate,
this.dragStartBehavior,
this.onSelectionHandleTapped,
this.clipboardStatus)
: assert(value != null),
assert(context != null),
assert(handlesVisible != null) {
OverlayState overlay = Overlay.of(context, rootOverlay: true);
assert(
overlay != null,
);
_toolbarController = AnimationController(
duration: Duration(milliseconds: 150), vsync: overlay);
}
setHandlesVisible(bool visible) {}
hideHandles() {
if (_handles == null) {
return;
}
_handles[0].remove();
_handles[1].remove();
_handles = null;
}
hideToolbar() {
assert(toolbar != null);
_toolbarController.stop();
toolbar.remove();
toolbar = null;
}
/// Shows the toolbar by inserting it into the [context]'s overlay.
showToolbar() {
assert(toolbar == null);
toolbar = OverlayEntry(builder: _buildToolbar);
Overlay.of(context, rootOverlay: true, debugRequiredFor: debugRequiredFor)
.insert(toolbar);
_toolbarController.forward(from: 0.0);
}
Widget _buildToolbar(BuildContext context) {
if (selectionCtrls == null) {
return Container();
}
}
markNeedsBuild() {
if (_handles != null) {
_handles[0].markNeedsBuild();
_handles[1].markNeedsBuild();
}
toolbar?.markNeedsBuild();
}
hide() {
if (_handles != null) {
_handles[0].remove();
_handles[1].remove();
_handles = null;
}
if (toolbar != null) {
hideToolbar();
}
}
dispose() {
hide();
_toolbarController.dispose();
}
}
class EditorTextSelectionGestureDetector extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
throw UnimplementedError();
}
}