|
|
@ -53,9 +53,9 @@ abstract class EditorState extends State<RawEditor> { |
|
|
|
|
|
|
|
|
|
|
|
void setTextEditingValue(TextEditingValue value); |
|
|
|
void setTextEditingValue(TextEditingValue value); |
|
|
|
|
|
|
|
|
|
|
|
RenderEditor getRenderEditor(); |
|
|
|
RenderEditor? getRenderEditor(); |
|
|
|
|
|
|
|
|
|
|
|
EditorTextSelectionOverlay getSelectionOverlay(); |
|
|
|
EditorTextSelectionOverlay? getSelectionOverlay(); |
|
|
|
|
|
|
|
|
|
|
|
bool showToolbar(); |
|
|
|
bool showToolbar(); |
|
|
|
|
|
|
|
|
|
|
@ -146,35 +146,35 @@ class QuillEditor extends StatefulWidget { |
|
|
|
final bool scrollable; |
|
|
|
final bool scrollable; |
|
|
|
final EdgeInsetsGeometry padding; |
|
|
|
final EdgeInsetsGeometry padding; |
|
|
|
final bool autoFocus; |
|
|
|
final bool autoFocus; |
|
|
|
final bool showCursor; |
|
|
|
final bool? showCursor; |
|
|
|
final bool readOnly; |
|
|
|
final bool readOnly; |
|
|
|
final String placeholder; |
|
|
|
final String? placeholder; |
|
|
|
final bool enableInteractiveSelection; |
|
|
|
final bool? enableInteractiveSelection; |
|
|
|
final double minHeight; |
|
|
|
final double? minHeight; |
|
|
|
final double maxHeight; |
|
|
|
final double? maxHeight; |
|
|
|
final DefaultStyles customStyles; |
|
|
|
final DefaultStyles? customStyles; |
|
|
|
final bool expands; |
|
|
|
final bool expands; |
|
|
|
final TextCapitalization textCapitalization; |
|
|
|
final TextCapitalization textCapitalization; |
|
|
|
final Brightness keyboardAppearance; |
|
|
|
final Brightness keyboardAppearance; |
|
|
|
final ScrollPhysics scrollPhysics; |
|
|
|
final ScrollPhysics? scrollPhysics; |
|
|
|
final ValueChanged<String> onLaunchUrl; |
|
|
|
final ValueChanged<String>? onLaunchUrl; |
|
|
|
final EmbedBuilder embedBuilder; |
|
|
|
final EmbedBuilder embedBuilder; |
|
|
|
|
|
|
|
|
|
|
|
QuillEditor( |
|
|
|
QuillEditor( |
|
|
|
{@required this.controller, |
|
|
|
{required this.controller, |
|
|
|
@required this.focusNode, |
|
|
|
required this.focusNode, |
|
|
|
@required this.scrollController, |
|
|
|
required this.scrollController, |
|
|
|
@required this.scrollable, |
|
|
|
required this.scrollable, |
|
|
|
@required this.padding, |
|
|
|
required this.padding, |
|
|
|
@required this.autoFocus, |
|
|
|
required this.autoFocus, |
|
|
|
this.showCursor, |
|
|
|
this.showCursor, |
|
|
|
@required this.readOnly, |
|
|
|
required this.readOnly, |
|
|
|
this.placeholder, |
|
|
|
this.placeholder, |
|
|
|
this.enableInteractiveSelection, |
|
|
|
this.enableInteractiveSelection, |
|
|
|
this.minHeight, |
|
|
|
this.minHeight, |
|
|
|
this.maxHeight, |
|
|
|
this.maxHeight, |
|
|
|
this.customStyles, |
|
|
|
this.customStyles, |
|
|
|
@required this.expands, |
|
|
|
required this.expands, |
|
|
|
this.textCapitalization = TextCapitalization.sentences, |
|
|
|
this.textCapitalization = TextCapitalization.sentences, |
|
|
|
this.keyboardAppearance = Brightness.light, |
|
|
|
this.keyboardAppearance = Brightness.light, |
|
|
|
this.scrollPhysics, |
|
|
|
this.scrollPhysics, |
|
|
@ -190,7 +190,7 @@ class QuillEditor extends StatefulWidget { |
|
|
|
assert(embedBuilder != null); |
|
|
|
assert(embedBuilder != null); |
|
|
|
|
|
|
|
|
|
|
|
factory QuillEditor.basic( |
|
|
|
factory QuillEditor.basic( |
|
|
|
{@required QuillController controller, bool readOnly}) { |
|
|
|
{required QuillController controller, required bool readOnly}) { |
|
|
|
return QuillEditor( |
|
|
|
return QuillEditor( |
|
|
|
controller: controller, |
|
|
|
controller: controller, |
|
|
|
scrollController: ScrollController(), |
|
|
|
scrollController: ScrollController(), |
|
|
@ -210,7 +210,7 @@ class QuillEditor extends StatefulWidget { |
|
|
|
class _QuillEditorState extends State<QuillEditor> |
|
|
|
class _QuillEditorState extends State<QuillEditor> |
|
|
|
implements EditorTextSelectionGestureDetectorBuilderDelegate { |
|
|
|
implements EditorTextSelectionGestureDetectorBuilderDelegate { |
|
|
|
final GlobalKey<EditorState> _editorKey = GlobalKey<EditorState>(); |
|
|
|
final GlobalKey<EditorState> _editorKey = GlobalKey<EditorState>(); |
|
|
|
EditorTextSelectionGestureDetectorBuilder _selectionGestureDetectorBuilder; |
|
|
|
late EditorTextSelectionGestureDetectorBuilder _selectionGestureDetectorBuilder; |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
void initState() { |
|
|
|
void initState() { |
|
|
@ -227,10 +227,10 @@ class _QuillEditorState extends State<QuillEditor> |
|
|
|
TextSelectionControls textSelectionControls; |
|
|
|
TextSelectionControls textSelectionControls; |
|
|
|
bool paintCursorAboveText; |
|
|
|
bool paintCursorAboveText; |
|
|
|
bool cursorOpacityAnimates; |
|
|
|
bool cursorOpacityAnimates; |
|
|
|
Offset cursorOffset; |
|
|
|
Offset? cursorOffset; |
|
|
|
Color cursorColor; |
|
|
|
Color? cursorColor; |
|
|
|
Color selectionColor; |
|
|
|
Color selectionColor; |
|
|
|
Radius cursorRadius; |
|
|
|
Radius? cursorRadius; |
|
|
|
|
|
|
|
|
|
|
|
switch (theme.platform) { |
|
|
|
switch (theme.platform) { |
|
|
|
case TargetPlatform.android: |
|
|
|
case TargetPlatform.android: |
|
|
@ -301,7 +301,7 @@ class _QuillEditorState extends State<QuillEditor> |
|
|
|
selectionColor, |
|
|
|
selectionColor, |
|
|
|
textSelectionControls, |
|
|
|
textSelectionControls, |
|
|
|
widget.keyboardAppearance, |
|
|
|
widget.keyboardAppearance, |
|
|
|
widget.enableInteractiveSelection, |
|
|
|
widget.enableInteractiveSelection!, |
|
|
|
widget.scrollPhysics, |
|
|
|
widget.scrollPhysics, |
|
|
|
widget.embedBuilder), |
|
|
|
widget.embedBuilder), |
|
|
|
); |
|
|
|
); |
|
|
@ -318,12 +318,12 @@ class _QuillEditorState extends State<QuillEditor> |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
bool getSelectionEnabled() { |
|
|
|
bool? getSelectionEnabled() { |
|
|
|
return widget.enableInteractiveSelection; |
|
|
|
return widget.enableInteractiveSelection; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_requestKeyboard() { |
|
|
|
_requestKeyboard() { |
|
|
|
_editorKey.currentState.requestKeyboard(); |
|
|
|
_editorKey.currentState!.requestKeyboard(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -336,8 +336,8 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
@override |
|
|
|
@override |
|
|
|
onForcePressStart(ForcePressDetails details) { |
|
|
|
onForcePressStart(ForcePressDetails details) { |
|
|
|
super.onForcePressStart(details); |
|
|
|
super.onForcePressStart(details); |
|
|
|
if (delegate.getSelectionEnabled() && shouldShowSelectionToolbar) { |
|
|
|
if (delegate.getSelectionEnabled()! && shouldShowSelectionToolbar) { |
|
|
|
getEditor().showToolbar(); |
|
|
|
getEditor()!.showToolbar(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -346,13 +346,13 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
void onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) { |
|
|
|
void onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) { |
|
|
|
if (!delegate.getSelectionEnabled()) { |
|
|
|
if (!delegate.getSelectionEnabled()!) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
switch (Theme.of(_state.context).platform) { |
|
|
|
switch (Theme.of(_state.context).platform) { |
|
|
|
case TargetPlatform.iOS: |
|
|
|
case TargetPlatform.iOS: |
|
|
|
case TargetPlatform.macOS: |
|
|
|
case TargetPlatform.macOS: |
|
|
|
getRenderEditor().selectPositionAt( |
|
|
|
getRenderEditor()!.selectPositionAt( |
|
|
|
details.globalPosition, |
|
|
|
details.globalPosition, |
|
|
|
null, |
|
|
|
null, |
|
|
|
SelectionChangedCause.longPress, |
|
|
|
SelectionChangedCause.longPress, |
|
|
@ -362,7 +362,7 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
case TargetPlatform.fuchsia: |
|
|
|
case TargetPlatform.fuchsia: |
|
|
|
case TargetPlatform.linux: |
|
|
|
case TargetPlatform.linux: |
|
|
|
case TargetPlatform.windows: |
|
|
|
case TargetPlatform.windows: |
|
|
|
getRenderEditor().selectWordsInRange( |
|
|
|
getRenderEditor()!.selectWordsInRange( |
|
|
|
details.globalPosition - details.offsetFromOrigin, |
|
|
|
details.globalPosition - details.offsetFromOrigin, |
|
|
|
details.globalPosition, |
|
|
|
details.globalPosition, |
|
|
|
SelectionChangedCause.longPress, |
|
|
|
SelectionChangedCause.longPress, |
|
|
@ -378,9 +378,9 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
TextPosition pos = |
|
|
|
TextPosition pos = |
|
|
|
getRenderEditor().getPositionForOffset(details.globalPosition); |
|
|
|
getRenderEditor()!.getPositionForOffset(details.globalPosition); |
|
|
|
containerNode.ChildQuery result = |
|
|
|
containerNode.ChildQuery result = |
|
|
|
getEditor().widget.controller.document.queryChild(pos.offset); |
|
|
|
getEditor()!.widget.controller.document.queryChild(pos.offset); |
|
|
|
if (result.node == null) { |
|
|
|
if (result.node == null) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
@ -391,7 +391,7 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
if (line.length == 1) { |
|
|
|
if (line.length == 1) { |
|
|
|
// tapping when no text yet on this line |
|
|
|
// tapping when no text yet on this line |
|
|
|
_flipListCheckbox(pos, line, segmentResult); |
|
|
|
_flipListCheckbox(pos, line, segmentResult); |
|
|
|
getEditor().widget.controller.updateSelection( |
|
|
|
getEditor()!.widget.controller.updateSelection( |
|
|
|
TextSelection.collapsed(offset: pos.offset), ChangeSource.LOCAL); |
|
|
|
TextSelection.collapsed(offset: pos.offset), ChangeSource.LOCAL); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
@ -399,33 +399,33 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
} |
|
|
|
} |
|
|
|
leaf.Leaf segment = segmentResult.node as leaf.Leaf; |
|
|
|
leaf.Leaf segment = segmentResult.node as leaf.Leaf; |
|
|
|
if (segment.style.containsKey(Attribute.link.key)) { |
|
|
|
if (segment.style.containsKey(Attribute.link.key)) { |
|
|
|
var launchUrl = getEditor().widget.onLaunchUrl; |
|
|
|
var launchUrl = getEditor()!.widget.onLaunchUrl; |
|
|
|
if (launchUrl == null) { |
|
|
|
if (launchUrl == null) { |
|
|
|
launchUrl = _launchUrl; |
|
|
|
launchUrl = _launchUrl; |
|
|
|
} |
|
|
|
} |
|
|
|
String link = segment.style.attributes[Attribute.link.key].value; |
|
|
|
String? link = segment.style.attributes[Attribute.link.key]!.value; |
|
|
|
if (getEditor().widget.readOnly && link != null) { |
|
|
|
if (getEditor()!.widget.readOnly && link != null) { |
|
|
|
link = link.trim(); |
|
|
|
link = link.trim(); |
|
|
|
if (!linkPrefixes |
|
|
|
if (!linkPrefixes |
|
|
|
.any((linkPrefix) => link.toLowerCase().startsWith(linkPrefix))) { |
|
|
|
.any((linkPrefix) => link!.toLowerCase().startsWith(linkPrefix))) { |
|
|
|
link = 'https://$link'; |
|
|
|
link = 'https://$link'; |
|
|
|
} |
|
|
|
} |
|
|
|
launchUrl(link); |
|
|
|
launchUrl(link); |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
if (getEditor().widget.readOnly && segment.value is BlockEmbed) { |
|
|
|
if (getEditor()!.widget.readOnly && segment.value is BlockEmbed) { |
|
|
|
BlockEmbed blockEmbed = segment.value as BlockEmbed; |
|
|
|
BlockEmbed blockEmbed = segment.value as BlockEmbed; |
|
|
|
if (blockEmbed.type == 'image') { |
|
|
|
if (blockEmbed.type == 'image') { |
|
|
|
final String imageUrl = blockEmbed.data; |
|
|
|
final String imageUrl = blockEmbed.data; |
|
|
|
Navigator.push( |
|
|
|
Navigator.push( |
|
|
|
getEditor().context, |
|
|
|
getEditor()!.context, |
|
|
|
MaterialPageRoute( |
|
|
|
MaterialPageRoute( |
|
|
|
builder: (context) => ImageTapWrapper( |
|
|
|
builder: (context) => ImageTapWrapper( |
|
|
|
imageProvider: imageUrl.startsWith('http') |
|
|
|
imageProvider: imageUrl.startsWith('http') |
|
|
|
? NetworkImage(imageUrl) |
|
|
|
? NetworkImage(imageUrl) |
|
|
|
: isBase64(imageUrl) |
|
|
|
: isBase64(imageUrl) |
|
|
|
? Image.memory(base64.decode(imageUrl)) |
|
|
|
? Image.memory(base64.decode(imageUrl)) as ImageProvider<Object>? |
|
|
|
: FileImage(io.File(imageUrl)), |
|
|
|
: FileImage(io.File(imageUrl)), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
@ -441,25 +441,25 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
|
|
|
|
|
|
|
|
bool _flipListCheckbox( |
|
|
|
bool _flipListCheckbox( |
|
|
|
TextPosition pos, Line line, containerNode.ChildQuery segmentResult) { |
|
|
|
TextPosition pos, Line line, containerNode.ChildQuery segmentResult) { |
|
|
|
if (getEditor().widget.readOnly || |
|
|
|
if (getEditor()!.widget.readOnly || |
|
|
|
!line.style.containsKey(Attribute.list.key) || |
|
|
|
!line.style.containsKey(Attribute.list.key) || |
|
|
|
segmentResult.offset != 0) { |
|
|
|
segmentResult.offset != 0) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
// segmentResult.offset == 0 means tap at the beginning of the TextLine |
|
|
|
// segmentResult.offset == 0 means tap at the beginning of the TextLine |
|
|
|
String listVal = line.style.attributes[Attribute.list.key].value; |
|
|
|
String? listVal = line.style.attributes[Attribute.list.key]!.value; |
|
|
|
if (listVal == Attribute.unchecked.value) { |
|
|
|
if (listVal == Attribute.unchecked.value) { |
|
|
|
getEditor() |
|
|
|
getEditor()! |
|
|
|
.widget |
|
|
|
.widget |
|
|
|
.controller |
|
|
|
.controller |
|
|
|
.formatText(pos.offset, 0, Attribute.checked); |
|
|
|
.formatText(pos.offset, 0, Attribute.checked); |
|
|
|
} else if (listVal == Attribute.checked.value) { |
|
|
|
} else if (listVal == Attribute.checked.value) { |
|
|
|
getEditor() |
|
|
|
getEditor()! |
|
|
|
.widget |
|
|
|
.widget |
|
|
|
.controller |
|
|
|
.controller |
|
|
|
.formatText(pos.offset, 0, Attribute.unchecked); |
|
|
|
.formatText(pos.offset, 0, Attribute.unchecked); |
|
|
|
} |
|
|
|
} |
|
|
|
getEditor().widget.controller.updateSelection( |
|
|
|
getEditor()!.widget.controller.updateSelection( |
|
|
|
TextSelection.collapsed(offset: pos.offset), ChangeSource.LOCAL); |
|
|
|
TextSelection.collapsed(offset: pos.offset), ChangeSource.LOCAL); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
@ -470,11 +470,11 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
onSingleTapUp(TapUpDetails details) { |
|
|
|
onSingleTapUp(TapUpDetails details) { |
|
|
|
getEditor().hideToolbar(); |
|
|
|
getEditor()!.hideToolbar(); |
|
|
|
|
|
|
|
|
|
|
|
bool positionSelected = _onTapping(details); |
|
|
|
bool positionSelected = _onTapping(details); |
|
|
|
|
|
|
|
|
|
|
|
if (delegate.getSelectionEnabled() && !positionSelected) { |
|
|
|
if (delegate.getSelectionEnabled()! && !positionSelected) { |
|
|
|
switch (Theme.of(_state.context).platform) { |
|
|
|
switch (Theme.of(_state.context).platform) { |
|
|
|
case TargetPlatform.iOS: |
|
|
|
case TargetPlatform.iOS: |
|
|
|
case TargetPlatform.macOS: |
|
|
|
case TargetPlatform.macOS: |
|
|
@ -482,11 +482,11 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
case PointerDeviceKind.mouse: |
|
|
|
case PointerDeviceKind.mouse: |
|
|
|
case PointerDeviceKind.stylus: |
|
|
|
case PointerDeviceKind.stylus: |
|
|
|
case PointerDeviceKind.invertedStylus: |
|
|
|
case PointerDeviceKind.invertedStylus: |
|
|
|
getRenderEditor().selectPosition(SelectionChangedCause.tap); |
|
|
|
getRenderEditor()!.selectPosition(SelectionChangedCause.tap); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case PointerDeviceKind.touch: |
|
|
|
case PointerDeviceKind.touch: |
|
|
|
case PointerDeviceKind.unknown: |
|
|
|
case PointerDeviceKind.unknown: |
|
|
|
getRenderEditor().selectWordEdge(SelectionChangedCause.tap); |
|
|
|
getRenderEditor()!.selectWordEdge(SelectionChangedCause.tap); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
@ -494,7 +494,7 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
case TargetPlatform.fuchsia: |
|
|
|
case TargetPlatform.fuchsia: |
|
|
|
case TargetPlatform.linux: |
|
|
|
case TargetPlatform.linux: |
|
|
|
case TargetPlatform.windows: |
|
|
|
case TargetPlatform.windows: |
|
|
|
getRenderEditor().selectPosition(SelectionChangedCause.tap); |
|
|
|
getRenderEditor()!.selectPosition(SelectionChangedCause.tap); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -503,11 +503,11 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
void onSingleLongTapStart(LongPressStartDetails details) { |
|
|
|
void onSingleLongTapStart(LongPressStartDetails details) { |
|
|
|
if (delegate.getSelectionEnabled()) { |
|
|
|
if (delegate.getSelectionEnabled()!) { |
|
|
|
switch (Theme.of(_state.context).platform) { |
|
|
|
switch (Theme.of(_state.context).platform) { |
|
|
|
case TargetPlatform.iOS: |
|
|
|
case TargetPlatform.iOS: |
|
|
|
case TargetPlatform.macOS: |
|
|
|
case TargetPlatform.macOS: |
|
|
|
getRenderEditor().selectPositionAt( |
|
|
|
getRenderEditor()!.selectPositionAt( |
|
|
|
details.globalPosition, |
|
|
|
details.globalPosition, |
|
|
|
null, |
|
|
|
null, |
|
|
|
SelectionChangedCause.longPress, |
|
|
|
SelectionChangedCause.longPress, |
|
|
@ -517,7 +517,7 @@ class _QuillEditorSelectionGestureDetectorBuilder |
|
|
|
case TargetPlatform.fuchsia: |
|
|
|
case TargetPlatform.fuchsia: |
|
|
|
case TargetPlatform.linux: |
|
|
|
case TargetPlatform.linux: |
|
|
|
case TargetPlatform.windows: |
|
|
|
case TargetPlatform.windows: |
|
|
|
getRenderEditor().selectWord(SelectionChangedCause.longPress); |
|
|
|
getRenderEditor()!.selectWord(SelectionChangedCause.longPress); |
|
|
|
Feedback.forLongPress(_state.context); |
|
|
|
Feedback.forLongPress(_state.context); |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
@ -548,7 +548,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
final ValueNotifier<bool> _selectionEndInViewport = ValueNotifier<bool>(true); |
|
|
|
final ValueNotifier<bool> _selectionEndInViewport = ValueNotifier<bool>(true); |
|
|
|
|
|
|
|
|
|
|
|
RenderEditor( |
|
|
|
RenderEditor( |
|
|
|
List<RenderEditableBox> children, |
|
|
|
List<RenderEditableBox>? children, |
|
|
|
TextDirection textDirection, |
|
|
|
TextDirection textDirection, |
|
|
|
EdgeInsetsGeometry padding, |
|
|
|
EdgeInsetsGeometry padding, |
|
|
|
this.document, |
|
|
|
this.document, |
|
|
@ -622,7 +622,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
offset: |
|
|
|
offset: |
|
|
|
textSelection.extentOffset - child.getContainer().getOffset()); |
|
|
|
textSelection.extentOffset - child.getContainer().getOffset()); |
|
|
|
Offset localOffset = child.getOffsetForCaret(localPosition); |
|
|
|
Offset localOffset = child.getOffsetForCaret(localPosition); |
|
|
|
BoxParentData parentData = child.parentData; |
|
|
|
BoxParentData parentData = child.parentData as BoxParentData; |
|
|
|
return <TextSelectionPoint>[ |
|
|
|
return <TextSelectionPoint>[ |
|
|
|
TextSelectionPoint( |
|
|
|
TextSelectionPoint( |
|
|
|
Offset(0.0, child.preferredLineHeight(localPosition)) + |
|
|
|
Offset(0.0, child.preferredLineHeight(localPosition)) + |
|
|
@ -632,7 +632,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
]; |
|
|
|
]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Node baseNode = _container.queryChild(textSelection.start, false).node; |
|
|
|
Node? baseNode = _container.queryChild(textSelection.start, false).node; |
|
|
|
|
|
|
|
|
|
|
|
var baseChild = firstChild; |
|
|
|
var baseChild = firstChild; |
|
|
|
while (baseChild != null) { |
|
|
|
while (baseChild != null) { |
|
|
@ -643,7 +643,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
} |
|
|
|
} |
|
|
|
assert(baseChild != null); |
|
|
|
assert(baseChild != null); |
|
|
|
|
|
|
|
|
|
|
|
BoxParentData baseParentData = baseChild.parentData; |
|
|
|
BoxParentData baseParentData = baseChild!.parentData as BoxParentData; |
|
|
|
TextSelection baseSelection = |
|
|
|
TextSelection baseSelection = |
|
|
|
localSelection(baseChild.getContainer(), textSelection, true); |
|
|
|
localSelection(baseChild.getContainer(), textSelection, true); |
|
|
|
TextSelectionPoint basePoint = |
|
|
|
TextSelectionPoint basePoint = |
|
|
@ -651,8 +651,8 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
basePoint = TextSelectionPoint( |
|
|
|
basePoint = TextSelectionPoint( |
|
|
|
basePoint.point + baseParentData.offset, basePoint.direction); |
|
|
|
basePoint.point + baseParentData.offset, basePoint.direction); |
|
|
|
|
|
|
|
|
|
|
|
Node extentNode = _container.queryChild(textSelection.end, false).node; |
|
|
|
Node? extentNode = _container.queryChild(textSelection.end, false).node; |
|
|
|
var extentChild = baseChild; |
|
|
|
RenderEditableBox? extentChild = baseChild; |
|
|
|
while (extentChild != null) { |
|
|
|
while (extentChild != null) { |
|
|
|
if (extentChild.getContainer() == extentNode) { |
|
|
|
if (extentChild.getContainer() == extentNode) { |
|
|
|
break; |
|
|
|
break; |
|
|
@ -661,7 +661,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
} |
|
|
|
} |
|
|
|
assert(extentChild != null); |
|
|
|
assert(extentChild != null); |
|
|
|
|
|
|
|
|
|
|
|
BoxParentData extentParentData = extentChild.parentData; |
|
|
|
BoxParentData extentParentData = extentChild!.parentData as BoxParentData; |
|
|
|
TextSelection extentSelection = |
|
|
|
TextSelection extentSelection = |
|
|
|
localSelection(extentChild.getContainer(), textSelection, true); |
|
|
|
localSelection(extentChild.getContainer(), textSelection, true); |
|
|
|
TextSelectionPoint extentPoint = |
|
|
|
TextSelectionPoint extentPoint = |
|
|
@ -672,7 +672,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
return <TextSelectionPoint>[basePoint, extentPoint]; |
|
|
|
return <TextSelectionPoint>[basePoint, extentPoint]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Offset _lastTapDownPosition; |
|
|
|
Offset? _lastTapDownPosition; |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
handleTapDown(TapDownDetails details) { |
|
|
|
handleTapDown(TapDownDetails details) { |
|
|
@ -682,7 +682,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
@override |
|
|
|
@override |
|
|
|
selectWordsInRange( |
|
|
|
selectWordsInRange( |
|
|
|
Offset from, |
|
|
|
Offset from, |
|
|
|
Offset to, |
|
|
|
Offset? to, |
|
|
|
SelectionChangedCause cause, |
|
|
|
SelectionChangedCause cause, |
|
|
|
) { |
|
|
|
) { |
|
|
|
assert(cause != null); |
|
|
|
assert(cause != null); |
|
|
@ -729,7 +729,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
if (onSelectionChanged == null) { |
|
|
|
if (onSelectionChanged == null) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
TextPosition position = getPositionForOffset(_lastTapDownPosition); |
|
|
|
TextPosition position = getPositionForOffset(_lastTapDownPosition!); |
|
|
|
RenderEditableBox child = childAtPosition(position); |
|
|
|
RenderEditableBox child = childAtPosition(position); |
|
|
|
int nodeOffset = child.getContainer().getOffset(); |
|
|
|
int nodeOffset = child.getContainer().getOffset(); |
|
|
|
TextPosition localPosition = TextPosition( |
|
|
|
TextPosition localPosition = TextPosition( |
|
|
@ -759,7 +759,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
@override |
|
|
|
@override |
|
|
|
selectPositionAt( |
|
|
|
selectPositionAt( |
|
|
|
Offset from, |
|
|
|
Offset from, |
|
|
|
Offset to, |
|
|
|
Offset? to, |
|
|
|
SelectionChangedCause cause, |
|
|
|
SelectionChangedCause cause, |
|
|
|
) { |
|
|
|
) { |
|
|
|
assert(cause != null); |
|
|
|
assert(cause != null); |
|
|
@ -768,7 +768,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
TextPosition fromPosition = getPositionForOffset(from); |
|
|
|
TextPosition fromPosition = getPositionForOffset(from); |
|
|
|
TextPosition toPosition = to == null ? null : getPositionForOffset(to); |
|
|
|
TextPosition? toPosition = to == null ? null : getPositionForOffset(to); |
|
|
|
|
|
|
|
|
|
|
|
int baseOffset = fromPosition.offset; |
|
|
|
int baseOffset = fromPosition.offset; |
|
|
|
int extentOffset = fromPosition.offset; |
|
|
|
int extentOffset = fromPosition.offset; |
|
|
@ -787,12 +787,12 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
selectWord(SelectionChangedCause cause) { |
|
|
|
selectWord(SelectionChangedCause cause) { |
|
|
|
selectWordsInRange(_lastTapDownPosition, null, cause); |
|
|
|
selectWordsInRange(_lastTapDownPosition!, null, cause); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
selectPosition(SelectionChangedCause cause) { |
|
|
|
selectPosition(SelectionChangedCause cause) { |
|
|
|
selectPositionAt(_lastTapDownPosition, null, cause); |
|
|
|
selectPositionAt(_lastTapDownPosition!, null, cause); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
@ -837,7 +837,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
bool hitTestChildren(BoxHitTestResult result, {Offset position}) { |
|
|
|
bool hitTestChildren(BoxHitTestResult result, {required Offset position}) { |
|
|
|
return defaultHitTestChildren(result, position: position); |
|
|
|
return defaultHitTestChildren(result, position: position); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -877,9 +877,9 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
@override |
|
|
|
@override |
|
|
|
TextPosition getPositionForOffset(Offset offset) { |
|
|
|
TextPosition getPositionForOffset(Offset offset) { |
|
|
|
Offset local = globalToLocal(offset); |
|
|
|
Offset local = globalToLocal(offset); |
|
|
|
RenderEditableBox child = childAtOffset(local); |
|
|
|
RenderEditableBox child = childAtOffset(local)!; |
|
|
|
|
|
|
|
|
|
|
|
BoxParentData parentData = child.parentData; |
|
|
|
BoxParentData parentData = child.parentData as BoxParentData; |
|
|
|
Offset localOffset = local - parentData.offset; |
|
|
|
Offset localOffset = local - parentData.offset; |
|
|
|
TextPosition localPosition = child.getPositionForOffset(localOffset); |
|
|
|
TextPosition localPosition = child.getPositionForOffset(localOffset); |
|
|
|
return TextPosition( |
|
|
|
return TextPosition( |
|
|
@ -888,7 +888,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
double getOffsetToRevealCursor( |
|
|
|
double? getOffsetToRevealCursor( |
|
|
|
double viewportHeight, double scrollOffset, double offsetInViewport) { |
|
|
|
double viewportHeight, double scrollOffset, double offsetInViewport) { |
|
|
|
List<TextSelectionPoint> endpoints = getEndpointsForSelection(selection); |
|
|
|
List<TextSelectionPoint> endpoints = getEndpointsForSelection(selection); |
|
|
|
TextSelectionPoint endpoint = endpoints.first; |
|
|
|
TextSelectionPoint endpoint = endpoints.first; |
|
|
@ -902,7 +902,7 @@ class RenderEditor extends RenderEditableContainerBox |
|
|
|
kMargin + |
|
|
|
kMargin + |
|
|
|
offsetInViewport; |
|
|
|
offsetInViewport; |
|
|
|
final caretBottom = endpoint.point.dy + kMargin + offsetInViewport; |
|
|
|
final caretBottom = endpoint.point.dy + kMargin + offsetInViewport; |
|
|
|
double dy; |
|
|
|
double? dy; |
|
|
|
if (caretTop < scrollOffset) { |
|
|
|
if (caretTop < scrollOffset) { |
|
|
|
dy = caretTop; |
|
|
|
dy = caretTop; |
|
|
|
} else if (caretBottom > scrollOffset + viewportHeight) { |
|
|
|
} else if (caretBottom > scrollOffset + viewportHeight) { |
|
|
@ -927,9 +927,9 @@ class RenderEditableContainerBox extends RenderBox |
|
|
|
containerNode.Container _container; |
|
|
|
containerNode.Container _container; |
|
|
|
TextDirection textDirection; |
|
|
|
TextDirection textDirection; |
|
|
|
EdgeInsetsGeometry _padding; |
|
|
|
EdgeInsetsGeometry _padding; |
|
|
|
EdgeInsets _resolvedPadding; |
|
|
|
EdgeInsets? _resolvedPadding; |
|
|
|
|
|
|
|
|
|
|
|
RenderEditableContainerBox(List<RenderEditableBox> children, this._container, |
|
|
|
RenderEditableContainerBox(List<RenderEditableBox>? children, this._container, |
|
|
|
this.textDirection, this._padding) |
|
|
|
this.textDirection, this._padding) |
|
|
|
: assert(_container != null), |
|
|
|
: assert(_container != null), |
|
|
|
assert(textDirection != null), |
|
|
|
assert(textDirection != null), |
|
|
@ -963,22 +963,22 @@ class RenderEditableContainerBox extends RenderBox |
|
|
|
_markNeedsPaddingResolution(); |
|
|
|
_markNeedsPaddingResolution(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
EdgeInsets get resolvedPadding => _resolvedPadding; |
|
|
|
EdgeInsets? get resolvedPadding => _resolvedPadding; |
|
|
|
|
|
|
|
|
|
|
|
_resolvePadding() { |
|
|
|
_resolvePadding() { |
|
|
|
if (_resolvedPadding != null) { |
|
|
|
if (_resolvedPadding != null) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
_resolvedPadding = _padding.resolve(textDirection); |
|
|
|
_resolvedPadding = _padding.resolve(textDirection); |
|
|
|
_resolvedPadding = _resolvedPadding.copyWith(left: _resolvedPadding.left); |
|
|
|
_resolvedPadding = _resolvedPadding!.copyWith(left: _resolvedPadding!.left); |
|
|
|
|
|
|
|
|
|
|
|
assert(_resolvedPadding.isNonNegative); |
|
|
|
assert(_resolvedPadding!.isNonNegative); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
RenderEditableBox childAtPosition(TextPosition position) { |
|
|
|
RenderEditableBox childAtPosition(TextPosition position) { |
|
|
|
assert(firstChild != null); |
|
|
|
assert(firstChild != null); |
|
|
|
|
|
|
|
|
|
|
|
Node targetNode = _container.queryChild(position.offset, false).node; |
|
|
|
Node? targetNode = _container.queryChild(position.offset, false).node; |
|
|
|
|
|
|
|
|
|
|
|
var targetChild = firstChild; |
|
|
|
var targetChild = firstChild; |
|
|
|
while (targetChild != null) { |
|
|
|
while (targetChild != null) { |
|
|
@ -998,19 +998,19 @@ class RenderEditableContainerBox extends RenderBox |
|
|
|
markNeedsLayout(); |
|
|
|
markNeedsLayout(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
RenderEditableBox childAtOffset(Offset offset) { |
|
|
|
RenderEditableBox? childAtOffset(Offset offset) { |
|
|
|
assert(firstChild != null); |
|
|
|
assert(firstChild != null); |
|
|
|
_resolvePadding(); |
|
|
|
_resolvePadding(); |
|
|
|
|
|
|
|
|
|
|
|
if (offset.dy <= _resolvedPadding.top) { |
|
|
|
if (offset.dy <= _resolvedPadding!.top) { |
|
|
|
return firstChild; |
|
|
|
return firstChild; |
|
|
|
} |
|
|
|
} |
|
|
|
if (offset.dy >= size.height - _resolvedPadding.bottom) { |
|
|
|
if (offset.dy >= size.height - _resolvedPadding!.bottom) { |
|
|
|
return lastChild; |
|
|
|
return lastChild; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var child = firstChild; |
|
|
|
var child = firstChild; |
|
|
|
double dx = -offset.dx, dy = _resolvedPadding.top; |
|
|
|
double dx = -offset.dx, dy = _resolvedPadding!.top; |
|
|
|
while (child != null) { |
|
|
|
while (child != null) { |
|
|
|
if (child.size.contains(offset.translate(dx, -dy))) { |
|
|
|
if (child.size.contains(offset.translate(dx, -dy))) { |
|
|
|
return child; |
|
|
|
return child; |
|
|
@ -1037,20 +1037,20 @@ class RenderEditableContainerBox extends RenderBox |
|
|
|
_resolvePadding(); |
|
|
|
_resolvePadding(); |
|
|
|
assert(_resolvedPadding != null); |
|
|
|
assert(_resolvedPadding != null); |
|
|
|
|
|
|
|
|
|
|
|
double mainAxisExtent = _resolvedPadding.top; |
|
|
|
double mainAxisExtent = _resolvedPadding!.top; |
|
|
|
var child = firstChild; |
|
|
|
var child = firstChild; |
|
|
|
BoxConstraints innerConstraints = |
|
|
|
BoxConstraints innerConstraints = |
|
|
|
BoxConstraints.tightFor(width: constraints.maxWidth) |
|
|
|
BoxConstraints.tightFor(width: constraints.maxWidth) |
|
|
|
.deflate(_resolvedPadding); |
|
|
|
.deflate(_resolvedPadding!); |
|
|
|
while (child != null) { |
|
|
|
while (child != null) { |
|
|
|
child.layout(innerConstraints, parentUsesSize: true); |
|
|
|
child.layout(innerConstraints, parentUsesSize: true); |
|
|
|
final EditableContainerParentData childParentData = child.parentData; |
|
|
|
final EditableContainerParentData childParentData = child.parentData as EditableContainerParentData; |
|
|
|
childParentData.offset = Offset(_resolvedPadding.left, mainAxisExtent); |
|
|
|
childParentData.offset = Offset(_resolvedPadding!.left, mainAxisExtent); |
|
|
|
mainAxisExtent += child.size.height; |
|
|
|
mainAxisExtent += child.size.height; |
|
|
|
assert(child.parentData == childParentData); |
|
|
|
assert(child.parentData == childParentData); |
|
|
|
child = childParentData.nextSibling; |
|
|
|
child = childParentData.nextSibling; |
|
|
|
} |
|
|
|
} |
|
|
|
mainAxisExtent += _resolvedPadding.bottom; |
|
|
|
mainAxisExtent += _resolvedPadding!.bottom; |
|
|
|
size = constraints.constrain(Size(constraints.maxWidth, mainAxisExtent)); |
|
|
|
size = constraints.constrain(Size(constraints.maxWidth, mainAxisExtent)); |
|
|
|
|
|
|
|
|
|
|
|
assert(size.isFinite); |
|
|
|
assert(size.isFinite); |
|
|
@ -1061,7 +1061,7 @@ class RenderEditableContainerBox extends RenderBox |
|
|
|
var child = firstChild; |
|
|
|
var child = firstChild; |
|
|
|
while (child != null) { |
|
|
|
while (child != null) { |
|
|
|
extent = math.max(extent, childSize(child)); |
|
|
|
extent = math.max(extent, childSize(child)); |
|
|
|
EditableContainerParentData childParentData = child.parentData; |
|
|
|
EditableContainerParentData childParentData = child.parentData as EditableContainerParentData; |
|
|
|
child = childParentData.nextSibling; |
|
|
|
child = childParentData.nextSibling; |
|
|
|
} |
|
|
|
} |
|
|
|
return extent; |
|
|
|
return extent; |
|
|
@ -1072,7 +1072,7 @@ class RenderEditableContainerBox extends RenderBox |
|
|
|
var child = firstChild; |
|
|
|
var child = firstChild; |
|
|
|
while (child != null) { |
|
|
|
while (child != null) { |
|
|
|
extent += childSize(child); |
|
|
|
extent += childSize(child); |
|
|
|
EditableContainerParentData childParentData = child.parentData; |
|
|
|
EditableContainerParentData childParentData = child.parentData as EditableContainerParentData; |
|
|
|
child = childParentData.nextSibling; |
|
|
|
child = childParentData.nextSibling; |
|
|
|
} |
|
|
|
} |
|
|
|
return extent; |
|
|
|
return extent; |
|
|
@ -1083,10 +1083,10 @@ class RenderEditableContainerBox extends RenderBox |
|
|
|
_resolvePadding(); |
|
|
|
_resolvePadding(); |
|
|
|
return _getIntrinsicCrossAxis((RenderBox child) { |
|
|
|
return _getIntrinsicCrossAxis((RenderBox child) { |
|
|
|
double childHeight = math.max( |
|
|
|
double childHeight = math.max( |
|
|
|
0.0, height - _resolvedPadding.top + _resolvedPadding.bottom); |
|
|
|
0.0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); |
|
|
|
return child.getMinIntrinsicWidth(childHeight) + |
|
|
|
return child.getMinIntrinsicWidth(childHeight) + |
|
|
|
_resolvedPadding.left + |
|
|
|
_resolvedPadding!.left + |
|
|
|
_resolvedPadding.right; |
|
|
|
_resolvedPadding!.right; |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1095,10 +1095,10 @@ class RenderEditableContainerBox extends RenderBox |
|
|
|
_resolvePadding(); |
|
|
|
_resolvePadding(); |
|
|
|
return _getIntrinsicCrossAxis((RenderBox child) { |
|
|
|
return _getIntrinsicCrossAxis((RenderBox child) { |
|
|
|
double childHeight = math.max( |
|
|
|
double childHeight = math.max( |
|
|
|
0.0, height - _resolvedPadding.top + _resolvedPadding.bottom); |
|
|
|
0.0, height - _resolvedPadding!.top + _resolvedPadding!.bottom); |
|
|
|
return child.getMaxIntrinsicWidth(childHeight) + |
|
|
|
return child.getMaxIntrinsicWidth(childHeight) + |
|
|
|
_resolvedPadding.left + |
|
|
|
_resolvedPadding!.left + |
|
|
|
_resolvedPadding.right; |
|
|
|
_resolvedPadding!.right; |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1107,10 +1107,10 @@ class RenderEditableContainerBox extends RenderBox |
|
|
|
_resolvePadding(); |
|
|
|
_resolvePadding(); |
|
|
|
return _getIntrinsicMainAxis((RenderBox child) { |
|
|
|
return _getIntrinsicMainAxis((RenderBox child) { |
|
|
|
double childWidth = |
|
|
|
double childWidth = |
|
|
|
math.max(0.0, width - _resolvedPadding.left + _resolvedPadding.right); |
|
|
|
math.max(0.0, width - _resolvedPadding!.left + _resolvedPadding!.right); |
|
|
|
return child.getMinIntrinsicHeight(childWidth) + |
|
|
|
return child.getMinIntrinsicHeight(childWidth) + |
|
|
|
_resolvedPadding.top + |
|
|
|
_resolvedPadding!.top + |
|
|
|
_resolvedPadding.bottom; |
|
|
|
_resolvedPadding!.bottom; |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1119,17 +1119,17 @@ class RenderEditableContainerBox extends RenderBox |
|
|
|
_resolvePadding(); |
|
|
|
_resolvePadding(); |
|
|
|
return _getIntrinsicMainAxis((RenderBox child) { |
|
|
|
return _getIntrinsicMainAxis((RenderBox child) { |
|
|
|
final childWidth = |
|
|
|
final childWidth = |
|
|
|
math.max(0.0, width - _resolvedPadding.left + _resolvedPadding.right); |
|
|
|
math.max(0.0, width - _resolvedPadding!.left + _resolvedPadding!.right); |
|
|
|
return child.getMaxIntrinsicHeight(childWidth) + |
|
|
|
return child.getMaxIntrinsicHeight(childWidth) + |
|
|
|
_resolvedPadding.top + |
|
|
|
_resolvedPadding!.top + |
|
|
|
_resolvedPadding.bottom; |
|
|
|
_resolvedPadding!.bottom; |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
|
double computeDistanceToActualBaseline(TextBaseline baseline) { |
|
|
|
double computeDistanceToActualBaseline(TextBaseline baseline) { |
|
|
|
_resolvePadding(); |
|
|
|
_resolvePadding(); |
|
|
|
return defaultComputeDistanceToFirstActualBaseline(baseline) + |
|
|
|
return defaultComputeDistanceToFirstActualBaseline(baseline)! + |
|
|
|
_resolvedPadding.top; |
|
|
|
_resolvedPadding!.top; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|