Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbfd23f1

Browse files
Fix selection in readOnly mode, Add magnifier via RawMagnifier widget (#2529)
* enable selection handles in read only mode, added magnifier* hide the context menu when dragging selection handles* added entry to change log file* after a long press (from double tap or drag) make sure magnifier is removed* added dragOffsetNotifier explanation* created [QuillMagnifer] and added a [QuillEditorConfig] parameter quillMangifierBuilder, also added a defaultQuillMagnifierBuilder function, when not specified the magnifier will not be used.---------Co-authored-by: Ellet <echo.ellet@gmail.com>
1 parent5d59de8 commitbfd23f1

File tree

10 files changed

+190
-3
lines changed

10 files changed

+190
-3
lines changed

‎CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
1111
##[Unreleased]
1212

13+
###Fixed
14+
15+
- Can't select text when`readOnly` is true[#2529](https://github.com/singerdmx/flutter-quill/pull/2529).
16+
17+
###Added
18+
19+
- Display magnifier using`RawMagnifier` widget when dragging on iOS/Android[#2529](https://github.com/singerdmx/flutter-quill/pull/2529).
20+
1321
##[11.2.0] - 2025-03-26
1422

1523
###Added

‎lib/flutter_quill.dart‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export 'src/editor/style_widgets/style_widgets.dart';
2727
export'src/editor/widgets/cursor.dart';
2828
export'src/editor/widgets/default_styles.dart';
2929
export'src/editor/widgets/link.dart';
30+
export'src/editor/widgets/text/magnifier.dart';
3031
export'src/editor/widgets/text/utils/text_block_utils.dart';
3132
export'src/editor_toolbar_controller_shared/copy_cut_service/copy_cut_service.dart';
3233
export'src/editor_toolbar_controller_shared/copy_cut_service/copy_cut_service_provider.dart';

‎lib/src/editor/config/editor_config.dart‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import '../raw_editor/raw_editor.dart';
1414
import'../widgets/default_styles.dart';
1515
import'../widgets/delegate.dart';
1616
import'../widgets/link.dart';
17+
import'../widgets/text/magnifier.dart';
1718
import'../widgets/text/utils/text_block_utils.dart';
1819
import'search_config.dart';
1920

@@ -56,6 +57,7 @@ class QuillEditorConfig {
5657
this.enableAlwaysIndentOnTab=false,
5758
this.embedBuilders,
5859
this.textSpanBuilder= defaultSpanBuilder,
60+
this.quillMagnifierBuilder,
5961
this.unknownEmbedBuilder,
6062
@experimentalthis.searchConfig=constQuillSearchConfig(),
6163
this.linkActionPickerDelegate= defaultLinkActionPickerDelegate,
@@ -367,6 +369,14 @@ class QuillEditorConfig {
367369

368370
finalTextSpanBuilder textSpanBuilder;
369371

372+
/// To add a magnifier when selecting, specify a builder that returns the magnfier widget
373+
///
374+
/// The default is no magnifier
375+
///
376+
/// There is a provided magnifier[QuillMagnifier] that is available via the function
377+
/// defaultQuillMagnifierBuilder
378+
finalQuillMagnifierBuilder? quillMagnifierBuilder;
379+
370380
/// See[search](https://github.com/singerdmx/flutter-quill/blob/master/doc/configurations/search.md)
371381
/// page for docs.
372382
@experimental

‎lib/src/editor/editor.dart‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ class QuillEditorState extends State<QuillEditor>
196196
QuillEditorConfigget configurations=> widget.config;
197197
QuillEditorConfigget config=> widget.config;
198198

199+
/// {@macro drag_offset_notifier}
200+
final dragOffsetNotifier= isMobileApp?ValueNotifier<Offset?>(null):null;
201+
199202
@override
200203
voidinitState() {
201204
super.initState();
@@ -260,6 +263,7 @@ class QuillEditorState extends State<QuillEditor>
260263
final child=QuillRawEditor(
261264
key: _editorKey,
262265
controller: controller,
266+
dragOffsetNotifier: dragOffsetNotifier,
263267
config:QuillRawEditorConfig(
264268
characterShortcutEvents: widget.config.characterShortcutEvents,
265269
spaceShortcutEvents: widget.config.spaceShortcutEvents,
@@ -305,6 +309,7 @@ class QuillEditorState extends State<QuillEditor>
305309
scrollPhysics: config.scrollPhysics,
306310
embedBuilder: _getEmbedBuilder,
307311
textSpanBuilder: config.textSpanBuilder,
312+
quillMagnifierBuilder: config.quillMagnifierBuilder,
308313
linkActionPickerDelegate: config.linkActionPickerDelegate,
309314
customStyleBuilder: config.customStyleBuilder,
310315
customRecognizerBuilder: config.customRecognizerBuilder,
@@ -330,6 +335,8 @@ class QuillEditorState extends State<QuillEditor>
330335
behavior:HitTestBehavior.translucent,
331336
detectWordBoundary: config.detectWordBoundary,
332337
child: child,
338+
dragOffsetNotifier: dragOffsetNotifier,
339+
quillMagnifierBuilder: config.quillMagnifierBuilder,
333340
)
334341
: child;
335342

‎lib/src/editor/raw_editor/config/raw_editor_config.dart‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import '../../../editor/widgets/default_styles.dart';
1212
import'../../../editor/widgets/delegate.dart';
1313
import'../../../editor/widgets/link.dart';
1414
import'../../../toolbar/theme/quill_dialog_theme.dart';
15+
import'../../widgets/text/magnifier.dart';
1516
import'../../widgets/text/utils/text_block_utils.dart';
1617
import'../builders/leading_block_builder.dart';
1718
import'events/events.dart';
@@ -70,6 +71,7 @@ class QuillRawEditorConfig {
7071
this.readOnlyMouseCursor=SystemMouseCursors.text,
7172
this.onPerformAction,
7273
@experimentalthis.customLeadingBuilder,
74+
this.quillMagnifierBuilder,
7375
});
7476

7577
/// Controls whether this editor has keyboard focus.
@@ -408,4 +410,7 @@ class QuillRawEditorConfig {
408410

409411
/// Called when a text input action is performed.
410412
finalvoidFunction(TextInputAction action)? onPerformAction;
413+
414+
/// Used to build the[QuillMagnifier] when long-pressing/dragging selection
415+
finalQuillMagnifierBuilder? quillMagnifierBuilder;
411416
}

‎lib/src/editor/raw_editor/raw_editor.dart‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class QuillRawEditor extends StatefulWidget {
1111
QuillRawEditor({
1212
requiredthis.config,
1313
requiredthis.controller,
14+
this.dragOffsetNotifier,
1415
super.key,
1516
}):assert(config.maxHeight==null|| config.maxHeight!>0,
1617
'maxHeight cannot be null'),
@@ -25,6 +26,28 @@ class QuillRawEditor extends StatefulWidget {
2526
finalQuillController controller;
2627
finalQuillRawEditorConfig config;
2728

29+
/// {@template drag_offset_notifier}
30+
/// dragOffsetNotifier - Only used on iOS and Android
31+
///
32+
///[QuillRawEditor] contains a gesture detector[EditorTextSelectionGestureDetector]
33+
/// within it's widget tree that includes a[RawMagnifier]. The RawMagnifier needs
34+
/// the current position of selection drag events in order to display the magnifier
35+
/// in the correct location. Setting the position to null will hide the magnifier.
36+
///
37+
/// Initial selection events are posted by[EditorTextSelectionGestureDetector]. Once
38+
/// a selection has been created, dragging the selection handles happens in
39+
///[EditorTextSelectionOverlay].
40+
///
41+
/// Both[EditorTextSelectionGestureDetector] and[EditorTextSelectionOverlay] will update
42+
/// the value of the dragOffsetNotifier.
43+
///
44+
/// The[EditorTextSelectionGestureDetector] will use the value to display the magnifier in
45+
/// the correct location (or hide the magnifier if null).[EditorTextSelectionOverlay] will
46+
/// use the value of the dragOffsetNotifier to hide the context menu when the magnifier is
47+
/// displayed and show the context menu when dragging is complete.
48+
/// {@endtemplate}
49+
finalValueNotifier<Offset?>? dragOffsetNotifier;
50+
2851
@override
2952
State<StatefulWidget>createState()=>QuillRawEditorState();
3053
}

‎lib/src/editor/raw_editor/raw_editor_state.dart‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -853,8 +853,9 @@ class QuillRawEditorState extends EditorState
853853
});
854854
}
855855

856+
controller.addListener(_didChangeTextEditingValueListener);
857+
856858
if (!widget.config.readOnly) {
857-
controller.addListener(_didChangeTextEditingValueListener);
858859
// listen to composing range changes
859860
composingRange.addListener(_onComposingRangeChanged);
860861
// Focus
@@ -965,8 +966,8 @@ class QuillRawEditorState extends EditorState
965966
assert(!hasConnection);
966967
_selectionOverlay?.dispose();
967968
_selectionOverlay=null;
969+
controller.removeListener(_didChangeTextEditingValueListener);
968970
if (!widget.config.readOnly) {
969-
controller.removeListener(_didChangeTextEditingValueListener);
970971
widget.config.focusNode.removeListener(_handleFocusChanged);
971972
composingRange.removeListener(_onComposingRangeChanged);
972973
}
@@ -1081,6 +1082,7 @@ class QuillRawEditorState extends EditorState
10811082
contextMenuBuilder: widget.config.contextMenuBuilder==null
10821083
?null
10831084
: (context)=> widget.config.contextMenuBuilder!(context,this),
1085+
dragOffsetNotifier: widget.dragOffsetNotifier,
10841086
);
10851087
_selectionOverlay!.handlesVisible=_shouldShowSelectionHandles();
10861088
_selectionOverlay!.showHandles();

‎lib/src/editor/widgets/delegate.dart‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import '../../document/attribute.dart';
88
import'../../document/nodes/leaf.dart';
99
import'../editor.dart';
1010
import'../raw_editor/raw_editor.dart';
11+
import'text/magnifier.dart';
1112
import'text/text_selection.dart';
1213

1314
typedefCustomStyleBuilder=TextStyleFunction(Attribute attribute);
@@ -361,6 +362,8 @@ class EditorTextSelectionGestureDetectorBuilder {
361362
requiredWidget child,
362363
Key? key,
363364
bool detectWordBoundary=true,
365+
ValueNotifier<Offset?>? dragOffsetNotifier,
366+
QuillMagnifierBuilder? quillMagnifierBuilder,
364367
}) {
365368
returnEditorTextSelectionGestureDetector(
366369
key: key,
@@ -379,6 +382,8 @@ class EditorTextSelectionGestureDetectorBuilder {
379382
onDragSelectionEnd: onDragSelectionEnd,
380383
behavior: behavior,
381384
detectWordBoundary: detectWordBoundary,
385+
dragOffsetNotifier: dragOffsetNotifier,
386+
quillMagnifierBuilder: quillMagnifierBuilder,
382387
child: child,
383388
);
384389
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import'package:flutter/material.dart';
2+
3+
typedefQuillMagnifierBuilder=WidgetFunction(Offset dragPosition);
4+
5+
WidgetdefaultQuillMagnifierBuilder(Offset dragPosition)=>
6+
QuillMagnifier(dragPosition: dragPosition);
7+
8+
classQuillMagnifierextendsStatelessWidget {
9+
constQuillMagnifier({requiredthis.dragPosition,super.key});
10+
11+
finalOffset dragPosition;
12+
13+
@override
14+
Widgetbuild(BuildContext context) {
15+
final position= dragPosition.translate(-60,-80);
16+
returnPositioned(
17+
top: position.dy,
18+
left: position.dx,
19+
child:Container(
20+
decoration:BoxDecoration(
21+
borderRadius:BorderRadius.circular(20),
22+
),
23+
child:RawMagnifier(
24+
clipBehavior:Clip.hardEdge,
25+
decoration:MagnifierDecoration(
26+
shape:RoundedRectangleBorder(borderRadius:BorderRadius.circular(20)),
27+
shadows:const [
28+
BoxShadow(
29+
color:Colors.black26,
30+
spreadRadius:2,
31+
blurRadius:5,
32+
offset:Offset(3,3),// changes position of shadow
33+
),
34+
],
35+
),
36+
size:constSize(100,45),
37+
focalPointOffset:constOffset(5,55),
38+
magnificationScale:1.3,
39+
),
40+
),
41+
);
42+
}
43+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp