mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[flutter]: fix compile errors after update flutter sdk
This commit is contained in:
parent
c4a6342c96
commit
c4e9fd0697
5
app_flowy/.vscode/settings.json
vendored
5
app_flowy/.vscode/settings.json
vendored
@ -2,5 +2,8 @@
|
||||
"svgviewer.enableautopreview": true,
|
||||
"svgviewer.previewcolumn": "Active",
|
||||
"svgviewer.showzoominout": true,
|
||||
"editor.wordWrapColumn": 120
|
||||
"editor.wordWrapColumn": 120,
|
||||
"editor.minimap.maxColumn": 140,
|
||||
"prettier.printWidth": 140,
|
||||
"editor.wordWrap": "wordWrapColumn"
|
||||
}
|
@ -1,32 +1,25 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
/* --------------------------------- Typedef -------------------------------- */
|
||||
//fixme workaround flutter MacOS issue https://github.com/flutter/flutter/issues/75595
|
||||
extension _LogicalKeyboardKeyCaseExt on LogicalKeyboardKey {
|
||||
static const _kUpperToLowerDist = 0x20;
|
||||
static final _kLowerCaseA = LogicalKeyboardKey.keyA.keyId;
|
||||
static final _kLowerCaseZ = LogicalKeyboardKey.keyZ.keyId;
|
||||
|
||||
enum InputShortcut {
|
||||
CUT,
|
||||
COPY,
|
||||
PASTE,
|
||||
SELECT_ALL,
|
||||
SAVE,
|
||||
LogicalKeyboardKey toUpperCase() {
|
||||
if (keyId < _kLowerCaseA || keyId > _kLowerCaseZ) return this;
|
||||
return LogicalKeyboardKey(keyId - _kUpperToLowerDist);
|
||||
}
|
||||
}
|
||||
|
||||
enum InputShortcut { CUT, COPY, PASTE, SELECT_ALL, UNDO, REDO }
|
||||
|
||||
typedef CursorMoveCallback = void Function(
|
||||
LogicalKeyboardKey key,
|
||||
bool wordModifier,
|
||||
bool lineModifier,
|
||||
bool shift,
|
||||
);
|
||||
|
||||
typedef InputShortcutCallback = void Function(
|
||||
InputShortcut? shortcut,
|
||||
);
|
||||
|
||||
typedef OnDeleteCallback = void Function(
|
||||
bool forward,
|
||||
);
|
||||
|
||||
/* -------------------------------- Listener -------------------------------- */
|
||||
LogicalKeyboardKey key, bool wordModifier, bool lineModifier, bool shift);
|
||||
typedef InputShortcutCallback = void Function(InputShortcut? shortcut);
|
||||
typedef OnDeleteCallback = void Function(bool forward);
|
||||
|
||||
class FlowyKeyboardListener {
|
||||
FlowyKeyboardListener(this.onCursorMove, this.onShortcut, this.onDelete);
|
||||
@ -35,43 +28,45 @@ class FlowyKeyboardListener {
|
||||
final InputShortcutCallback onShortcut;
|
||||
final OnDeleteCallback onDelete;
|
||||
|
||||
static final Set<LogicalKeyboardKey> _moveKeys = {
|
||||
static final Set<LogicalKeyboardKey> _moveKeys = <LogicalKeyboardKey>{
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
LogicalKeyboardKey.arrowUp,
|
||||
LogicalKeyboardKey.arrowDown,
|
||||
LogicalKeyboardKey.arrowLeft,
|
||||
LogicalKeyboardKey.arrowRight,
|
||||
};
|
||||
|
||||
static final Set<LogicalKeyboardKey> _shortcutKeys = {
|
||||
static final Set<LogicalKeyboardKey> _shortcutKeys = <LogicalKeyboardKey>{
|
||||
LogicalKeyboardKey.keyA,
|
||||
LogicalKeyboardKey.keyC,
|
||||
LogicalKeyboardKey.keyV,
|
||||
LogicalKeyboardKey.keyX,
|
||||
LogicalKeyboardKey.keyS,
|
||||
LogicalKeyboardKey.keyZ.toUpperCase(),
|
||||
LogicalKeyboardKey.keyZ,
|
||||
LogicalKeyboardKey.delete,
|
||||
LogicalKeyboardKey.backspace,
|
||||
};
|
||||
|
||||
static final Set<LogicalKeyboardKey> _nonModifierKeys = {
|
||||
..._moveKeys,
|
||||
static final Set<LogicalKeyboardKey> _nonModifierKeys = <LogicalKeyboardKey>{
|
||||
..._shortcutKeys,
|
||||
..._moveKeys,
|
||||
};
|
||||
|
||||
static final Set<LogicalKeyboardKey> _winModifierKeys = {
|
||||
static final Set<LogicalKeyboardKey> _modifierKeys = <LogicalKeyboardKey>{
|
||||
LogicalKeyboardKey.shift,
|
||||
LogicalKeyboardKey.control,
|
||||
LogicalKeyboardKey.alt,
|
||||
LogicalKeyboardKey.shift,
|
||||
};
|
||||
|
||||
static final Set<LogicalKeyboardKey> _osxModifierKeys = {
|
||||
static final Set<LogicalKeyboardKey> _macOsModifierKeys =
|
||||
<LogicalKeyboardKey>{
|
||||
LogicalKeyboardKey.shift,
|
||||
LogicalKeyboardKey.meta,
|
||||
LogicalKeyboardKey.alt,
|
||||
LogicalKeyboardKey.shift,
|
||||
};
|
||||
|
||||
static final Set<LogicalKeyboardKey> _interestingKeys = {
|
||||
..._winModifierKeys,
|
||||
..._osxModifierKeys,
|
||||
static final Set<LogicalKeyboardKey> _interestingKeys = <LogicalKeyboardKey>{
|
||||
..._modifierKeys,
|
||||
..._macOsModifierKeys,
|
||||
..._nonModifierKeys,
|
||||
};
|
||||
|
||||
@ -80,66 +75,55 @@ class FlowyKeyboardListener {
|
||||
LogicalKeyboardKey.keyC: InputShortcut.COPY,
|
||||
LogicalKeyboardKey.keyV: InputShortcut.PASTE,
|
||||
LogicalKeyboardKey.keyA: InputShortcut.SELECT_ALL,
|
||||
LogicalKeyboardKey.keyS: InputShortcut.SAVE,
|
||||
};
|
||||
|
||||
bool handleRawKeyEvent(RawKeyEvent event) {
|
||||
KeyEventResult handleRawKeyEvent(RawKeyEvent event) {
|
||||
if (kIsWeb) {
|
||||
// On web platform, we should ignore the key because it's processed already.
|
||||
return false;
|
||||
}
|
||||
if (event is! RawKeyDownEvent) {
|
||||
return false;
|
||||
// On web platform, we ignore the key because it's already processed.
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
|
||||
final keysPressed = LogicalKeyboardKey.collapseSynonyms(RawKeyboard.instance.keysPressed);
|
||||
if (event is! RawKeyDownEvent) {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
|
||||
final keysPressed =
|
||||
LogicalKeyboardKey.collapseSynonyms(RawKeyboard.instance.keysPressed);
|
||||
final key = event.logicalKey;
|
||||
final isMacOS = event.data is RawKeyEventDataMacOs;
|
||||
final modifierKeys = isMacOS ? _osxModifierKeys : _winModifierKeys;
|
||||
// If any one of below cases is hitten:
|
||||
// 1. None of the nonModifierKeys is pressed
|
||||
// 2. Press the key except the keys that trigger shortcut
|
||||
// We will skip this event
|
||||
if (!_nonModifierKeys.contains(key) ||
|
||||
keysPressed.difference(modifierKeys).length > 1 ||
|
||||
keysPressed
|
||||
.difference(isMacOS ? _macOsModifierKeys : _modifierKeys)
|
||||
.length >
|
||||
1 ||
|
||||
keysPressed.difference(_interestingKeys).isNotEmpty) {
|
||||
return false;
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
|
||||
if (_isCursorMoveAction(key)) {
|
||||
final isShortcutModifierPressed =
|
||||
isMacOS ? event.isMetaPressed : event.isControlPressed;
|
||||
|
||||
if (_moveKeys.contains(key)) {
|
||||
onCursorMove(
|
||||
key,
|
||||
isMacOS ? event.isAltPressed : event.isControlPressed,
|
||||
isMacOS ? event.isMetaPressed : event.isAltPressed,
|
||||
event.isShiftPressed,
|
||||
);
|
||||
return true;
|
||||
} else if (_isShortcutAction(event, key)) {
|
||||
onShortcut(_keyToShortcut[key]);
|
||||
return true;
|
||||
} else if (LogicalKeyboardKey.delete == key) {
|
||||
key,
|
||||
isMacOS ? event.isAltPressed : event.isControlPressed,
|
||||
isMacOS ? event.isMetaPressed : event.isAltPressed,
|
||||
event.isShiftPressed);
|
||||
} else if (isShortcutModifierPressed && (_shortcutKeys.contains(key))) {
|
||||
if (key == LogicalKeyboardKey.keyZ ||
|
||||
key == LogicalKeyboardKey.keyZ.toUpperCase()) {
|
||||
onShortcut(
|
||||
event.isShiftPressed ? InputShortcut.REDO : InputShortcut.UNDO);
|
||||
} else {
|
||||
onShortcut(_keyToShortcut[key]);
|
||||
}
|
||||
} else if (key == LogicalKeyboardKey.delete) {
|
||||
onDelete(true);
|
||||
return true;
|
||||
} else if (LogicalKeyboardKey.backspace == key) {
|
||||
} else if (key == LogicalKeyboardKey.backspace) {
|
||||
onDelete(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Helper
|
||||
|
||||
bool _isCursorMoveAction(LogicalKeyboardKey key) => _moveKeys.contains(key);
|
||||
|
||||
bool _isShortcutAction(RawKeyEvent event, LogicalKeyboardKey key) {
|
||||
if (!_shortcutKeys.contains(key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event.data is RawKeyEventDataMacOs) {
|
||||
return event.isMetaPressed;
|
||||
} else {
|
||||
return event.isControlPressed;
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
return KeyEventResult.handled;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,8 @@ class BaselineProxy extends SingleChildRenderObjectWidget {
|
||||
}
|
||||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, covariant RenderBaselineProxy renderObject) {
|
||||
void updateRenderObject(
|
||||
BuildContext context, covariant RenderBaselineProxy renderObject) {
|
||||
renderObject
|
||||
..textStyle = textStyle!
|
||||
..padding = padding!;
|
||||
@ -37,7 +38,8 @@ class EmbedProxy extends SingleChildRenderObjectWidget {
|
||||
const EmbedProxy(Widget child) : super(child: child);
|
||||
|
||||
@override
|
||||
RenderEmbedProxy createRenderObject(BuildContext context) => RenderEmbedProxy(null);
|
||||
RenderEmbedProxy createRenderObject(BuildContext context) =>
|
||||
RenderEmbedProxy(null);
|
||||
}
|
||||
|
||||
/* ---------------------------------- Text ---------------------------------- */
|
||||
@ -80,7 +82,8 @@ class RichTextProxy extends SingleChildRenderObjectWidget {
|
||||
}
|
||||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, covariant RenderParagraphProxy renderObject) {
|
||||
void updateRenderObject(
|
||||
BuildContext context, covariant RenderParagraphProxy renderObject) {
|
||||
renderObject
|
||||
..textStyle = textStyle
|
||||
..textAlign = textAlign
|
||||
|
@ -60,7 +60,8 @@ class RawEditor extends StatefulWidget {
|
||||
this.embedBuilder,
|
||||
) : assert(maxHeight == null || maxHeight > 0, 'maxHeight cannot be null'),
|
||||
assert(minHeight == null || minHeight >= 0, 'minHeight cannot be null'),
|
||||
assert(maxHeight == null || minHeight == null || maxHeight >= minHeight),
|
||||
assert(
|
||||
maxHeight == null || minHeight == null || maxHeight >= minHeight),
|
||||
showCursor = showCursor ?? true,
|
||||
super(key: key);
|
||||
|
||||
@ -111,7 +112,10 @@ abstract class EditorState extends State<RawEditor> {
|
||||
}
|
||||
|
||||
class _RawEditorState extends EditorState
|
||||
with AutomaticKeepAliveClientMixin<RawEditor>, WidgetsBindingObserver, TickerProviderStateMixin<RawEditor>
|
||||
with
|
||||
AutomaticKeepAliveClientMixin<RawEditor>,
|
||||
WidgetsBindingObserver,
|
||||
TickerProviderStateMixin<RawEditor>
|
||||
implements TextSelectionDelegate, TextInputClient {
|
||||
final GlobalKey _editorKey = GlobalKey();
|
||||
final List<TextEditingValue> _sentRemoteValues = [];
|
||||
@ -129,7 +133,8 @@ class _RawEditorState extends EditorState
|
||||
bool _didAutoFocus = false;
|
||||
bool _keyboardVisible = false;
|
||||
DefaultStyles? _styles;
|
||||
final ClipboardStatusNotifier? _clipboardStatus = kIsWeb ? null : ClipboardStatusNotifier();
|
||||
final ClipboardStatusNotifier? _clipboardStatus =
|
||||
kIsWeb ? null : ClipboardStatusNotifier();
|
||||
final LayerLink _toolbarLayerLink = LayerLink();
|
||||
final LayerLink _startHandleLayerLink = LayerLink();
|
||||
final LayerLink _endHandleLayerLink = LayerLink();
|
||||
@ -177,57 +182,78 @@ class _RawEditorState extends EditorState
|
||||
downKey = key == LogicalKeyboardKey.arrowDown;
|
||||
|
||||
if ((rightKey || leftKey) && !(rightKey && leftKey)) {
|
||||
newSelection =
|
||||
_jumpToBeginOrEndOfWord(newSelection, wordModifier, leftKey, rightKey, plainText, lineModifier, shift);
|
||||
newSelection = _jumpToBeginOrEndOfWord(newSelection, wordModifier,
|
||||
leftKey, rightKey, plainText, lineModifier, shift);
|
||||
}
|
||||
|
||||
if (downKey || upKey) {
|
||||
newSelection = _handleMovingCursorVertically(upKey, downKey, shift, selection, newSelection, plainText);
|
||||
newSelection = _handleMovingCursorVertically(
|
||||
upKey, downKey, shift, selection, newSelection, plainText);
|
||||
}
|
||||
|
||||
if (!shift) {
|
||||
newSelection = _placeCollapsedSelection(selection, newSelection, leftKey, rightKey);
|
||||
newSelection =
|
||||
_placeCollapsedSelection(selection, newSelection, leftKey, rightKey);
|
||||
}
|
||||
|
||||
widget.controller.updateSelection(newSelection, ChangeSource.LOCAL);
|
||||
}
|
||||
|
||||
TextSelection _placeCollapsedSelection(
|
||||
TextSelection selection, TextSelection newSelection, bool leftKey, bool rightKey) {
|
||||
TextSelection _placeCollapsedSelection(TextSelection selection,
|
||||
TextSelection newSelection, bool leftKey, bool rightKey) {
|
||||
var newOffset = newSelection.extentOffset;
|
||||
if (!selection.isCollapsed) {
|
||||
if (leftKey) {
|
||||
newOffset =
|
||||
newSelection.baseOffset < newSelection.extentOffset ? newSelection.baseOffset : newSelection.extentOffset;
|
||||
newOffset = newSelection.baseOffset < newSelection.extentOffset
|
||||
? newSelection.baseOffset
|
||||
: newSelection.extentOffset;
|
||||
} else if (rightKey) {
|
||||
newOffset =
|
||||
newSelection.baseOffset > newSelection.extentOffset ? newSelection.baseOffset : newSelection.extentOffset;
|
||||
newOffset = newSelection.baseOffset > newSelection.extentOffset
|
||||
? newSelection.baseOffset
|
||||
: newSelection.extentOffset;
|
||||
}
|
||||
}
|
||||
return TextSelection.fromPosition(TextPosition(offset: newOffset));
|
||||
}
|
||||
|
||||
TextSelection _handleMovingCursorVertically(
|
||||
bool upKey, bool downKey, bool shift, TextSelection selection, TextSelection newSelection, String plainText) {
|
||||
final originPosition = TextPosition(offset: upKey ? selection.baseOffset : selection.extentOffset);
|
||||
bool upKey,
|
||||
bool downKey,
|
||||
bool shift,
|
||||
TextSelection selection,
|
||||
TextSelection newSelection,
|
||||
String plainText) {
|
||||
final originPosition = TextPosition(
|
||||
offset: upKey ? selection.baseOffset : selection.extentOffset);
|
||||
|
||||
final child = getRenderEditor()!.childAtPosition(originPosition);
|
||||
final localPosition = TextPosition(offset: originPosition.offset - child.container.documentOffset);
|
||||
|
||||
var position = upKey ? child.getPositionAbove(localPosition) : child.getPositionBelow(localPosition);
|
||||
final localPosition = TextPosition(
|
||||
offset: originPosition.offset - child.container.documentOffset);
|
||||
var position = upKey
|
||||
? child.getPositionAbove(localPosition)
|
||||
: child.getPositionBelow(localPosition);
|
||||
|
||||
if (position == null) {
|
||||
final sibling = upKey ? getRenderEditor()!.childBefore(child) : getRenderEditor()!.childAfter(child);
|
||||
final sibling = upKey
|
||||
? getRenderEditor()!.childBefore(child)
|
||||
: getRenderEditor()!.childAfter(child);
|
||||
|
||||
if (sibling == null) {
|
||||
position = TextPosition(offset: upKey ? 0 : plainText.length - 1);
|
||||
} else {
|
||||
final finalOffset = Offset(child.getOffsetForCaret(localPosition).dx,
|
||||
sibling.getOffsetForCaret(TextPosition(offset: upKey ? sibling.container.length - 1 : 0)).dy);
|
||||
final finalOffset = Offset(
|
||||
child.getOffsetForCaret(localPosition).dx,
|
||||
sibling
|
||||
.getOffsetForCaret(TextPosition(
|
||||
offset: upKey ? sibling.container.length - 1 : 0))
|
||||
.dy);
|
||||
final siblingPosition = sibling.getPositionForOffset(finalOffset);
|
||||
position = TextPosition(offset: sibling.container.documentOffset + siblingPosition.offset);
|
||||
position = TextPosition(
|
||||
offset: sibling.container.documentOffset + siblingPosition.offset);
|
||||
}
|
||||
} else {
|
||||
position = TextPosition(offset: child.container.documentOffset + position.offset);
|
||||
position = TextPosition(
|
||||
offset: child.container.documentOffset + position.offset);
|
||||
}
|
||||
|
||||
if (position.offset == newSelection.extentOffset) {
|
||||
@ -250,33 +276,49 @@ class _RawEditorState extends EditorState
|
||||
return newSelection;
|
||||
}
|
||||
|
||||
TextSelection _jumpToBeginOrEndOfWord(TextSelection newSelection, bool wordModifier, bool leftKey, bool rightKey,
|
||||
String plainText, bool lineModifier, bool shift) {
|
||||
TextSelection _jumpToBeginOrEndOfWord(
|
||||
TextSelection newSelection,
|
||||
bool wordModifier,
|
||||
bool leftKey,
|
||||
bool rightKey,
|
||||
String plainText,
|
||||
bool lineModifier,
|
||||
bool shift) {
|
||||
if (wordModifier) {
|
||||
if (leftKey) {
|
||||
final textSelection = getRenderEditor()!.selectWordAtPosition(
|
||||
TextPosition(offset: _previousCharacter(newSelection.extentOffset, plainText, false)));
|
||||
TextPosition(
|
||||
offset: _previousCharacter(
|
||||
newSelection.extentOffset, plainText, false)));
|
||||
|
||||
return newSelection.copyWith(extentOffset: textSelection.baseOffset);
|
||||
}
|
||||
final textSelection = getRenderEditor()!
|
||||
.selectWordAtPosition(TextPosition(offset: _nextCharacter(newSelection.extentOffset, plainText, false)));
|
||||
final textSelection = getRenderEditor()!.selectWordAtPosition(
|
||||
TextPosition(
|
||||
offset:
|
||||
_nextCharacter(newSelection.extentOffset, plainText, false)));
|
||||
return newSelection.copyWith(extentOffset: textSelection.extentOffset);
|
||||
} else if (lineModifier) {
|
||||
if (leftKey) {
|
||||
final textSelection = getRenderEditor()!.selectLineAtPosition(
|
||||
TextPosition(offset: _previousCharacter(newSelection.extentOffset, plainText, false)));
|
||||
TextPosition(
|
||||
offset: _previousCharacter(
|
||||
newSelection.extentOffset, plainText, false)));
|
||||
return newSelection.copyWith(extentOffset: textSelection.baseOffset);
|
||||
}
|
||||
final startPoint = newSelection.extentOffset;
|
||||
if (startPoint < plainText.length) {
|
||||
final textSelection = getRenderEditor()!.selectLineAtPosition(TextPosition(offset: startPoint));
|
||||
final textSelection = getRenderEditor()!
|
||||
.selectLineAtPosition(TextPosition(offset: startPoint));
|
||||
return newSelection.copyWith(extentOffset: textSelection.extentOffset);
|
||||
}
|
||||
return newSelection;
|
||||
}
|
||||
|
||||
if (rightKey && newSelection.extentOffset < plainText.length) {
|
||||
final nextExtent = _nextCharacter(newSelection.extentOffset, plainText, true);
|
||||
final nextExtent =
|
||||
_nextCharacter(newSelection.extentOffset, plainText, true);
|
||||
|
||||
final distance = nextExtent - newSelection.extentOffset;
|
||||
newSelection = newSelection.copyWith(extentOffset: nextExtent);
|
||||
if (shift) {
|
||||
@ -286,7 +328,8 @@ class _RawEditorState extends EditorState
|
||||
}
|
||||
|
||||
if (leftKey && newSelection.extentOffset > 0) {
|
||||
final previousExtent = _previousCharacter(newSelection.extentOffset, plainText, true);
|
||||
final previousExtent =
|
||||
_previousCharacter(newSelection.extentOffset, plainText, true);
|
||||
final distance = newSelection.extentOffset - previousExtent;
|
||||
newSelection = newSelection.copyWith(extentOffset: previousExtent);
|
||||
if (shift) {
|
||||
@ -326,7 +369,9 @@ class _RawEditorState extends EditorState
|
||||
var count = 0;
|
||||
int? lastNonWhitespace;
|
||||
for (final currentString in string.characters) {
|
||||
if (!includeWhitespace && !WHITE_SPACE.contains(currentString.characters.first.toString().codeUnitAt(0))) {
|
||||
if (!includeWhitespace &&
|
||||
!WHITE_SPACE.contains(
|
||||
currentString.characters.first.toString().codeUnitAt(0))) {
|
||||
lastNonWhitespace = count;
|
||||
}
|
||||
if (count + currentString.length >= index) {
|
||||
@ -337,7 +382,8 @@ class _RawEditorState extends EditorState
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool get hasConnection => _textInputConnection != null && _textInputConnection!.attached;
|
||||
bool get hasConnection =>
|
||||
_textInputConnection != null && _textInputConnection!.attached;
|
||||
|
||||
void openConnectionIfNeeded() {
|
||||
if (!shouldCreateInputConnection) {
|
||||
@ -388,7 +434,8 @@ class _RawEditorState extends EditorState
|
||||
return;
|
||||
}
|
||||
|
||||
final shouldRemember = textEditingValue.text != _lastKnownRemoteTextEditingValue!.text;
|
||||
final shouldRemember =
|
||||
textEditingValue.text != _lastKnownRemoteTextEditingValue!.text;
|
||||
_lastKnownRemoteTextEditingValue = actualValue;
|
||||
_textInputConnection!.setEditingState(actualValue);
|
||||
if (shouldRemember) {
|
||||
@ -397,7 +444,8 @@ class _RawEditorState extends EditorState
|
||||
}
|
||||
|
||||
@override
|
||||
TextEditingValue? get currentTextEditingValue => _lastKnownRemoteTextEditingValue;
|
||||
TextEditingValue? get currentTextEditingValue =>
|
||||
_lastKnownRemoteTextEditingValue;
|
||||
|
||||
@override
|
||||
AutofillScope? get currentAutofillScope => null;
|
||||
@ -429,7 +477,8 @@ class _RawEditorState extends EditorState
|
||||
final text = value.text;
|
||||
final cursorPosition = value.selection.extentOffset;
|
||||
final diff = getDiff(oldText, text, cursorPosition);
|
||||
widget.controller.replaceText(diff.start, diff.deleted.length, diff.inserted, value.selection);
|
||||
widget.controller.replaceText(
|
||||
diff.start, diff.deleted.length, diff.inserted, value.selection);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -472,6 +521,20 @@ class _RawEditorState extends EditorState
|
||||
_sentRemoteValues.clear();
|
||||
}
|
||||
|
||||
@override
|
||||
void copySelection(SelectionChangedCause cause) {}
|
||||
|
||||
@override
|
||||
void cutSelection(SelectionChangedCause cause) {}
|
||||
|
||||
@override
|
||||
Future<void> pasteText(SelectionChangedCause cause) {
|
||||
return Future(() => {});
|
||||
}
|
||||
|
||||
@override
|
||||
void selectAll(SelectionChangedCause cause) {}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
assert(debugCheckHasMediaQuery(context));
|
||||
@ -479,8 +542,11 @@ class _RawEditorState extends EditorState
|
||||
super.build(context);
|
||||
|
||||
var _doc = widget.controller.document;
|
||||
if (_doc.isEmpty() && !widget.focusNode.hasFocus && widget.placeholder != null) {
|
||||
_doc = Document.fromJson(jsonDecode('[{"attributes":{"placeholder":true},"insert":"${widget.placeholder}\\n"}]'));
|
||||
if (_doc.isEmpty() &&
|
||||
!widget.focusNode.hasFocus &&
|
||||
widget.placeholder != null) {
|
||||
_doc = Document.fromJson(jsonDecode(
|
||||
'[{"attributes":{"placeholder":true},"insert":"${widget.placeholder}\\n"}]'));
|
||||
}
|
||||
|
||||
Widget child = CompositedTransformTarget(
|
||||
@ -503,7 +569,8 @@ class _RawEditorState extends EditorState
|
||||
);
|
||||
|
||||
if (widget.scrollable) {
|
||||
final baselinePadding = EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.item1);
|
||||
final baselinePadding =
|
||||
EdgeInsets.only(top: _styles!.paragraph!.verticalSpacing.item1);
|
||||
child = BaselineProxy(
|
||||
textStyle: _styles!.paragraph!.style,
|
||||
padding: baselinePadding,
|
||||
@ -534,7 +601,8 @@ class _RawEditorState extends EditorState
|
||||
);
|
||||
}
|
||||
|
||||
void _handleSelectionChanged(TextSelection selection, SelectionChangedCause cause) {
|
||||
void _handleSelectionChanged(
|
||||
TextSelection selection, SelectionChangedCause cause) {
|
||||
widget.controller.updateSelection(selection, ChangeSource.LOCAL);
|
||||
|
||||
_selectionOverlay?.handlesVisible = _shouldShowSelectionHandles();
|
||||
@ -563,7 +631,9 @@ class _RawEditorState extends EditorState
|
||||
_styles,
|
||||
widget.enableInteractiveSelection,
|
||||
_hasFocus,
|
||||
attrs.containsKey(Attribute.codeBlock.key) ? const EdgeInsets.all(16) : null,
|
||||
attrs.containsKey(Attribute.codeBlock.key)
|
||||
? const EdgeInsets.all(16)
|
||||
: null,
|
||||
widget.embedBuilder,
|
||||
_cursorController,
|
||||
indentLevelCounts);
|
||||
@ -575,7 +645,8 @@ class _RawEditorState extends EditorState
|
||||
return result;
|
||||
}
|
||||
|
||||
EditableTextLine _getEditableTextLineFromNode(Line node, BuildContext context) {
|
||||
EditableTextLine _getEditableTextLineFromNode(
|
||||
Line node, BuildContext context) {
|
||||
final textLine = TextLine(
|
||||
line: node,
|
||||
textDirection: _textDirection,
|
||||
@ -598,7 +669,8 @@ class _RawEditorState extends EditorState
|
||||
return editableTextLine;
|
||||
}
|
||||
|
||||
Tuple2<double, double> _getVerticalSpacingForLine(Line line, DefaultStyles? defaultStyles) {
|
||||
Tuple2<double, double> _getVerticalSpacingForLine(
|
||||
Line line, DefaultStyles? defaultStyles) {
|
||||
final attrs = line.style.attributes;
|
||||
if (attrs.containsKey(Attribute.header.key)) {
|
||||
final int? level = attrs[Attribute.header.key]!.value;
|
||||
@ -623,7 +695,8 @@ class _RawEditorState extends EditorState
|
||||
return defaultStyles!.paragraph!.verticalSpacing;
|
||||
}
|
||||
|
||||
Tuple2<double, double> _getVerticalSpacingForBlock(Block node, DefaultStyles? defaultStyles) {
|
||||
Tuple2<double, double> _getVerticalSpacingForBlock(
|
||||
Block node, DefaultStyles? defaultStyles) {
|
||||
final attrs = node.style.attributes;
|
||||
if (attrs.containsKey(Attribute.quoteBlock.key)) {
|
||||
return defaultStyles!.quote!.verticalSpacing;
|
||||
@ -666,7 +739,8 @@ class _RawEditorState extends EditorState
|
||||
} else {
|
||||
_keyboardVisibilityController = KeyboardVisibilityController();
|
||||
_keyboardVisible = _keyboardVisibilityController!.isVisible;
|
||||
_keyboardVisibilitySubscription = _keyboardVisibilityController?.onChange.listen((visible) {
|
||||
_keyboardVisibilitySubscription =
|
||||
_keyboardVisibilityController?.onChange.listen((visible) {
|
||||
_keyboardVisible = visible;
|
||||
if (visible) {
|
||||
_onChangeTextEditingValue();
|
||||
@ -674,13 +748,8 @@ class _RawEditorState extends EditorState
|
||||
});
|
||||
}
|
||||
|
||||
_focusAttachment = widget.focusNode.attach(context, onKey: (node, event) {
|
||||
if (_keyboardListener.handleRawKeyEvent(event)) {
|
||||
return KeyEventResult.handled;
|
||||
} else {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
});
|
||||
_focusAttachment = widget.focusNode.attach(context,
|
||||
onKey: (node, event) => _keyboardListener.handleRawKeyEvent(event));
|
||||
widget.focusNode.addListener(_handleFocusChanged);
|
||||
}
|
||||
|
||||
@ -689,7 +758,9 @@ class _RawEditorState extends EditorState
|
||||
super.didChangeDependencies();
|
||||
final parentStyles = EditorStyles.getStyles(context, true);
|
||||
final defaultStyles = DefaultStyles.getInstance(context);
|
||||
_styles = (parentStyles != null) ? defaultStyles.merge(parentStyles) : defaultStyles;
|
||||
_styles = (parentStyles != null)
|
||||
? defaultStyles.merge(parentStyles)
|
||||
: defaultStyles;
|
||||
|
||||
if (widget.customStyles != null) {
|
||||
_styles = _styles!.merge(widget.customStyles!);
|
||||
@ -723,13 +794,8 @@ class _RawEditorState extends EditorState
|
||||
if (widget.focusNode != oldWidget.focusNode) {
|
||||
oldWidget.focusNode.removeListener(_handleFocusChanged);
|
||||
_focusAttachment?.detach();
|
||||
_focusAttachment = widget.focusNode.attach(context, onKey: (node, event) {
|
||||
if (_keyboardListener.handleRawKeyEvent(event)) {
|
||||
return KeyEventResult.handled;
|
||||
} else {
|
||||
return KeyEventResult.ignored;
|
||||
}
|
||||
});
|
||||
_focusAttachment = widget.focusNode.attach(context,
|
||||
onKey: (node, event) => _keyboardListener.handleRawKeyEvent(event));
|
||||
widget.focusNode.addListener(_handleFocusChanged);
|
||||
updateKeepAlive();
|
||||
}
|
||||
@ -749,7 +815,8 @@ class _RawEditorState extends EditorState
|
||||
}
|
||||
|
||||
bool _shouldShowSelectionHandles() {
|
||||
return widget.showSelectionHandles && !widget.controller.selection.isCollapsed;
|
||||
return widget.showSelectionHandles &&
|
||||
!widget.controller.selection.isCollapsed;
|
||||
}
|
||||
|
||||
void handleDelete(bool forward) {
|
||||
@ -760,7 +827,8 @@ class _RawEditorState extends EditorState
|
||||
var textAfter = selection.textAfter(plainText);
|
||||
if (selection.isCollapsed) {
|
||||
if (!forward && textBefore.isNotEmpty) {
|
||||
final characterBoundary = _previousCharacter(textBefore.length, textBefore, true);
|
||||
final characterBoundary =
|
||||
_previousCharacter(textBefore.length, textBefore, true);
|
||||
textBefore = textBefore.substring(0, characterBoundary);
|
||||
cursorPosition = characterBoundary;
|
||||
}
|
||||
@ -783,13 +851,24 @@ class _RawEditorState extends EditorState
|
||||
Future<void> handleShortcut(InputShortcut? shortcut) async {
|
||||
final selection = widget.controller.selection;
|
||||
final plainText = textEditingValue.text;
|
||||
if (shortcut == InputShortcut.SAVE) {
|
||||
widget.controller.save();
|
||||
|
||||
if (shortcut == InputShortcut.UNDO) {
|
||||
if (widget.controller.hasUndo) {
|
||||
widget.controller.undo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (shortcut == InputShortcut.REDO) {
|
||||
if (widget.controller.hasRedo) {
|
||||
widget.controller.redo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (shortcut == InputShortcut.COPY) {
|
||||
if (!selection.isCollapsed) {
|
||||
await Clipboard.setData(ClipboardData(text: selection.textInside(plainText)));
|
||||
await Clipboard.setData(
|
||||
ClipboardData(text: selection.textInside(plainText)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -806,7 +885,8 @@ class _RawEditorState extends EditorState
|
||||
);
|
||||
|
||||
textEditingValue = TextEditingValue(
|
||||
text: selection.textBefore(plainText) + selection.textAfter(plainText),
|
||||
text:
|
||||
selection.textBefore(plainText) + selection.textAfter(plainText),
|
||||
selection: TextSelection.collapsed(offset: selection.start),
|
||||
);
|
||||
}
|
||||
@ -824,7 +904,8 @@ class _RawEditorState extends EditorState
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (shortcut == InputShortcut.SELECT_ALL && widget.enableInteractiveSelection) {
|
||||
if (shortcut == InputShortcut.SELECT_ALL &&
|
||||
widget.enableInteractiveSelection) {
|
||||
widget.controller.updateSelection(
|
||||
selection.copyWith(
|
||||
baseOffset: 0,
|
||||
@ -878,14 +959,16 @@ class _RawEditorState extends EditorState
|
||||
void _onChangeTextEditingValue() {
|
||||
_showCaretOnScreen();
|
||||
updateRemoteValueIfNeeded();
|
||||
_cursorController.startOrStopCursorTimerIfNeeded(_hasFocus, widget.controller.selection);
|
||||
_cursorController.startOrStopCursorTimerIfNeeded(
|
||||
_hasFocus, widget.controller.selection);
|
||||
if (hasConnection) {
|
||||
_cursorController
|
||||
..stopCursorTimer(resetCharTicks: false)
|
||||
..startCursorTimer();
|
||||
}
|
||||
|
||||
SchedulerBinding.instance!.addPostFrameCallback((_) => _updateOrDisposeSelectionOverlayIfNeeded());
|
||||
SchedulerBinding.instance!.addPostFrameCallback(
|
||||
(_) => _updateOrDisposeSelectionOverlayIfNeeded());
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
// Use widget.controller.value in build()
|
||||
@ -928,7 +1011,8 @@ class _RawEditorState extends EditorState
|
||||
|
||||
void _handleFocusChanged() {
|
||||
openOrCloseConnection();
|
||||
_cursorController.startOrStopCursorTimerIfNeeded(_hasFocus, widget.controller.selection);
|
||||
_cursorController.startOrStopCursorTimerIfNeeded(
|
||||
_hasFocus, widget.controller.selection);
|
||||
_updateOrDisposeSelectionOverlayIfNeeded();
|
||||
if (_hasFocus) {
|
||||
WidgetsBinding.instance!.addObserver(this);
|
||||
@ -959,7 +1043,8 @@ class _RawEditorState extends EditorState
|
||||
_showCaretOnScreenScheduled = false;
|
||||
|
||||
final viewport = RenderAbstractViewport.of(getRenderEditor())!;
|
||||
final editorOffset = getRenderEditor()!.localToGlobal(const Offset(0, 0), ancestor: viewport);
|
||||
final editorOffset = getRenderEditor()!
|
||||
.localToGlobal(const Offset(0, 0), ancestor: viewport);
|
||||
final offsetInViewport = _scrollController!.offset + editorOffset.dy;
|
||||
|
||||
final offset = getRenderEditor()!.getOffsetToRevealCursor(
|
||||
@ -1042,7 +1127,8 @@ class _RawEditorState extends EditorState
|
||||
final value = textEditingValue;
|
||||
final data = await Clipboard.getData(Clipboard.kTextPlain);
|
||||
if (data != null) {
|
||||
final length = textEditingValue.selection.end - textEditingValue.selection.start;
|
||||
final length =
|
||||
textEditingValue.selection.end - textEditingValue.selection.start;
|
||||
widget.controller.replaceText(
|
||||
value.selection.start,
|
||||
length,
|
||||
@ -1051,7 +1137,9 @@ class _RawEditorState extends EditorState
|
||||
);
|
||||
// move cursor to the end of pasted text selection
|
||||
widget.controller.updateSelection(
|
||||
TextSelection.collapsed(offset: value.selection.start + data.text!.length), ChangeSource.LOCAL);
|
||||
TextSelection.collapsed(
|
||||
offset: value.selection.start + data.text!.length),
|
||||
ChangeSource.LOCAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1061,7 +1149,8 @@ class _RawEditorState extends EditorState
|
||||
if (data == null) {
|
||||
return false;
|
||||
}
|
||||
return textEditingValue.text.length - value.text.length == data.text!.length;
|
||||
return textEditingValue.text.length - value.text.length ==
|
||||
data.text!.length;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -1094,7 +1183,8 @@ class _RawEditorState extends EditorState
|
||||
}
|
||||
|
||||
@override
|
||||
void userUpdateTextEditingValue(TextEditingValue value, SelectionChangedCause cause) {
|
||||
void userUpdateTextEditingValue(
|
||||
TextEditingValue value, SelectionChangedCause cause) {
|
||||
// TODO: implement userUpdateTextEditingValue
|
||||
}
|
||||
}
|
||||
@ -1144,7 +1234,8 @@ class _Editor extends MultiChildRenderObjectWidget {
|
||||
}
|
||||
|
||||
@override
|
||||
void updateRenderObject(BuildContext context, covariant RenderEditor renderObject) {
|
||||
void updateRenderObject(
|
||||
BuildContext context, covariant RenderEditor renderObject) {
|
||||
renderObject
|
||||
..document = document
|
||||
..container = document.root
|
||||
|
@ -474,7 +474,7 @@ class __CheckboxState extends State<_Checkbox> {
|
||||
return Container(
|
||||
alignment: AlignmentDirectional.topEnd,
|
||||
width: widget.width,
|
||||
padding: const EdgeInsetsDirectional.only(end: 13),
|
||||
padding: const EdgeInsetsDirectional.only(end: 2),
|
||||
child: Checkbox(
|
||||
value: widget.isChecked,
|
||||
onChanged: _onCheckboxChanged,
|
||||
|
@ -35,7 +35,7 @@ packages:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
version: "2.8.2"
|
||||
bloc:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -112,7 +112,7 @@ packages:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -470,7 +470,7 @@ packages:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10"
|
||||
version: "0.12.11"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -743,7 +743,7 @@ packages:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.1"
|
||||
version: "0.4.3"
|
||||
textstyle_extensions:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
Loading…
Reference in New Issue
Block a user