|
|
|
@ -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<Node>(); |
|
|
|
|
} |
|
|
|
|
// 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<Node> nodes, |
|
|
|
|
TextStyle lineStyle) { |
|
|
|
|
final children = nodes |
|
|
|
|
.map((node) => _getTextSpanFromNode(defaultStyles, node)) |
|
|
|
|
.toList(growable: false); |
|
|
|
|
TextSpan _buildTextSpan(DefaultStyles defaultStyles, LinkedList<Node> 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<String, Attribute> attributes) { |
|
|
|
|
TextStyle _applyCustomAttributes(TextStyle textStyle, Map<String, Attribute> 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<dynamic, TextDecoration>(decorations))); |
|
|
|
|
return a.merge(b).apply(decoration: TextDecoration.combine(List.castFrom<dynamic, TextDecoration>(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(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|