|
|
|
@ -1,6 +1,8 @@ |
|
|
|
|
import 'dart:math'; |
|
|
|
|
import 'dart:math' as math; |
|
|
|
|
|
|
|
|
|
import 'package:flutter/foundation.dart'; |
|
|
|
|
import 'package:flutter/rendering.dart'; |
|
|
|
|
import 'package:flutter/services.dart'; |
|
|
|
|
import 'package:flutter/widgets.dart'; |
|
|
|
|
|
|
|
|
|
import '../editor.dart'; |
|
|
|
@ -14,7 +16,8 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
set textEditingValue(TextEditingValue value) { |
|
|
|
|
setTextEditingValue(value); |
|
|
|
|
// deprecated |
|
|
|
|
setTextEditingValue(value, SelectionChangedCause.keyboard); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@ -50,8 +53,8 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState |
|
|
|
|
final expandedRect = Rect.fromCenter( |
|
|
|
|
center: rect.center, |
|
|
|
|
width: rect.width, |
|
|
|
|
height: |
|
|
|
|
max(rect.height, getRenderEditor()!.preferredLineHeight(position)), |
|
|
|
|
height: math.max( |
|
|
|
|
rect.height, getRenderEditor()!.preferredLineHeight(position)), |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
additionalOffset = expandedRect.height >= editableSize.height |
|
|
|
@ -81,10 +84,8 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
void userUpdateTextEditingValue( |
|
|
|
|
TextEditingValue value, |
|
|
|
|
SelectionChangedCause cause, |
|
|
|
|
) { |
|
|
|
|
setTextEditingValue(value); |
|
|
|
|
TextEditingValue value, SelectionChangedCause cause) { |
|
|
|
|
setTextEditingValue(value, cause); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@ -98,4 +99,118 @@ mixin RawEditorStateSelectionDelegateMixin on EditorState |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
bool get selectAllEnabled => widget.toolbarOptions.selectAll; |
|
|
|
|
|
|
|
|
|
void setSelection(TextSelection nextSelection, SelectionChangedCause cause) { |
|
|
|
|
if (nextSelection == textEditingValue.selection) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
setTextEditingValue( |
|
|
|
|
textEditingValue.copyWith(selection: nextSelection), |
|
|
|
|
cause, |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
void copySelection(SelectionChangedCause cause) { |
|
|
|
|
final selection = textEditingValue.selection; |
|
|
|
|
if (selection.isCollapsed || !selection.isValid) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
Clipboard.setData( |
|
|
|
|
ClipboardData(text: selection.textInside(textEditingValue.text))); |
|
|
|
|
|
|
|
|
|
if (cause == SelectionChangedCause.toolbar) { |
|
|
|
|
bringIntoView(textEditingValue.selection.extent); |
|
|
|
|
hideToolbar(false); |
|
|
|
|
|
|
|
|
|
switch (defaultTargetPlatform) { |
|
|
|
|
case TargetPlatform.iOS: |
|
|
|
|
break; |
|
|
|
|
case TargetPlatform.macOS: |
|
|
|
|
case TargetPlatform.android: |
|
|
|
|
case TargetPlatform.fuchsia: |
|
|
|
|
case TargetPlatform.linux: |
|
|
|
|
case TargetPlatform.windows: |
|
|
|
|
// Collapse the selection and hide the toolbar and handles. |
|
|
|
|
userUpdateTextEditingValue( |
|
|
|
|
TextEditingValue( |
|
|
|
|
text: textEditingValue.text, |
|
|
|
|
selection: TextSelection.collapsed(offset: textEditingValue.selection.end), |
|
|
|
|
), |
|
|
|
|
SelectionChangedCause.toolbar, |
|
|
|
|
); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
void cutSelection(SelectionChangedCause cause) { |
|
|
|
|
final selection = textEditingValue.selection; |
|
|
|
|
if (readOnly || !selection.isValid || selection.isCollapsed) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
final text = textEditingValue.text; |
|
|
|
|
Clipboard.setData(ClipboardData(text: selection.textInside(text))); |
|
|
|
|
setTextEditingValue( |
|
|
|
|
TextEditingValue( |
|
|
|
|
text: selection.textBefore(text) + selection.textAfter(text), |
|
|
|
|
selection: TextSelection.collapsed( |
|
|
|
|
offset: math.min(selection.start, selection.end), |
|
|
|
|
affinity: selection.affinity, |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
cause, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
if (cause == SelectionChangedCause.toolbar) { |
|
|
|
|
bringIntoView(textEditingValue.selection.extent); |
|
|
|
|
hideToolbar(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
Future<void> pasteText(SelectionChangedCause cause) async { |
|
|
|
|
final selection = textEditingValue.selection; |
|
|
|
|
if (readOnly || !selection.isValid) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
final text = textEditingValue.text; |
|
|
|
|
// See https://github.com/flutter/flutter/issues/11427 |
|
|
|
|
final data = await Clipboard.getData(Clipboard.kTextPlain); |
|
|
|
|
if (data == null) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
setTextEditingValue( |
|
|
|
|
TextEditingValue( |
|
|
|
|
text: |
|
|
|
|
selection.textBefore(text) + data.text! + selection.textAfter(text), |
|
|
|
|
selection: TextSelection.collapsed( |
|
|
|
|
offset: math.min(selection.start, selection.end) + data.text!.length, |
|
|
|
|
affinity: selection.affinity, |
|
|
|
|
), |
|
|
|
|
), |
|
|
|
|
cause, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
if (cause == SelectionChangedCause.toolbar) { |
|
|
|
|
bringIntoView(textEditingValue.selection.extent); |
|
|
|
|
hideToolbar(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@override |
|
|
|
|
void selectAll(SelectionChangedCause cause) { |
|
|
|
|
setSelection( |
|
|
|
|
textEditingValue.selection.copyWith( |
|
|
|
|
baseOffset: 0, |
|
|
|
|
extentOffset: textEditingValue.text.length, |
|
|
|
|
), |
|
|
|
|
cause, |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
if (cause == SelectionChangedCause.toolbar) { |
|
|
|
|
bringIntoView(textEditingValue.selection.extent); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|