diff --git a/lib/widgets/editor.dart b/lib/widgets/editor.dart index df74e2e7..9991c2a6 100644 --- a/lib/widgets/editor.dart +++ b/lib/widgets/editor.dart @@ -134,6 +134,16 @@ class QuillEditor extends StatefulWidget { final Brightness keyboardAppearance; final ScrollPhysics? scrollPhysics; final ValueChanged? onLaunchUrl; + // Returns whether gesture is handled + final bool Function(TapDownDetails details, TextPosition textPosition)? onTapDown; + // Returns whether gesture is handled + final bool Function(TapUpDetails details, TextPosition textPosition)? onTapUp; + // Returns whether gesture is handled + final bool Function(LongPressStartDetails details, TextPosition textPosition)? onSingleLongTapStart; + // Returns whether gesture is handled + final bool Function(LongPressMoveUpdateDetails details, TextPosition textPosition)? onSingleLongTapMoveUpdate; + // Returns whether gesture is handled + final bool Function(LongPressEndDetails details, TextPosition textPosition)? onSingleLongTapEnd; final EmbedBuilder embedBuilder; const QuillEditor( @@ -155,6 +165,11 @@ class QuillEditor extends StatefulWidget { this.keyboardAppearance = Brightness.light, this.scrollPhysics, this.onLaunchUrl, + this.onTapDown, + this.onTapUp, + this.onSingleLongTapStart, + this.onSingleLongTapMoveUpdate, + this.onSingleLongTapEnd, this.embedBuilder = _defaultEmbedBuilder}); factory QuillEditor.basic( @@ -314,6 +329,15 @@ class _QuillEditorSelectionGestureDetectorBuilder @override void onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) { + if (_state.widget.onSingleLongTapMoveUpdate != null) { + final renderEditor = getRenderEditor(); + if (renderEditor != null) { + if (_state.widget.onSingleLongTapMoveUpdate!(details, renderEditor.getPositionForOffset(details.globalPosition) + )) { + return; + } + } + } if (!delegate.getSelectionEnabled()) { return; } @@ -435,8 +459,30 @@ class _QuillEditorSelectionGestureDetectorBuilder await launch(url); } + @override + void onTapDown(TapDownDetails details) { + if (_state.widget.onTapDown != null) { + final renderEditor = getRenderEditor(); + if (renderEditor != null) { + if (_state.widget.onTapDown!(details, renderEditor.getPositionForOffset(details.globalPosition))) { + return; + } + } + } + super.onTapDown(details); + } + @override void onSingleTapUp(TapUpDetails details) { + if (_state.widget.onTapUp != null) { + final renderEditor = getRenderEditor(); + if (renderEditor != null) { + if (_state.widget.onTapUp!(details, renderEditor.getPositionForOffset(details.globalPosition))) { + return; + } + } + } + getEditor()!.hideToolbar(); bool positionSelected = _onTapping(details); @@ -470,6 +516,15 @@ class _QuillEditorSelectionGestureDetectorBuilder @override void onSingleLongTapStart(LongPressStartDetails details) { + if (_state.widget.onSingleLongTapStart != null) { + final renderEditor = getRenderEditor(); + if (renderEditor != null) { + if (_state.widget.onSingleLongTapStart!(details, renderEditor.getPositionForOffset(details.globalPosition))) { + return; + } + } + } + if (delegate.getSelectionEnabled()) { switch (Theme.of(_state.context).platform) { case TargetPlatform.iOS: @@ -492,6 +547,19 @@ class _QuillEditorSelectionGestureDetectorBuilder } } } + + @override + void onSingleLongTapEnd(LongPressEndDetails details) { + if (_state.widget.onSingleLongTapEnd != null) { + final renderEditor = getRenderEditor(); + if (renderEditor != null) { + if (_state.widget.onSingleLongTapEnd!(details, renderEditor.getPositionForOffset(details.globalPosition))) { + return; + } + } + } + super.onSingleLongTapEnd(details); + } } typedef TextSelectionChangedHandler = void Function( diff --git a/lib/widgets/text_selection.dart b/lib/widgets/text_selection.dart index 8aa29d25..ff733de2 100644 --- a/lib/widgets/text_selection.dart +++ b/lib/widgets/text_selection.dart @@ -533,6 +533,7 @@ class _EditorTextSelectionGestureDetectorState } void _handleTapDown(TapDownDetails details) { + // renderObject.resetTapDownStatus(); if (widget.onTapDown != null) { widget.onTapDown!(details); }