Not ready yet

pull/1511/head
Ellet 2 years ago
parent 614bf1a526
commit d5b4aa6c94
No known key found for this signature in database
GPG Key ID: C488CC70BBCEF0D1
  1. 6
      example/lib/pages/home_page.dart
  2. 68
      example/lib/widgets/custom_magnifer.dart
  3. 42
      lib/src/widgets/proxy.dart
  4. 34
      lib/src/widgets/raw_editor/raw_editor_state.dart
  5. 23
      lib/src/widgets/text_line.dart

@ -18,6 +18,7 @@ import 'package:flutter_quill_extensions/presentation/embeds/widgets/image.dart'
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import '../widgets/custom_magnifer.dart';
import '../widgets/time_stamp_embed_widget.dart'; import '../widgets/time_stamp_embed_widget.dart';
import 'read_only_page.dart'; import 'read_only_page.dart';
@ -405,6 +406,11 @@ class _HomePageState extends State<HomePage> {
} }
return QuillEditor( return QuillEditor(
configurations: QuillEditorConfigurations( configurations: QuillEditorConfigurations(
magnifierConfiguration: TextMagnifierConfiguration(
magnifierBuilder: (_, __, magnifierInfo) => CustomMagnifier(
magnifierInfo: magnifierInfo,
),
),
builder: (context, rawEditor) { builder: (context, rawEditor) {
return DropTarget( return DropTarget(
onDragDone: _onDragDone, onDragDone: _onDragDone,

@ -0,0 +1,68 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class CustomMagnifier extends StatelessWidget {
const CustomMagnifier({required this.magnifierInfo, super.key});
static const Size magnifierSize = Size(200, 200);
// This magnifier will consume some text data and position itself
// based on the info in the magnifier.
final ValueNotifier<MagnifierInfo> magnifierInfo;
@override
Widget build(BuildContext context) {
// Use a value listenable builder because we want to rebuild
// every time the text selection info changes.
// `CustomMagnifier` could also be a `StatefulWidget` and call `setState`
// when `magnifierInfo` updates. This would be useful for more complex
// positioning cases.
return ValueListenableBuilder<MagnifierInfo>(
valueListenable: magnifierInfo,
builder: (context, currentMagnifierInfo, _) {
// We want to position the magnifier at the global position of the gesture.
var magnifierPosition = currentMagnifierInfo.globalGesturePosition;
// You may use the `MagnifierInfo` however you'd like:
// In this case, we make sure the magnifier never goes out of the current line bounds.
magnifierPosition = Offset(
clampDouble(
magnifierPosition.dx,
currentMagnifierInfo.currentLineBoundaries.left,
currentMagnifierInfo.currentLineBoundaries.right,
),
clampDouble(
magnifierPosition.dy,
currentMagnifierInfo.currentLineBoundaries.top,
currentMagnifierInfo.currentLineBoundaries.bottom,
),
);
// Finally, align the magnifier to the bottom center. The initial anchor is
// the top left, so subtract bottom center alignment.
magnifierPosition -= Alignment.bottomCenter.alongSize(magnifierSize);
return Positioned(
left: magnifierPosition.dx,
top: magnifierPosition.dy,
child: RawMagnifier(
magnificationScale: 2,
// The focal point starts at the center of the magnifier.
// We probably want to point below the magnifier, so
// offset the focal point by half the magnifier height.
focalPointOffset: Offset(0, magnifierSize.height / 2),
// Decorate it however we'd like!
decoration: const MagnifierDecoration(
shape: StarBorder(
side: BorderSide(
color: Colors.green,
width: 2,
),
),
),
size: magnifierSize,
),
);
});
}
}

@ -129,17 +129,18 @@ class RenderEmbedProxy extends RenderProxyBox implements RenderContentProxyBox {
class RichTextProxy extends SingleChildRenderObjectWidget { class RichTextProxy extends SingleChildRenderObjectWidget {
/// Child argument should be an instance of RichText widget. /// Child argument should be an instance of RichText widget.
const RichTextProxy( const RichTextProxy({
{required RichText super.child, required RichText super.child,
required this.textStyle, required this.textStyle,
required this.textAlign, required this.textAlign,
required this.textDirection, required this.textDirection,
required this.locale, required this.locale,
required this.strutStyle, required this.strutStyle,
this.textScaleFactor = 1.0, this.textScaleFactor = 1.0,
this.textWidthBasis = TextWidthBasis.parent, this.textWidthBasis = TextWidthBasis.parent,
this.textHeightBehavior, this.textHeightBehavior,
super.key}); super.key,
});
final TextStyle textStyle; final TextStyle textStyle;
final TextAlign textAlign; final TextAlign textAlign;
@ -153,15 +154,16 @@ class RichTextProxy extends SingleChildRenderObjectWidget {
@override @override
RenderParagraphProxy createRenderObject(BuildContext context) { RenderParagraphProxy createRenderObject(BuildContext context) {
return RenderParagraphProxy( return RenderParagraphProxy(
null, null,
textStyle, textStyle,
textAlign, textAlign,
textDirection, textDirection,
textScaleFactor, textScaleFactor,
strutStyle, strutStyle,
locale, locale,
textWidthBasis, textWidthBasis,
textHeightBehavior); textHeightBehavior,
);
} }
@override @override

@ -760,7 +760,9 @@ class QuillRawEditorState extends EditorState
} }
EditableTextLine _getEditableTextLineFromNode( EditableTextLine _getEditableTextLineFromNode(
Line node, BuildContext context) { Line node,
BuildContext context,
) {
final textLine = TextLine( final textLine = TextLine(
line: node, line: node,
textDirection: _textDirection, textDirection: _textDirection,
@ -775,18 +777,19 @@ class QuillRawEditorState extends EditorState
customLinkPrefixes: widget.customLinkPrefixes, customLinkPrefixes: widget.customLinkPrefixes,
); );
final editableTextLine = EditableTextLine( final editableTextLine = EditableTextLine(
node, node,
null, null,
textLine, textLine,
0, 0,
_getVerticalSpacingForLine(node, _styles), _getVerticalSpacingForLine(node, _styles),
_textDirection, _textDirection,
controller.selection, controller.selection,
widget.selectionColor, widget.selectionColor,
widget.enableInteractiveSelection, widget.enableInteractiveSelection,
_hasFocus, _hasFocus,
MediaQuery.devicePixelRatioOf(context), MediaQuery.devicePixelRatioOf(context),
_cursorCont); _cursorCont,
);
return editableTextLine; return editableTextLine;
} }
@ -1188,7 +1191,10 @@ class QuillRawEditorState extends EditorState
/// This property is typically used to notify the renderer of input gestures. /// This property is typically used to notify the renderer of input gestures.
@override @override
RenderEditor get renderEditor => RenderEditor get renderEditor =>
_editorKey.currentContext!.findRenderObject() as RenderEditor; (_editorKey.currentContext?.findRenderObject() as RenderEditor?) ??
(throw StateError(
"The _editorKey current context can't be null",
));
/// Express interest in interacting with the keyboard. /// Express interest in interacting with the keyboard.
/// ///

@ -150,8 +150,14 @@ class _TextLineState extends State<TextLine> {
// Creates correct node for custom embed // Creates correct node for custom embed
final lineStyle = _getLineStyle(widget.styles); final lineStyle = _getLineStyle(widget.styles);
return EmbedProxy( return EmbedProxy(
embedBuilder.build(context, widget.controller, embed, widget.readOnly, embedBuilder.build(
false, lineStyle), context,
widget.controller,
embed,
widget.readOnly,
false,
lineStyle,
),
); );
} }
} }
@ -167,12 +173,13 @@ class _TextLineState extends State<TextLine> {
textScaleFactor: MediaQuery.textScaleFactorOf(context), textScaleFactor: MediaQuery.textScaleFactorOf(context),
); );
return RichTextProxy( return RichTextProxy(
textStyle: textSpan.style!, textStyle: textSpan.style!,
textAlign: textAlign, textAlign: textAlign,
textDirection: widget.textDirection!, textDirection: widget.textDirection!,
strutStyle: strutStyle, strutStyle: strutStyle,
locale: Localizations.localeOf(context), locale: Localizations.localeOf(context),
child: child); child: child,
);
} }
InlineSpan _getTextSpanForWholeLine(BuildContext context) { InlineSpan _getTextSpanForWholeLine(BuildContext context) {

Loading…
Cancel
Save