|
|
|
|
|
|
StrutStyle strutStyle = null, |
|
|
|
Color cursorColor = null, |
|
|
|
Color backgroundCursorColor = null, |
|
|
|
TextAlign textAlign = TextAlign.left, |
|
|
|
TextAlign textAlign = TextAlign.start, |
|
|
|
TextDirection? textDirection = null, |
|
|
|
Locale locale = null, |
|
|
|
float? textScaleFactor = null, |
|
|
|
|
|
|
bool forceLine = false, |
|
|
|
bool forceLine = true, |
|
|
|
bool showCursor = false, |
|
|
|
bool? showCursor = null, |
|
|
|
bool showSelectionHandles = false, |
|
|
|
Color selectionColor = null, |
|
|
|
TextSelectionControls selectionControls = null, |
|
|
|
|
|
|
VoidCallback onSelectionHandleTapped = null, |
|
|
|
List<TextInputFormatter> inputFormatters = null, |
|
|
|
bool rendererIgnoresPointer = false, |
|
|
|
float? cursorWidth = 2.0f, |
|
|
|
float cursorWidth = 2.0f, |
|
|
|
Radius cursorRadius = null, |
|
|
|
bool cursorOpacityAnimates = false, |
|
|
|
Offset cursorOffset = null, |
|
|
|
|
|
|
(maxLines == null) || (minLines == null) || (maxLines >= minLines), |
|
|
|
()=>"minLines can't be greater than maxLines" |
|
|
|
); |
|
|
|
D.assert(expands != null); |
|
|
|
D.assert( |
|
|
|
!expands || (maxLines == null && minLines == null),()=> |
|
|
|
"minLines and maxLines must be null when expands is true." |
|
|
|
|
|
|
this.keyboardAppearance = keyboardAppearance; |
|
|
|
this.enableInteractiveSelection = enableInteractiveSelection; |
|
|
|
this.dragStartBehavior = dragStartBehavior; |
|
|
|
this.scrollPhysics = scrollPhysics; |
|
|
|
// this.globalKeyEventHandler = globalKeyEventHandler;
|
|
|
|
this.scrollPhysics = scrollPhysics; |
|
|
|
} |
|
|
|
|
|
|
|
public readonly bool readOnly; |
|
|
|
|
|
|
public readonly TextWidthBasis textWidthBasis; |
|
|
|
public readonly VoidCallback onSelectionHandleTapped; |
|
|
|
public readonly ScrollController scrollController; |
|
|
|
public readonly bool showCursor; |
|
|
|
public readonly bool? showCursor; |
|
|
|
public readonly ui.BoxHeightStyle selectionHeightStyle; |
|
|
|
public readonly ui.BoxWidthStyle selectionWidthStyle; |
|
|
|
public readonly bool forceLine; |
|
|
|
|
|
|
if (_strutStyle == null) { |
|
|
|
return style != null |
|
|
|
? StrutStyle.fromTextStyle(style, forceStrutHeight: true) |
|
|
|
: StrutStyle.disabled; |
|
|
|
: new StrutStyle(); |
|
|
|
} |
|
|
|
|
|
|
|
return _strutStyle.inheritFromTextStyle(style); |
|
|
|
|
|
|
|
|
|
|
public class EditableTextState : AutomaticKeepAliveClientWithTickerProviderStateMixin<EditableText>, |
|
|
|
WidgetsBindingObserver, TextInputClient, |
|
|
|
TextSelectionDelegate { |
|
|
|
TextSelectionDelegate |
|
|
|
{ |
|
|
|
const int _kObscureShowLatestCharCursorTicks = 3; |
|
|
|
static TimeSpan _kCursorBlinkHalfPeriod = TimeSpan.FromMilliseconds(500); |
|
|
|
static TimeSpan _kCursorBlinkWaitForStart = TimeSpan.FromMilliseconds(150); |
|
|
|
|
|
|
_cursorBlinkOpacityController.addListener(_onCursorColorTick); |
|
|
|
_floatingCursorResetController = new AnimationController(vsync: this); |
|
|
|
_floatingCursorResetController.addListener(_onFloatingCursorResetTick); |
|
|
|
_cursorVisibilityNotifier.value = widget.showCursor; |
|
|
|
_cursorVisibilityNotifier.value = widget.showCursor ?? false; |
|
|
|
} |
|
|
|
|
|
|
|
public override void didChangeDependencies() { |
|
|
|
|
|
|
oldWidget.controller.removeListener(_didChangeTextEditingValue); |
|
|
|
widget.controller.addListener(_didChangeTextEditingValue); |
|
|
|
_updateRemoteEditingValueIfNeeded(); |
|
|
|
//_updateImePosIfNeed();
|
|
|
|
} |
|
|
|
if (widget.controller.selection != oldWidget.controller.selection) { |
|
|
|
_selectionOverlay?.update(_value); |
|
|
|
|
|
|
fontFamily: style.fontFamily, |
|
|
|
fontSize: style.fontSize, |
|
|
|
fontWeight: style.fontWeight, |
|
|
|
textDirection: _textDirection.Value, |
|
|
|
textDirection: (TextDirection)_textDirection, |
|
|
|
textAlign: widget.textAlign |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
_obscureLatestCharIndex = _value.selection.baseOffset; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_stopCursorTimer(resetCharTicks: false); |
|
|
|
_startCursorTimer(); |
|
|
|
} |
|
|
|
|
|
|
void _onCursorColorTick() { |
|
|
|
renderEditable.cursorColor = |
|
|
|
widget.cursorColor.withOpacity(_cursorBlinkOpacityController.value); |
|
|
|
_cursorVisibilityNotifier.value = widget.showCursor && _cursorBlinkOpacityController.value > 0; |
|
|
|
_cursorVisibilityNotifier.value = widget.showCursor.Value && _cursorBlinkOpacityController.value > 0; |
|
|
|
} |
|
|
|
|
|
|
|
public bool cursorCurrentlyVisible { |
|
|
|
|
|
|
link: _toolbarLayerLink, |
|
|
|
child: new _Editable( |
|
|
|
key: _editableKey, |
|
|
|
startHandleLayerLink: _startHandleLayerLink, |
|
|
|
endHandleLayerLink: _endHandleLayerLink, |
|
|
|
textSpan: buildTextSpan(), |
|
|
|
value: _value, |
|
|
|
cursorColor: _cursorColor, |
|
|
|
backgroundCursorColor: widget.backgroundCursorColor, |
|
|
|
showCursor: EditableText.debugDeterministicCursor |
|
|
|
? new ValueNotifier<bool>(widget.showCursor) |
|
|
|
: _cursorVisibilityNotifier, |
|
|
|
forceLine: widget.forceLine, |
|
|
|
readOnly: widget.readOnly, |
|
|
|
hasFocus: _hasFocus, |
|
|
|
maxLines: widget.maxLines, |
|
|
|
minLines: widget.minLines, |
|
|
|
expands: widget.expands, |
|
|
|
strutStyle: widget.strutStyle, |
|
|
|
selectionColor: widget.selectionColor, |
|
|
|
textScaleFactor: widget.textScaleFactor ?? MediaQuery.textScaleFactorOf(context), |
|
|
|
textAlign: widget.textAlign, |
|
|
|
textDirection: _textDirection, |
|
|
|
textWidthBasis: widget.textWidthBasis, |
|
|
|
obscureText: widget.obscureText, |
|
|
|
autocorrect: widget.autocorrect, |
|
|
|
smartDashesType: widget.smartDashesType, |
|
|
|
smartQuotesType: widget.smartQuotesType, |
|
|
|
enableSuggestions: widget.enableSuggestions, |
|
|
|
offset: offset, |
|
|
|
onSelectionChanged: _handleSelectionChanged, |
|
|
|
onCaretChanged: _handleCaretChanged, |
|
|
|
rendererIgnoresPointer: widget.rendererIgnoresPointer, |
|
|
|
cursorWidth: widget.cursorWidth, |
|
|
|
cursorRadius: widget.cursorRadius, |
|
|
|
cursorOffset: widget.cursorOffset, |
|
|
|
selectionHeightStyle: widget.selectionHeightStyle, |
|
|
|
selectionWidthStyle: widget.selectionWidthStyle, |
|
|
|
paintCursorAboveText: widget.paintCursorAboveText, |
|
|
|
enableInteractiveSelection: widget.enableInteractiveSelection == true, |
|
|
|
textSelectionDelegate: this, |
|
|
|
devicePixelRatio: _devicePixelRatio, |
|
|
|
globalKeyEventHandler : widget.globalKeyEventHandler |
|
|
|
startHandleLayerLink: _startHandleLayerLink, |
|
|
|
endHandleLayerLink: _endHandleLayerLink, |
|
|
|
textSpan: buildTextSpan(), |
|
|
|
value: _value, |
|
|
|
cursorColor: _cursorColor, |
|
|
|
backgroundCursorColor: widget.backgroundCursorColor, |
|
|
|
showCursor: EditableText.debugDeterministicCursor |
|
|
|
? new ValueNotifier<bool>(widget.showCursor ?? false) |
|
|
|
: _cursorVisibilityNotifier, |
|
|
|
forceLine: widget.forceLine, |
|
|
|
readOnly: widget.readOnly, |
|
|
|
hasFocus: _hasFocus, |
|
|
|
maxLines: widget.maxLines, |
|
|
|
minLines: widget.minLines, |
|
|
|
expands: widget.expands, |
|
|
|
strutStyle: widget.strutStyle, |
|
|
|
selectionColor: widget.selectionColor, |
|
|
|
textScaleFactor: widget.textScaleFactor ?? MediaQuery.textScaleFactorOf(context), |
|
|
|
textAlign: widget.textAlign, |
|
|
|
textDirection: _textDirection, |
|
|
|
locale: widget.locale, |
|
|
|
textWidthBasis: widget.textWidthBasis, |
|
|
|
obscureText: widget.obscureText, |
|
|
|
autocorrect: widget.autocorrect, |
|
|
|
smartDashesType: widget.smartDashesType, |
|
|
|
smartQuotesType: widget.smartQuotesType, |
|
|
|
enableSuggestions: widget.enableSuggestions, |
|
|
|
offset: offset, |
|
|
|
onSelectionChanged: _handleSelectionChanged, |
|
|
|
onCaretChanged: _handleCaretChanged, |
|
|
|
rendererIgnoresPointer: widget.rendererIgnoresPointer, |
|
|
|
cursorWidth: widget.cursorWidth, |
|
|
|
cursorRadius: widget.cursorRadius, |
|
|
|
cursorOffset: widget.cursorOffset, |
|
|
|
selectionHeightStyle: widget.selectionHeightStyle, |
|
|
|
selectionWidthStyle: widget.selectionWidthStyle, |
|
|
|
paintCursorAboveText: widget.paintCursorAboveText, |
|
|
|
enableInteractiveSelection: widget.enableInteractiveSelection ?? true, |
|
|
|
textSelectionDelegate: this, |
|
|
|
devicePixelRatio: _devicePixelRatio |
|
|
|
|
|
|
|
) |
|
|
|
) |
|
|
|
); |
|
|
|
|
|
|
public readonly StrutStyle strutStyle; |
|
|
|
public readonly Color selectionColor; |
|
|
|
public readonly float textScaleFactor; |
|
|
|
public readonly TextAlign textAlign; |
|
|
|
public readonly TextAlign? textAlign; |
|
|
|
public readonly TextDirection? textDirection; |
|
|
|
public readonly bool obscureText; |
|
|
|
public readonly TextWidthBasis textWidthBasis; |
|
|
|
|
|
|
public readonly TextSelectionDelegate textSelectionDelegate; |
|
|
|
public readonly bool? paintCursorAboveText; |
|
|
|
public readonly float? devicePixelRatio; |
|
|
|
public readonly GlobalKeyEventHandlerDelegate globalKeyEventHandler; |
|
|
|
|
|
|
|
public _Editable(TextSpan textSpan = null, |
|
|
|
//public readonly GlobalKeyEventHandlerDelegate globalKeyEventHandler;
|
|
|
|
public readonly Locale locale; |
|
|
|
public _Editable( |
|
|
|
Key key = null, |
|
|
|
TextSpan textSpan = null, |
|
|
|
TextEditingValue value = null, |
|
|
|
LayerLink startHandleLayerLink = null, |
|
|
|
LayerLink endHandleLayerLink = null, |
|
|
|
|
|
|
StrutStyle strutStyle = null, |
|
|
|
Color selectionColor = null, |
|
|
|
float textScaleFactor = 1.0f, |
|
|
|
TextAlign? textAlign = null, |
|
|
|
Locale locale = null, |
|
|
|
TextAlign textAlign = TextAlign.left, |
|
|
|
bool autocorrect = false, |
|
|
|
SmartDashesType smartDashesType = SmartDashesType.disabled, |
|
|
|
SmartQuotesType smartQuotesType = SmartQuotesType.disabled, |
|
|
|
|
|
|
CaretChangedHandler onCaretChanged = null, |
|
|
|
bool rendererIgnoresPointer = false, |
|
|
|
Key key = null, |
|
|
|
TextSelectionDelegate textSelectionDelegate = null, |
|
|
|
bool? paintCursorAboveText = null, |
|
|
|
bool? paintCursorAboveText = null, |
|
|
|
float? devicePixelRatio = null, |
|
|
|
GlobalKeyEventHandlerDelegate globalKeyEventHandler = null) : base(key) { |
|
|
|
TextSelectionDelegate textSelectionDelegate = null, |
|
|
|
float? devicePixelRatio = null |
|
|
|
//GlobalKeyEventHandlerDelegate globalKeyEventHandler = null
|
|
|
|
) : base(key) { |
|
|
|
this.locale = locale; |
|
|
|
this.backgroundCursorColor = backgroundCursorColor; |
|
|
|
this.showCursor = showCursor; |
|
|
|
this.forceLine = forceLine; |
|
|
|
|
|
|
this.selectionWidthStyle = selectionWidthStyle; |
|
|
|
this.enableInteractiveSelection = enableInteractiveSelection; |
|
|
|
this.devicePixelRatio = devicePixelRatio; |
|
|
|
this.globalKeyEventHandler = globalKeyEventHandler; |
|
|
|
//this.globalKeyEventHandler = globalKeyEventHandler;
|
|
|
|
textDirection: textDirection ?? TextDirection.ltr, |
|
|
|
offset: offset, |
|
|
|
showCursor: showCursor, |
|
|
|
showCursor: showCursor, |
|
|
|
forceLine: forceLine, |
|
|
|
readOnly: readOnly, |
|
|
|
hasFocus: hasFocus, |
|
|
|
|
|
|
strutStyle: strutStyle, |
|
|
|
selectionColor: selectionColor, |
|
|
|
textScaleFactor: textScaleFactor, |
|
|
|
textAlign: textAlign, |
|
|
|
textAlign: textAlign ?? TextAlign.start, |
|
|
|
textDirection: textDirection, |
|
|
|
locale: locale ?? Localizations.localeOf(context, nullOk: true), |
|
|
|
obscureText: obscureText, |
|
|
|
textWidthBasis: textWidthBasis, |
|
|
|
offset: offset, |
|
|
|
obscureText: obscureText, |
|
|
|
textWidthBasis: textWidthBasis, |
|
|
|
paintCursorAboveText: paintCursorAboveText ?? false, |
|
|
|
paintCursorAboveText: paintCursorAboveText == true, |
|
|
|
devicePixelRatio: devicePixelRatio ?? 1.0f, |
|
|
|
globalKeyEventHandler : globalKeyEventHandler |
|
|
|
devicePixelRatio: devicePixelRatio ?? 1.0f |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
edit.cursorColor = cursorColor; |
|
|
|
edit.startHandleLayerLink = startHandleLayerLink; |
|
|
|
edit.endHandleLayerLink = endHandleLayerLink; |
|
|
|
edit.backgroundCursorColor = backgroundCursorColor; |
|
|
|
edit.minLines = minLines; |
|
|
|
edit.expands = expands; |
|
|
|
edit.locale = locale ?? Localizations.localeOf(context, nullOk: true); |
|
|
|
edit.selection = value.selection; |
|
|
|
edit.offset = offset; |
|
|
|
edit.onSelectionChanged = onSelectionChanged; |
|
|
|
|
|
|
edit.obscureText = obscureText; |
|
|
|
edit.textSelectionDelegate = textSelectionDelegate; |
|
|
|
edit.cursorWidth = cursorWidth ?? 1.0f; |
|
|
|
edit.cursorWidth = cursorWidth ?? 0.0f; |
|
|
|
edit.enableInteractiveSelection = enableInteractiveSelection; |
|
|
|
edit.paintCursorAboveText = paintCursorAboveText == true; |
|
|
|
edit.textSelectionDelegate = textSelectionDelegate; |
|
|
|
edit.globalKeyEventHandler = globalKeyEventHandler; |
|
|
|
edit.paintCursorAboveText = paintCursorAboveText ?? false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |