From 4d0a258c229a1e13ceedee5611d9bfc5accd1ac2 Mon Sep 17 00:00:00 2001 From: kfdykme Date: Sun, 11 Aug 2024 15:22:30 +0800 Subject: [PATCH 1/5] feature: enanble custom TextSelectionControls --- packages/fleather/lib/src/widgets/editor.dart | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/fleather/lib/src/widgets/editor.dart b/packages/fleather/lib/src/widgets/editor.dart index 43379301..52178668 100644 --- a/packages/fleather/lib/src/widgets/editor.dart +++ b/packages/fleather/lib/src/widgets/editor.dart @@ -286,6 +286,8 @@ class FleatherEditor extends StatefulWidget { final GlobalKey? editorKey; + final TextSelectionControls? textSelectionControls; + const FleatherEditor({ super.key, required this.controller, @@ -314,6 +316,7 @@ class FleatherEditor extends StatefulWidget { this.contextMenuBuilder = defaultContextMenuBuilder, this.embedBuilder = defaultFleatherEmbedBuilder, this.linkActionPickerDelegate = defaultLinkActionPickerDelegate, + this.textSelectionControls }); @override @@ -412,10 +415,11 @@ class _FleatherEditorState extends State final keyboardAppearance = widget.keyboardAppearance ?? theme.brightness; + switch (theme.platform) { case TargetPlatform.iOS: final cupertinoTheme = CupertinoTheme.of(context); - textSelectionControls = cupertinoTextSelectionControls; + textSelectionControls = widget.textSelectionControls ?? cupertinoTextSelectionControls; paintCursorAboveText = true; cursorOpacityAnimates = true; cursorColor = selectionTheme.cursorColor ?? cupertinoTheme.primaryColor; @@ -428,7 +432,7 @@ class _FleatherEditorState extends State case TargetPlatform.macOS: final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context); - textSelectionControls = cupertinoDesktopTextSelectionControls; + textSelectionControls = widget.textSelectionControls ?? cupertinoDesktopTextSelectionControls; paintCursorAboveText = true; cursorOpacityAnimates = false; cursorColor = selectionTheme.cursorColor ?? cupertinoTheme.primaryColor; @@ -441,7 +445,7 @@ class _FleatherEditorState extends State case TargetPlatform.android: case TargetPlatform.fuchsia: - textSelectionControls = materialTextSelectionControls; + textSelectionControls = widget.textSelectionControls ?? materialTextSelectionControls; paintCursorAboveText = false; cursorOpacityAnimates = false; cursorColor = selectionTheme.cursorColor ?? theme.colorScheme.primary; @@ -451,7 +455,7 @@ class _FleatherEditorState extends State case TargetPlatform.linux: case TargetPlatform.windows: - textSelectionControls = desktopTextSelectionControls; + textSelectionControls = widget.textSelectionControls ?? desktopTextSelectionControls; paintCursorAboveText = false; cursorOpacityAnimates = false; cursorColor = selectionTheme.cursorColor ?? theme.colorScheme.primary; From eb4388e3efb8c330d1666d5fcd6f305f64af710b Mon Sep 17 00:00:00 2001 From: kfdykme Date: Sun, 11 Aug 2024 17:38:16 +0800 Subject: [PATCH 2/5] feature: enanble custom TextSelectionControls - add test --- ...ditor_text_selection_controllers_test.dart | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 packages/fleather/test/widgets/editor_text_selection_controllers_test.dart diff --git a/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart b/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart new file mode 100644 index 00000000..c7d85d91 --- /dev/null +++ b/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart @@ -0,0 +1,89 @@ +import 'dart:math' as math; + +import 'package:fleather/fleather.dart'; +import 'package:fleather/src/widgets/editor_input_client_mixin.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import '../testing.dart'; + +class MyTextSelectionHandle extends StatefulWidget { + final Size size; + const MyTextSelectionHandle( + {super.key, required this.size}); + + @override + State createState() { + return MyTextSelectionHandleState(); + } +} + +class MyTextSelectionHandleState + extends State { + @override + Widget build(BuildContext context) { + return Container( + width: widget.size.width, + height: widget.size.height, + color: Colors.red, + ); + } +} + +class MyTextSelectionControllers + extends MaterialTextSelectionControls { + final Size size; + MyTextSelectionControllers(this.size); + + @override + Widget buildHandle(BuildContext context, + TextSelectionHandleType type, double textHeight, + [VoidCallback? onTap]) { + final Widget handle = MyTextSelectionHandle( + size: size, + ); + + return switch (type) { + TextSelectionHandleType.left => Transform.rotate( + angle: math.pi / 2.0, + child: handle), // points up-right + TextSelectionHandleType.right => + handle, // points up-left + TextSelectionHandleType.collapsed => Transform.rotate( + angle: math.pi / 4.0, child: handle), // points up + }; + } +} + +void main() { + group('CustomTextSelectionControllers', () { + + testWidgets('set customTextSelectionControllers', + (tester) async { + final document = ParchmentDocument.fromJson([ + {'insert': 'some text\n'} + ]); + FleatherController controller = + FleatherController(document: document); + FocusNode focusNode = FocusNode(); + final Size testSize = Size(230, 5); + final editor = MaterialApp( + home: FleatherEditor( + controller: controller, + focusNode: focusNode, + textSelectionControls: + MyTextSelectionControllers(testSize)), + ); + await tester.pumpWidget(editor); + await tester.tap(find.byType(RawEditor).first); + await tester.pumpAndSettle(); + expect(focusNode.hasFocus, isTrue); + tester.binding.scheduleWarmUpFrame(); + final handleState = + tester.state(find.byType(MyTextSelectionHandle)) + as MyTextSelectionHandleState; + expect(handleState.context.size, testSize); + }); + }); +} From 67ae8053d6e8a26fa053735150ad7f4b4df9274b Mon Sep 17 00:00:00 2001 From: kfdykme Date: Sun, 11 Aug 2024 19:52:32 +0800 Subject: [PATCH 3/5] feature: enanble custom TextSelectionControls - format code --- packages/fleather/lib/src/widgets/editor.dart | 72 ++++++++++--------- ...ditor_text_selection_controllers_test.dart | 42 +++++------ 2 files changed, 53 insertions(+), 61 deletions(-) diff --git a/packages/fleather/lib/src/widgets/editor.dart b/packages/fleather/lib/src/widgets/editor.dart index 52178668..17374de9 100644 --- a/packages/fleather/lib/src/widgets/editor.dart +++ b/packages/fleather/lib/src/widgets/editor.dart @@ -288,36 +288,35 @@ class FleatherEditor extends StatefulWidget { final TextSelectionControls? textSelectionControls; - const FleatherEditor({ - super.key, - required this.controller, - this.editorKey, - this.focusNode, - this.scrollController, - this.scrollable = true, - this.padding = EdgeInsets.zero, - this.autofocus = false, - this.showCursor = true, - this.readOnly = false, - this.autocorrect = true, - this.enableSuggestions = true, - this.enableInteractiveSelection = true, - this.minHeight, - this.maxHeight, - this.maxContentWidth, - this.expands = false, - this.textCapitalization = TextCapitalization.sentences, - this.keyboardAppearance, - this.scrollPhysics, - this.onLaunchUrl, - this.spellCheckConfiguration, - this.clipboardManager = const PlainTextClipboardManager(), - this.clipboardStatus, - this.contextMenuBuilder = defaultContextMenuBuilder, - this.embedBuilder = defaultFleatherEmbedBuilder, - this.linkActionPickerDelegate = defaultLinkActionPickerDelegate, - this.textSelectionControls - }); + const FleatherEditor( + {super.key, + required this.controller, + this.editorKey, + this.focusNode, + this.scrollController, + this.scrollable = true, + this.padding = EdgeInsets.zero, + this.autofocus = false, + this.showCursor = true, + this.readOnly = false, + this.autocorrect = true, + this.enableSuggestions = true, + this.enableInteractiveSelection = true, + this.minHeight, + this.maxHeight, + this.maxContentWidth, + this.expands = false, + this.textCapitalization = TextCapitalization.sentences, + this.keyboardAppearance, + this.scrollPhysics, + this.onLaunchUrl, + this.spellCheckConfiguration, + this.clipboardManager = const PlainTextClipboardManager(), + this.clipboardStatus, + this.contextMenuBuilder = defaultContextMenuBuilder, + this.embedBuilder = defaultFleatherEmbedBuilder, + this.linkActionPickerDelegate = defaultLinkActionPickerDelegate, + this.textSelectionControls}); @override State createState() => _FleatherEditorState(); @@ -415,11 +414,11 @@ class _FleatherEditorState extends State final keyboardAppearance = widget.keyboardAppearance ?? theme.brightness; - switch (theme.platform) { case TargetPlatform.iOS: final cupertinoTheme = CupertinoTheme.of(context); - textSelectionControls = widget.textSelectionControls ?? cupertinoTextSelectionControls; + textSelectionControls = + widget.textSelectionControls ?? cupertinoTextSelectionControls; paintCursorAboveText = true; cursorOpacityAnimates = true; cursorColor = selectionTheme.cursorColor ?? cupertinoTheme.primaryColor; @@ -432,7 +431,8 @@ class _FleatherEditorState extends State case TargetPlatform.macOS: final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context); - textSelectionControls = widget.textSelectionControls ?? cupertinoDesktopTextSelectionControls; + textSelectionControls = widget.textSelectionControls ?? + cupertinoDesktopTextSelectionControls; paintCursorAboveText = true; cursorOpacityAnimates = false; cursorColor = selectionTheme.cursorColor ?? cupertinoTheme.primaryColor; @@ -445,7 +445,8 @@ class _FleatherEditorState extends State case TargetPlatform.android: case TargetPlatform.fuchsia: - textSelectionControls = widget.textSelectionControls ?? materialTextSelectionControls; + textSelectionControls = + widget.textSelectionControls ?? materialTextSelectionControls; paintCursorAboveText = false; cursorOpacityAnimates = false; cursorColor = selectionTheme.cursorColor ?? theme.colorScheme.primary; @@ -455,7 +456,8 @@ class _FleatherEditorState extends State case TargetPlatform.linux: case TargetPlatform.windows: - textSelectionControls = widget.textSelectionControls ?? desktopTextSelectionControls; + textSelectionControls = + widget.textSelectionControls ?? desktopTextSelectionControls; paintCursorAboveText = false; cursorOpacityAnimates = false; cursorColor = selectionTheme.cursorColor ?? theme.colorScheme.primary; diff --git a/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart b/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart index c7d85d91..6f845fce 100644 --- a/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart +++ b/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart @@ -10,8 +10,7 @@ import '../testing.dart'; class MyTextSelectionHandle extends StatefulWidget { final Size size; - const MyTextSelectionHandle( - {super.key, required this.size}); + const MyTextSelectionHandle({super.key, required this.size}); @override State createState() { @@ -19,8 +18,7 @@ class MyTextSelectionHandle extends StatefulWidget { } } -class MyTextSelectionHandleState - extends State { +class MyTextSelectionHandleState extends State { @override Widget build(BuildContext context) { return Container( @@ -31,14 +29,13 @@ class MyTextSelectionHandleState } } -class MyTextSelectionControllers - extends MaterialTextSelectionControls { +class MyTextSelectionControllers extends MaterialTextSelectionControls { final Size size; MyTextSelectionControllers(this.size); @override - Widget buildHandle(BuildContext context, - TextSelectionHandleType type, double textHeight, + Widget buildHandle( + BuildContext context, TextSelectionHandleType type, double textHeight, [VoidCallback? onTap]) { final Widget handle = MyTextSelectionHandle( size: size, @@ -46,43 +43,36 @@ class MyTextSelectionControllers return switch (type) { TextSelectionHandleType.left => Transform.rotate( - angle: math.pi / 2.0, - child: handle), // points up-right - TextSelectionHandleType.right => - handle, // points up-left - TextSelectionHandleType.collapsed => Transform.rotate( - angle: math.pi / 4.0, child: handle), // points up + angle: math.pi / 2.0, child: handle), // points up-right + TextSelectionHandleType.right => handle, // points up-left + TextSelectionHandleType.collapsed => + Transform.rotate(angle: math.pi / 4.0, child: handle), // points up }; } } void main() { - group('CustomTextSelectionControllers', () { - - testWidgets('set customTextSelectionControllers', - (tester) async { + group('CustomTextSelectionControllers', () { + testWidgets('set customTextSelectionControllers', (tester) async { final document = ParchmentDocument.fromJson([ {'insert': 'some text\n'} ]); - FleatherController controller = - FleatherController(document: document); + FleatherController controller = FleatherController(document: document); FocusNode focusNode = FocusNode(); final Size testSize = Size(230, 5); final editor = MaterialApp( home: FleatherEditor( controller: controller, focusNode: focusNode, - textSelectionControls: - MyTextSelectionControllers(testSize)), - ); + textSelectionControls: MyTextSelectionControllers(testSize)), + ); await tester.pumpWidget(editor); await tester.tap(find.byType(RawEditor).first); await tester.pumpAndSettle(); expect(focusNode.hasFocus, isTrue); tester.binding.scheduleWarmUpFrame(); - final handleState = - tester.state(find.byType(MyTextSelectionHandle)) - as MyTextSelectionHandleState; + final handleState = tester.state(find.byType(MyTextSelectionHandle)) + as MyTextSelectionHandleState; expect(handleState.context.size, testSize); }); }); From acf7f641a7cc282f62c9d448f1e7d49c4bc89bab Mon Sep 17 00:00:00 2001 From: kfdykme Date: Sun, 11 Aug 2024 21:01:56 +0800 Subject: [PATCH 4/5] feature: enanble custom TextSelectionControls. fix analyze --- .../test/widgets/editor_text_selection_controllers_test.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart b/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart index 6f845fce..6eb29092 100644 --- a/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart +++ b/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart @@ -1,12 +1,8 @@ import 'dart:math' as math; import 'package:fleather/fleather.dart'; -import 'package:fleather/src/widgets/editor_input_client_mixin.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import '../testing.dart'; class MyTextSelectionHandle extends StatefulWidget { final Size size; From 8879fadf400ae52fd6dfa05da20281eea74c3fe3 Mon Sep 17 00:00:00 2001 From: kfdykme Date: Sun, 11 Aug 2024 22:44:59 +0800 Subject: [PATCH 5/5] feature: enanble custom TextSelectionControls. fix analyze --- .../test/widgets/editor_text_selection_controllers_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart b/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart index 6eb29092..4ebe749c 100644 --- a/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart +++ b/packages/fleather/test/widgets/editor_text_selection_controllers_test.dart @@ -55,7 +55,7 @@ void main() { ]); FleatherController controller = FleatherController(document: document); FocusNode focusNode = FocusNode(); - final Size testSize = Size(230, 5); + const Size testSize = Size(230, 5); final editor = MaterialApp( home: FleatherEditor( controller: controller,