Skip to content

Commit 4d56bf0

Browse files
authored
refactor: context menu function, add test code (singerdmx#1979)
1 parent e7f7714 commit 4d56bf0

File tree

2 files changed

+76
-9
lines changed

2 files changed

+76
-9
lines changed

lib/src/widgets/others/delegate.dart

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,18 @@ class EditorTextSelectionGestureDetectorBuilder {
8585
/// will return true if current [onTapDown] event is triggered by a touch or
8686
/// a stylus.
8787
bool shouldShowSelectionToolbar = true;
88-
bool requiresAdditionalActionForToolbar = false;
88+
PointerDeviceKind? kind;
89+
90+
/// Check if the selection toolbar should show.
91+
///
92+
/// If mouse is used, the toolbar should only show when right click.
93+
/// Else, it should show when the selection is enabled.
94+
bool checkSelectionToolbarShouldShow({required bool isAdditionalAction}) {
95+
if (kind != PointerDeviceKind.mouse) {
96+
return shouldShowSelectionToolbar;
97+
}
98+
return shouldShowSelectionToolbar && isAdditionalAction;
99+
}
89100

90101
bool detectWordBoundary = true;
91102

@@ -116,14 +127,13 @@ class EditorTextSelectionGestureDetectorBuilder {
116127
// through a touch screen (via either a finger or a stylus).
117128
// A mouse shouldn't trigger the selection overlay.
118129
// For backwards-compatibility, we treat a null kind the same as touch.
119-
final kind = details.kind;
130+
kind = details.kind;
120131
shouldShowSelectionToolbar = kind == null ||
121132
kind ==
122133
PointerDeviceKind
123134
.mouse || // Enable word selection by mouse double tap
124135
kind == PointerDeviceKind.touch ||
125136
kind == PointerDeviceKind.stylus;
126-
requiresAdditionalActionForToolbar = kind == PointerDeviceKind.mouse;
127137
}
128138

129139
/// Handler for [EditorTextSelectionGestureDetector.onForcePressStart].
@@ -169,7 +179,7 @@ class EditorTextSelectionGestureDetectorBuilder {
169179
null,
170180
SelectionChangedCause.forcePress,
171181
);
172-
if (shouldShowSelectionToolbar && !requiresAdditionalActionForToolbar) {
182+
if (checkSelectionToolbarShouldShow(isAdditionalAction: false)) {
173183
editor!.showToolbar();
174184
}
175185
}
@@ -193,7 +203,7 @@ class EditorTextSelectionGestureDetectorBuilder {
193203
@protected
194204
void onSecondarySingleTapUp(TapUpDetails details) {
195205
// added to show toolbar by right click
196-
if (shouldShowSelectionToolbar) {
206+
if (checkSelectionToolbarShouldShow(isAdditionalAction: true)) {
197207
editor!.showToolbar();
198208
}
199209
}
@@ -259,7 +269,7 @@ class EditorTextSelectionGestureDetectorBuilder {
259269
/// which triggers this callback.
260270
@protected
261271
void onSingleLongTapEnd(LongPressEndDetails details) {
262-
if (shouldShowSelectionToolbar && !requiresAdditionalActionForToolbar) {
272+
if (checkSelectionToolbarShouldShow(isAdditionalAction: false)) {
263273
editor!.showToolbar();
264274
}
265275
}
@@ -284,7 +294,7 @@ class EditorTextSelectionGestureDetectorBuilder {
284294
// have focus, selection hasn't been set when the toolbars
285295
// get added
286296
SchedulerBinding.instance.addPostFrameCallback((_) {
287-
if (shouldShowSelectionToolbar && !requiresAdditionalActionForToolbar) {
297+
if (checkSelectionToolbarShouldShow(isAdditionalAction: false)) {
288298
editor!.showToolbar();
289299
}
290300
});
@@ -336,8 +346,7 @@ class EditorTextSelectionGestureDetectorBuilder {
336346
renderEditor!.handleDragEnd(details);
337347
if (isDesktop(supportWeb: true) &&
338348
delegate.selectionEnabled &&
339-
shouldShowSelectionToolbar &&
340-
!requiresAdditionalActionForToolbar) {
349+
checkSelectionToolbarShouldShow(isAdditionalAction: false)) {
341350
// added to show selection copy/paste toolbar after drag to select
342351
editor!.showToolbar();
343352
}

test/bug_fix_test.dart

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'package:flutter/gestures.dart';
12
import 'package:flutter/material.dart';
23
import 'package:flutter_quill/flutter_quill.dart';
34
import 'package:flutter_quill_test/flutter_quill_test.dart';
@@ -128,4 +129,61 @@ void main() {
128129
});
129130
});
130131
});
132+
133+
group('1742 - Disable context menu after selection for desktop platform', () {
134+
late QuillController controller;
135+
136+
setUp(() {
137+
controller = QuillController.basic();
138+
});
139+
140+
tearDown(() {
141+
controller.dispose();
142+
});
143+
144+
for (final device in [PointerDeviceKind.mouse, PointerDeviceKind.touch]) {
145+
testWidgets(
146+
'1742 - Disable context menu after selection for desktop platform $device',
147+
(tester) async {
148+
await tester.pumpWidget(
149+
MaterialApp(
150+
home: QuillEditor(
151+
focusNode: FocusNode(),
152+
scrollController: ScrollController(),
153+
// ignore: avoid_redundant_argument_values
154+
configurations: QuillEditorConfigurations(
155+
controller: controller,
156+
// ignore: avoid_redundant_argument_values
157+
autoFocus: true,
158+
expands: true,
159+
),
160+
),
161+
),
162+
);
163+
if (device == PointerDeviceKind.mouse) {
164+
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
165+
// Long press to show menu
166+
await tester.longPress(find.byType(QuillEditor), kind: device);
167+
await tester.pumpAndSettle();
168+
169+
// Verify custom widget not shows
170+
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
171+
172+
await tester.tap(find.byType(QuillEditor),
173+
buttons: kSecondaryButton, kind: device);
174+
await tester.pumpAndSettle();
175+
176+
// Verify custom widget shows
177+
expect(find.byType(AdaptiveTextSelectionToolbar), findsAny);
178+
} else {
179+
// Long press to show menu
180+
await tester.longPress(find.byType(QuillEditor), kind: device);
181+
await tester.pumpAndSettle();
182+
183+
// Verify custom widget shows
184+
expect(find.byType(AdaptiveTextSelectionToolbar), findsAny);
185+
}
186+
});
187+
}
188+
});
131189
}

0 commit comments

Comments
 (0)