diff --git a/lib/src/widgets/text_line.dart b/lib/src/widgets/text_line.dart index f87645ab..9cc0e45c 100644 --- a/lib/src/widgets/text_line.dart +++ b/lib/src/widgets/text_line.dart @@ -56,16 +56,8 @@ class TextLine extends StatelessWidget { strutStyle: strutStyle, textScaleFactor: MediaQuery.textScaleFactorOf(context), ); - return RichTextProxy( - child, - textSpan.style!, - textAlign, - textDirection!, - 1, - Localizations.localeOf(context), - strutStyle, - TextWidthBasis.parent, - null); + return RichTextProxy(child, textSpan.style!, textAlign, textDirection!, 1, Localizations.localeOf(context), + strutStyle, TextWidthBasis.parent, null); } InlineSpan _getTextSpanForWholeLine(BuildContext context) { @@ -84,8 +76,7 @@ class TextLine extends StatelessWidget { textNodes = LinkedList(); } // Here it should be image - final embed = WidgetSpan( - child: EmbedProxy(embedBuilder(context, child, readOnly))); + final embed = WidgetSpan(child: EmbedProxy(embedBuilder(context, child, readOnly))); textSpanChildren.add(embed); continue; } @@ -115,11 +106,8 @@ class TextLine extends StatelessWidget { return TextAlign.start; } - TextSpan _buildTextSpan(DefaultStyles defaultStyles, LinkedList nodes, - TextStyle lineStyle) { - final children = nodes - .map((node) => _getTextSpanFromNode(defaultStyles, node)) - .toList(growable: false); + TextSpan _buildTextSpan(DefaultStyles defaultStyles, LinkedList nodes, TextStyle lineStyle) { + final children = nodes.map((node) => _getTextSpanFromNode(defaultStyles, node)).toList(growable: false); return TextSpan(children: children, style: lineStyle); } @@ -163,8 +151,7 @@ class TextLine extends StatelessWidget { return textStyle; } - TextStyle _applyCustomAttributes( - TextStyle textStyle, Map attributes) { + TextStyle _applyCustomAttributes(TextStyle textStyle, Map attributes) { if (customStyleBuilder == null) { return textStyle; } @@ -200,8 +187,7 @@ class TextLine extends StatelessWidget { if (color?.value is String) { textColor = stringToColor(color?.value); } - res = _merge(res.copyWith(decorationColor: textColor), - s!.copyWith(decorationColor: textColor)); + res = _merge(res.copyWith(decorationColor: textColor), s!.copyWith(decorationColor: textColor)); } else { res = _merge(res, s!); } @@ -263,9 +249,7 @@ class TextLine extends StatelessWidget { if (b.decoration != null) { decorations.add(b.decoration); } - return a.merge(b).apply( - decoration: TextDecoration.combine( - List.castFrom(decorations))); + return a.merge(b).apply(decoration: TextDecoration.combine(List.castFrom(decorations))); } } @@ -305,21 +289,12 @@ class EditableTextLine extends RenderObjectWidget { @override RenderObject createRenderObject(BuildContext context) { - return RenderEditableTextLine( - line, - textDirection, - textSelection, - enableInteractiveSelection, - hasFocus, - devicePixelRatio, - _getPadding(), - color, - cursorCont); + return RenderEditableTextLine(line, textDirection, textSelection, enableInteractiveSelection, hasFocus, + devicePixelRatio, _getPadding(), color, cursorCont); } @override - void updateRenderObject( - BuildContext context, covariant RenderEditableTextLine renderObject) { + void updateRenderObject(BuildContext context, covariant RenderEditableTextLine renderObject) { renderObject ..setLine(line) ..setPadding(_getPadding()) @@ -333,10 +308,7 @@ class EditableTextLine extends RenderObjectWidget { } EdgeInsetsGeometry _getPadding() { - return EdgeInsetsDirectional.only( - start: indentWidth, - top: verticalSpacing.item1, - bottom: verticalSpacing.item2); + return EdgeInsetsDirectional.only(start: indentWidth, top: verticalSpacing.item1, bottom: verticalSpacing.item2); } } @@ -413,7 +385,7 @@ class RenderEditableTextLine extends RenderEditableBox { color = c; if (containsTextSelection()) { - markNeedsPaint(); + safeMarkNeedsPaint(); } } @@ -425,7 +397,7 @@ class RenderEditableTextLine extends RenderEditableBox { final containsSelection = containsTextSelection(); if (attached && containsCursor()) { cursorCont.removeListener(markNeedsLayout); - cursorCont.color.removeListener(markNeedsPaint); + cursorCont.color.removeListener(safeMarkNeedsPaint); } textSelection = t; @@ -433,11 +405,11 @@ class RenderEditableTextLine extends RenderEditableBox { _containsCursor = null; if (attached && containsCursor()) { cursorCont.addListener(markNeedsLayout); - cursorCont.color.addListener(markNeedsPaint); + cursorCont.color.addListener(safeMarkNeedsPaint); } if (containsSelection || containsTextSelection()) { - markNeedsPaint(); + safeMarkNeedsPaint(); } } @@ -478,17 +450,14 @@ class RenderEditableTextLine extends RenderEditableBox { } bool containsTextSelection() { - return line.documentOffset <= textSelection.end && - textSelection.start <= line.documentOffset + line.length - 1; + return line.documentOffset <= textSelection.end && textSelection.start <= line.documentOffset + line.length - 1; } bool containsCursor() { - return _containsCursor ??= textSelection.isCollapsed && - line.containsOffset(textSelection.baseOffset); + return _containsCursor ??= textSelection.isCollapsed && line.containsOffset(textSelection.baseOffset); } - RenderBox? _updateChild( - RenderBox? old, RenderBox? newChild, TextLineSlot slot) { + RenderBox? _updateChild(RenderBox? old, RenderBox? newChild, TextLineSlot slot) { if (old != null) { dropChild(old); children.remove(slot); @@ -527,46 +496,35 @@ class RenderEditableTextLine extends RenderEditableBox { } @override - TextSelectionPoint getExtentEndpointForSelection( - TextSelection textSelection) { + TextSelectionPoint getExtentEndpointForSelection(TextSelection textSelection) { return _getEndpointForSelection(textSelection, false); } - TextSelectionPoint _getEndpointForSelection( - TextSelection textSelection, bool first) { + TextSelectionPoint _getEndpointForSelection(TextSelection textSelection, bool first) { if (textSelection.isCollapsed) { return TextSelectionPoint( - Offset(0, preferredLineHeight(textSelection.extent)) + - getOffsetForCaret(textSelection.extent), - null); + Offset(0, preferredLineHeight(textSelection.extent)) + getOffsetForCaret(textSelection.extent), null); } final boxes = _getBoxes(textSelection); assert(boxes.isNotEmpty); final targetBox = first ? boxes.first : boxes.last; - return TextSelectionPoint( - Offset(first ? targetBox.start : targetBox.end, targetBox.bottom), - targetBox.direction); + return TextSelectionPoint(Offset(first ? targetBox.start : targetBox.end, targetBox.bottom), targetBox.direction); } @override TextRange getLineBoundary(TextPosition position) { - final lineDy = getOffsetForCaret(position) - .translate(0, 0.5 * preferredLineHeight(position)) - .dy; - final lineBoxes = - _getBoxes(TextSelection(baseOffset: 0, extentOffset: line.length - 1)) - .where((element) => element.top < lineDy && element.bottom > lineDy) - .toList(growable: false); + final lineDy = getOffsetForCaret(position).translate(0, 0.5 * preferredLineHeight(position)).dy; + final lineBoxes = _getBoxes(TextSelection(baseOffset: 0, extentOffset: line.length - 1)) + .where((element) => element.top < lineDy && element.bottom > lineDy) + .toList(growable: false); return TextRange( - start: - getPositionForOffset(Offset(lineBoxes.first.left, lineDy)).offset, + start: getPositionForOffset(Offset(lineBoxes.first.left, lineDy)).offset, end: getPositionForOffset(Offset(lineBoxes.last.right, lineDy)).offset); } @override Offset getOffsetForCaret(TextPosition position) { - return _body!.getOffsetForCaret(position, _caretPrototype) + - (_body!.parentData as BoxParentData).offset; + return _body!.getOffsetForCaret(position, _caretPrototype) + (_body!.parentData as BoxParentData).offset; } @override @@ -581,10 +539,8 @@ class RenderEditableTextLine extends RenderEditableBox { TextPosition? _getPosition(TextPosition textPosition, double dyScale) { assert(textPosition.offset < line.length); - final offset = getOffsetForCaret(textPosition) - .translate(0, dyScale * preferredLineHeight(textPosition)); - if (_body!.size - .contains(offset - (_body!.parentData as BoxParentData).offset)) { + final offset = getOffsetForCaret(textPosition).translate(0, dyScale * preferredLineHeight(textPosition)); + if (_body!.size.contains(offset - (_body!.parentData as BoxParentData).offset)) { return getPositionForOffset(offset); } return null; @@ -592,8 +548,7 @@ class RenderEditableTextLine extends RenderEditableBox { @override TextPosition getPositionForOffset(Offset offset) { - return _body!.getPositionForOffset( - offset - (_body!.parentData as BoxParentData).offset); + return _body!.getPositionForOffset(offset - (_body!.parentData as BoxParentData).offset); } @override @@ -613,9 +568,7 @@ class RenderEditableTextLine extends RenderEditableBox { double get cursorWidth => cursorCont.style.width; - double get cursorHeight => - cursorCont.style.height ?? - preferredLineHeight(const TextPosition(offset: 0)); + double get cursorHeight => cursorCont.style.height ?? preferredLineHeight(const TextPosition(offset: 0)); void _computeCaretPrototype() { switch (defaultTargetPlatform) { @@ -642,7 +595,7 @@ class RenderEditableTextLine extends RenderEditableBox { } if (containsCursor()) { cursorCont.addListener(markNeedsLayout); - cursorCont.color.addListener(markNeedsPaint); + cursorCont.color.addListener(safeMarkNeedsPaint); } } @@ -654,7 +607,7 @@ class RenderEditableTextLine extends RenderEditableBox { } if (containsCursor()) { cursorCont.removeListener(markNeedsLayout); - cursorCont.color.removeListener(markNeedsPaint); + cursorCont.color.removeListener(safeMarkNeedsPaint); } } @@ -690,14 +643,8 @@ class RenderEditableTextLine extends RenderEditableBox { _resolvePadding(); final horizontalPadding = _resolvedPadding!.left + _resolvedPadding!.right; final verticalPadding = _resolvedPadding!.top + _resolvedPadding!.bottom; - final leadingWidth = _leading == null - ? 0 - : _leading!.getMinIntrinsicWidth(height - verticalPadding).ceil(); - final bodyWidth = _body == null - ? 0 - : _body! - .getMinIntrinsicWidth(math.max(0, height - verticalPadding)) - .ceil(); + final leadingWidth = _leading == null ? 0 : _leading!.getMinIntrinsicWidth(height - verticalPadding).ceil(); + final bodyWidth = _body == null ? 0 : _body!.getMinIntrinsicWidth(math.max(0, height - verticalPadding)).ceil(); return horizontalPadding + leadingWidth + bodyWidth; } @@ -706,14 +653,8 @@ class RenderEditableTextLine extends RenderEditableBox { _resolvePadding(); final horizontalPadding = _resolvedPadding!.left + _resolvedPadding!.right; final verticalPadding = _resolvedPadding!.top + _resolvedPadding!.bottom; - final leadingWidth = _leading == null - ? 0 - : _leading!.getMaxIntrinsicWidth(height - verticalPadding).ceil(); - final bodyWidth = _body == null - ? 0 - : _body! - .getMaxIntrinsicWidth(math.max(0, height - verticalPadding)) - .ceil(); + final leadingWidth = _leading == null ? 0 : _leading!.getMaxIntrinsicWidth(height - verticalPadding).ceil(); + final bodyWidth = _body == null ? 0 : _body!.getMaxIntrinsicWidth(math.max(0, height - verticalPadding)).ceil(); return horizontalPadding + leadingWidth + bodyWidth; } @@ -723,9 +664,7 @@ class RenderEditableTextLine extends RenderEditableBox { final horizontalPadding = _resolvedPadding!.left + _resolvedPadding!.right; final verticalPadding = _resolvedPadding!.top + _resolvedPadding!.bottom; if (_body != null) { - return _body! - .getMinIntrinsicHeight(math.max(0, width - horizontalPadding)) + - verticalPadding; + return _body!.getMinIntrinsicHeight(math.max(0, width - horizontalPadding)) + verticalPadding; } return verticalPadding; } @@ -736,9 +675,7 @@ class RenderEditableTextLine extends RenderEditableBox { final horizontalPadding = _resolvedPadding!.left + _resolvedPadding!.right; final verticalPadding = _resolvedPadding!.top + _resolvedPadding!.bottom; if (_body != null) { - return _body! - .getMaxIntrinsicHeight(math.max(0, width - horizontalPadding)) + - verticalPadding; + return _body!.getMaxIntrinsicHeight(math.max(0, width - horizontalPadding)) + verticalPadding; } return verticalPadding; } @@ -746,8 +683,7 @@ class RenderEditableTextLine extends RenderEditableBox { @override double computeDistanceToActualBaseline(TextBaseline baseline) { _resolvePadding(); - return _body!.getDistanceToActualBaseline(baseline)! + - _resolvedPadding!.top; + return _body!.getDistanceToActualBaseline(baseline)! + _resolvedPadding!.top; } @override @@ -767,22 +703,16 @@ class RenderEditableTextLine extends RenderEditableBox { } final innerConstraints = constraints.deflate(_resolvedPadding!); - final indentWidth = textDirection == TextDirection.ltr - ? _resolvedPadding!.left - : _resolvedPadding!.right; + final indentWidth = textDirection == TextDirection.ltr ? _resolvedPadding!.left : _resolvedPadding!.right; _body!.layout(innerConstraints, parentUsesSize: true); - (_body!.parentData as BoxParentData).offset = - Offset(_resolvedPadding!.left, _resolvedPadding!.top); + (_body!.parentData as BoxParentData).offset = Offset(_resolvedPadding!.left, _resolvedPadding!.top); if (_leading != null) { - final leadingConstraints = innerConstraints.copyWith( - minWidth: indentWidth, - maxWidth: indentWidth, - maxHeight: _body!.size.height); + final leadingConstraints = + innerConstraints.copyWith(minWidth: indentWidth, maxWidth: indentWidth, maxHeight: _body!.size.height); _leading!.layout(leadingConstraints, parentUsesSize: true); - (_leading!.parentData as BoxParentData).offset = - Offset(0, _resolvedPadding!.top); + (_leading!.parentData as BoxParentData).offset = Offset(0, _resolvedPadding!.top); } size = constraints.constrain(Size( @@ -822,19 +752,13 @@ class RenderEditableTextLine extends RenderEditableBox { _paintSelection(context, effectiveOffset); } - if (hasFocus && - cursorCont.show.value && - containsCursor() && - !cursorCont.style.paintAboveText) { + if (hasFocus && cursorCont.show.value && containsCursor() && !cursorCont.style.paintAboveText) { _paintCursor(context, effectiveOffset, line.hasEmbed); } context.paintChild(_body!, effectiveOffset); - if (hasFocus && - cursorCont.show.value && - containsCursor() && - cursorCont.style.paintAboveText) { + if (hasFocus && cursorCont.show.value && containsCursor() && cursorCont.style.paintAboveText) { _paintCursor(context, effectiveOffset, line.hasEmbed); } } @@ -848,14 +772,12 @@ class RenderEditableTextLine extends RenderEditableBox { } } - void _paintCursor( - PaintingContext context, Offset effectiveOffset, bool lineHasEmbed) { + void _paintCursor(PaintingContext context, Offset effectiveOffset, bool lineHasEmbed) { final position = TextPosition( offset: textSelection.extentOffset - line.documentOffset, affinity: textSelection.base.affinity, ); - _cursorPainter.paint( - context.canvas, effectiveOffset, position, lineHasEmbed); + _cursorPainter.paint(context.canvas, effectiveOffset, position, lineHasEmbed); } @override @@ -866,8 +788,7 @@ class RenderEditableTextLine extends RenderEditableBox { @override Rect getLocalRectForCaret(TextPosition position) { final caretOffset = getOffsetForCaret(position); - var rect = - Rect.fromLTWH(0, 0, cursorWidth, cursorHeight).shift(caretOffset); + var rect = Rect.fromLTWH(0, 0, cursorWidth, cursorHeight).shift(caretOffset); final cursorOffset = cursorCont.style.offset; // Add additional cursor offset (generally only if on iOS). if (cursorOffset != null) rect = rect.shift(cursorOffset); @@ -876,13 +797,20 @@ class RenderEditableTextLine extends RenderEditableBox { @override TextPosition globalToLocalPosition(TextPosition position) { - assert(getContainer().containsOffset(position.offset), - 'The provided text position is not in the current node'); + assert(getContainer().containsOffset(position.offset), 'The provided text position is not in the current node'); return TextPosition( offset: position.offset - getContainer().documentOffset, affinity: position.affinity, ); } + + void safesafeMarkNeedsPaint() { + if (!attached) { + //Should not paint if it was unattach. + return; + } + markNeedsPaint(); + } } class _TextLineElement extends RenderObjectElement { @@ -894,8 +822,7 @@ class _TextLineElement extends RenderObjectElement { EditableTextLine get widget => super.widget as EditableTextLine; @override - RenderEditableTextLine get renderObject => - super.renderObject as RenderEditableTextLine; + RenderEditableTextLine get renderObject => super.renderObject as RenderEditableTextLine; @override void visitChildren(ElementVisitor visitor) { @@ -942,8 +869,7 @@ class _TextLineElement extends RenderObjectElement { } @override - void moveRenderObjectChild( - RenderObject child, dynamic oldSlot, dynamic newSlot) { + void moveRenderObjectChild(RenderObject child, dynamic oldSlot, dynamic newSlot) { throw UnimplementedError(); }