|
|
|
|
|
|
public override State createState() { |
|
|
|
return new EditableTextState(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static bool debugDeterministicCursor = false; |
|
|
|
|
|
|
|
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|
|
|
|
|
|
public class EditableTextState : AutomaticKeepAliveClientWithTickerProviderStateMixin<EditableText>, |
|
|
|
WidgetsBindingObserver, TextInputClient, |
|
|
|
TextSelectionDelegate { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get { |
|
|
|
return this.widget.cursorColor.withOpacity(this._cursorBlinkOpacityController.value); |
|
|
|
} |
|
|
|
get { return this.widget.cursorColor.withOpacity(this._cursorBlinkOpacityController.value); } |
|
|
|
} |
|
|
|
|
|
|
|
public override void initState() { |
|
|
|
|
|
|
|
|
|
|
this._lastKnownRemoteTextEditingValue = value; |
|
|
|
this._formatAndSetValue(value); |
|
|
|
|
|
|
|
|
|
|
|
this._stopCursorTimer(resetCharTicks: false); |
|
|
|
this._startCursorTimer(); |
|
|
|
} |
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get { |
|
|
|
return new Offset(0, this.renderEditable.preferredLineHeight / 2); |
|
|
|
} |
|
|
|
get { return new Offset(0, this.renderEditable.preferredLineHeight / 2); } |
|
|
|
|
|
|
|
|
|
|
|
// TODO: remove comment when renderEditable is updated and FloatingCursorDragState is ready
|
|
|
|
// void updateFloatingCursor(RawFloatingCursorPoint point) {
|
|
|
|
// switch(point.state){
|
|
|
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: remove comment when RenderEditable.setFloatingCursor, Floating CursorDragState, and force press is ready
|
|
|
|
// void _onFloatingCursorResetTick() {
|
|
|
|
// Offset finalPosition = this.renderEditable.getLocalRectForCaret(this._lastTextPosition).centerLeft - this._floatingCursorOffset;
|
|
|
|
|
|
|
float caretOffset = (lineHeight - caretRect.height) / 2; |
|
|
|
caretStart = caretRect.top - caretOffset; |
|
|
|
caretEnd = caretRect.bottom + caretOffset; |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
|
|
|
|
float scrollOffset = this._scrollController.offset; |
|
|
|
float viewportExtent = this._scrollController.position.viewportDimension; |
|
|
|
if (caretStart < 0.0) { |
|
|
|
|
|
|
this.widget.onChanged(value.text); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.renderEditable.cursorColor = this.widget.cursorColor.withOpacity(this._cursorBlinkOpacityController.value); |
|
|
|
this.renderEditable.cursorColor = |
|
|
|
this.widget.cursorColor.withOpacity(this._cursorBlinkOpacityController.value); |
|
|
|
this._cursorVisibilityNotifier.value = this._cursorBlinkOpacityController.value > 0; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
public TimeSpan cursorBlinkInterval { |
|
|
|
get { return _kCursorBlinkHalfPeriod; } |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
get { |
|
|
|
return this._selectionOverlay; |
|
|
|
} |
|
|
|
get { return this._selectionOverlay; } |
|
|
|
} |
|
|
|
|
|
|
|
int _obscureShowCharTicksPending = 0; |
|
|
|
|
|
|
float targetOpacity = this._targetCursorVisibility ? 1.0f : 0.0f; |
|
|
|
if (this.widget.cursorOpacityAnimates) { |
|
|
|
this._cursorBlinkOpacityController.animateTo(targetOpacity, curve: Curves.easeOut); |
|
|
|
} else { |
|
|
|
} |
|
|
|
else { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void _cursorWaitForStart() { |
|
|
|
D.assert(_kCursorBlinkHalfPeriod > _fadeDuration); |
|
|
|
this._cursorTimer?.cancel(); |
|
|
|
|
|
|
this._targetCursorVisibility = true; |
|
|
|
this._cursorBlinkOpacityController.setValue(1.0f); |
|
|
|
this._cursorVisibilityNotifier.value = !this._unityKeyboard(); |
|
|
|
if (EditableText.debugDeterministicCursor) |
|
|
|
if (EditableText.debugDeterministicCursor) { |
|
|
|
} |
|
|
|
this._cursorTimer = Window.instance.run(_kCursorBlinkWaitForStart, this._cursorWaitForStart, periodic: true); |
|
|
|
this._cursorTimer = |
|
|
|
Window.instance.run(_kCursorBlinkWaitForStart, this._cursorWaitForStart, periodic: true); |
|
|
|
} |
|
|
|
else { |
|
|
|
this._cursorTimer = Window.instance.run(_kCursorBlinkHalfPeriod, this._cursorTick, periodic: true); |
|
|
|
|
|
|
this._targetCursorVisibility = false; |
|
|
|
this._cursorBlinkOpacityController.setValue(0.0f); |
|
|
|
this._cursorVisibilityNotifier.value = false; |
|
|
|
if (EditableText.debugDeterministicCursor) |
|
|
|
if (EditableText.debugDeterministicCursor) { |
|
|
|
if (resetCharTicks) |
|
|
|
} |
|
|
|
|
|
|
|
if (resetCharTicks) { |
|
|
|
} |
|
|
|
|
|
|
|
if (this.widget.cursorOpacityAnimates) { |
|
|
|
this._cursorBlinkOpacityController.stop(); |
|
|
|
this._cursorBlinkOpacityController.setValue(0.0f); |
|
|
|
|
|
|
this._formatAndSetValue(value); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
float _devicePixelRatio { |
|
|
|
get { return MediaQuery.of(this.context).devicePixelRatio; } |
|
|
|
} |
|
|
|
|
|
|
this._getScrollOffsetForCaret(this.renderEditable.getLocalRectForCaret(position))); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (this._selectionOverlay == null) |
|
|
|
if (this._selectionOverlay == null) { |
|
|
|
} |
|
|
|
|
|
|
|
this._selectionOverlay.showToolbar(); |
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public _Editable(TextSpan textSpan = null, TextEditingValue value = null, |
|
|
|
Color cursorColor = null, Color backgroundColor = null, ValueNotifier<bool> showCursor = null, bool hasFocus = false, |
|
|
|
Color cursorColor = null, Color backgroundColor = null, ValueNotifier<bool> showCursor = null, |
|
|
|
bool hasFocus = false, |
|
|
|
int? maxLines = null, Color selectionColor = null, float textScaleFactor = 1.0f, |
|
|
|
TextDirection? textDirection = null, bool obscureText = false, TextAlign textAlign = TextAlign.left, |
|
|
|
bool autocorrect = false, ViewportOffset offset = null, SelectionChangedHandler onSelectionChanged = null, |
|
|
|