Пример #1
0
 public override Widget buildToolbar(BuildContext context, Rect globalEditableRegion, Offset position,
                                     TextSelectionDelegate selectionDelegate)
 {
     return(new ConstrainedBox(
                constraints: BoxConstraints.tight(globalEditableRegion.size),
                child: new CustomSingleChildLayout(
                    layoutDelegate: new _TextSelectionToolbarLayout(
                        MediaQuery.of(context).size,
                        globalEditableRegion,
                        position
                        ),
                    child: new _TextSelectionToolbar(
                        handleCut: this.canCut(selectionDelegate)
                     ? () => this.handleCut(selectionDelegate)
                     : (VoidCallback)null,
                        handleCopy: this.canCopy(selectionDelegate)
                     ? () => this.handleCopy(selectionDelegate)
                     : (VoidCallback)null,
                        handlePaste: this.canPaste(selectionDelegate)
                     ? () => this.handlePaste(selectionDelegate)
                     : (VoidCallback)null,
                        handleSelectAll: this.canSelectAll(selectionDelegate)
                     ? () => this.handleSelectAll(selectionDelegate)
                     : (VoidCallback)null
                        )
                    )
                ));
 }
Пример #2
0
        public TextSelectionOverlay(TextEditingValue value                  = null,
                                    BuildContext context                    = null, Widget debugRequiredFor = null,
                                    LayerLink layerLink                     = null,
                                    RenderEditable renderObject             = null,
                                    TextSelectionControls selectionControls = null,
                                    TextSelectionDelegate selectionDelegate = null,
                                    DragStartBehavior dragStartBehavior     = DragStartBehavior.start)
        {
            D.assert(value != null);
            D.assert(context != null);
            this.context           = context;
            this.debugRequiredFor  = debugRequiredFor;
            this.layerLink         = layerLink;
            this.renderObject      = renderObject;
            this.selectionControls = selectionControls;
            this.selectionDelegate = selectionDelegate;
            this._value            = value;
            OverlayState overlay = Overlay.of(context);

            D.assert(overlay != null, () => $"No Overlay widget exists above {context}.\n" +
                     "Usually the Navigator created by WidgetsApp provides the overlay. Perhaps your " +
                     "app content was created above the Navigator with the WidgetsApp builder parameter.");
            this._toolbarController = new AnimationController(duration: fadeDuration, vsync: overlay);
            this.dragStartBehavior  = dragStartBehavior;
        }
Пример #3
0
        public override Widget buildToolbar(
            BuildContext context,
            Rect globalEditableRegion,
            Offset position,
            TextSelectionDelegate selectionDelegate
            )
        {
            float availableHeight
                = globalEditableRegion.top - MediaQuery.of(context).padding.top - CustomTextSelectionControlsUtils._kToolbarScreenPadding;
            _ArrowDirection direction = availableHeight > CustomTextSelectionControlsUtils._kToolbarHeight
                ? _ArrowDirection.down
                : _ArrowDirection.up;

            float y = direction == _ArrowDirection.up
                ? globalEditableRegion.height + CustomTextSelectionControlsUtils._kToolbarHeight + 6.0f
                : 0.0f;

            return(new ConstrainedBox(
                       constraints: BoxConstraints.tight(globalEditableRegion.size),
                       child: new CustomSingleChildLayout(
                           layoutDelegate: new _TextSelectionToolbarLayout(
                               MediaQuery.of(context).size,
                               globalEditableRegion,
                               new Offset(position.dx, position.dy + y)
                               ),
                           child: new _TextSelectionToolbar(
                               handleCut: this.canCut(selectionDelegate) ? () => this.handleCut(selectionDelegate) : (VoidCallback)null,
                               handleCopy: this.canCopy(selectionDelegate) ? () => this.handleCopy(selectionDelegate) : (VoidCallback)null,
                               handlePaste: this.canPaste(selectionDelegate) ? () => this.handlePaste(selectionDelegate) : (VoidCallback)null,
                               handleSelectAll: this.canSelectAll(selectionDelegate) ? () => this.handleSelectAll(selectionDelegate) : (VoidCallback)null,
                               arrowDirection: direction
                               )
                           )
                       ));
        }
Пример #4
0
 public _Editable(TextSpan textSpan                  = null, TextEditingValue value          = null,
                  Color cursorColor                  = 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,
                  CaretChangedHandler onCaretChanged = null, bool rendererIgnoresPointer = false,
                  Key key = null, TextSelectionDelegate textSelectionDelegate            = null) : base(key)
 {
     this.textSpan               = textSpan;
     this.value                  = value;
     this.cursorColor            = cursorColor;
     this.showCursor             = showCursor;
     this.hasFocus               = hasFocus;
     this.maxLines               = maxLines;
     this.selectionColor         = selectionColor;
     this.textScaleFactor        = textScaleFactor;
     this.textAlign              = textAlign;
     this.textDirection          = textDirection;
     this.obscureText            = obscureText;
     this.autocorrect            = autocorrect;
     this.offset                 = offset;
     this.onSelectionChanged     = onSelectionChanged;
     this.onCaretChanged         = onCaretChanged;
     this.rendererIgnoresPointer = rendererIgnoresPointer;
     this.textSelectionDelegate  = textSelectionDelegate;
 }
        new bool canSelectAll(TextSelectionDelegate selectionDelegate)
        {
            TextEditingValue value = selectionDelegate.textEditingValue;

            return(selectionDelegate.selectAllEnabled &&
                   value.text.isNotEmpty() &&
                   !(value.selection.start == 0 && value.selection.end == value.text.Length));
        }
Пример #6
0
 public abstract Widget buildToolbar(
     BuildContext context,
     Rect globalEditableRegion,
     float textLineHeight,
     Offset position,
     List <TextSelectionPoint> endpoints,
     TextSelectionDelegate selectionDelegate
     );
Пример #7
0
 public void handleSelectAll(TextSelectionDelegate selectionDelegate)
 {
     selectionDelegate.textEditingValue = new TextEditingValue(
         text: selectionDelegate.textEditingValue.text,
         selection: new TextSelection(
             baseOffset: 0,
             extentOffset: selectionDelegate.textEditingValue.text.Length
             )
         );
     selectionDelegate.bringIntoView(selectionDelegate.textEditingValue.selection.extendPos);
 }
Пример #8
0
        public void handleCopy(TextSelectionDelegate selectionDelegate)
        {
            TextEditingValue value = selectionDelegate.textEditingValue;

            Clipboard.setData(new ClipboardData(
                                  text: value.selection.textInside(value.text)
                                  ));
            selectionDelegate.textEditingValue = new TextEditingValue(
                text: value.text,
                selection: TextSelection.collapsed(offset: value.selection.end)
                );
            selectionDelegate.bringIntoView(selectionDelegate.textEditingValue.selection.extendPos);
            selectionDelegate.hideToolbar();
        }
Пример #9
0
        public RenderEditable(TextSpan text, TextDirection textDirection, ViewportOffset offset,
                              ValueNotifier <bool> showCursor,
                              TextAlign textAlign                         = TextAlign.left, float textScaleFactor = 1.0f, Color cursorColor = null,
                              bool?hasFocus                               = null, int?maxLines = 1, Color selectionColor = null,
                              TextSelection selection                     = null, bool obscureText = false, SelectionChangedHandler onSelectionChanged = null,
                              CaretChangedHandler onCaretChanged          = null, bool ignorePointer = false,
                              float cursorWidth                           = 1.0f,
                              Radius cursorRadius                         = null,
                              bool enableInteractiveSelection             = true,
                              TextSelectionDelegate textSelectionDelegate = null)
        {
            D.assert(textSelectionDelegate != null);
            this._textPainter = new TextPainter(text: text, textAlign: textAlign, textDirection: textDirection,
                                                textScaleFactor: textScaleFactor);
            this._cursorColor                = cursorColor;
            this._showCursor                 = showCursor ?? new ValueNotifier <bool>(false);
            this._hasFocus                   = hasFocus ?? false;
            this._maxLines                   = maxLines;
            this._selectionColor             = selectionColor;
            this._selection                  = selection;
            this._obscureText                = obscureText;
            this._offset                     = offset;
            this._cursorWidth                = cursorWidth;
            this._cursorRadius               = cursorRadius;
            this._enableInteractiveSelection = enableInteractiveSelection;
            this.ignorePointer               = ignorePointer;
            this.onCaretChanged              = onCaretChanged;
            this.onSelectionChanged          = onSelectionChanged;
            this.textSelectionDelegate       = textSelectionDelegate;

            D.assert(this._maxLines == null || this._maxLines > 0);
            D.assert(this._showCursor != null);
            D.assert(!this._showCursor.value || cursorColor != null);

            this._tap                   = new TapGestureRecognizer(this);
            this._doubleTap             = new DoubleTapGestureRecognizer(this);
            this._tap.onTapDown         = this._handleTapDown;
            this._tap.onTap             = this._handleTap;
            this._doubleTap.onDoubleTap = this._handleDoubleTap;
            this._longPress             = new LongPressGestureRecognizer(debugOwner: this);
            this._longPress.onLongPress = this._handleLongPress;
        }
Пример #10
0
        public void handlePaste(TextSelectionDelegate selectionDelegate)
        {
            TextEditingValue value = selectionDelegate.textEditingValue; // Snapshot the input before using `await`.

            Clipboard.getData(Clipboard.kTextPlain).Then((data) => {
                if (data != null)
                {
                    selectionDelegate.textEditingValue = new TextEditingValue(
                        text: value.selection.textBefore(value.text)
                        + data.text
                        + value.selection.textAfter(value.text),
                        selection: TextSelection.collapsed(
                            offset: value.selection.start + data.text.Length
                            )
                        );
                }

                selectionDelegate.bringIntoView(selectionDelegate.textEditingValue.selection.extendPos);
                selectionDelegate.hideToolbar();
            });
        }
Пример #11
0
        public TextSelectionOverlay(TextEditingValue value                  = null,
                                    BuildContext context                    = null, Widget debugRequiredFor = null,
                                    LayerLink layerLink                     = null,
                                    RenderEditable renderObject             = null,
                                    TextSelectionControls selectionControls = null,
                                    TextSelectionDelegate selectionDelegate = null)
        {
            D.assert(value != null);
            D.assert(context != null);
            this.context           = context;
            this.debugRequiredFor  = debugRequiredFor;
            this.layerLink         = layerLink;
            this.renderObject      = renderObject;
            this.selectionControls = selectionControls;
            this.selectionDelegate = selectionDelegate;
            this._value            = value;
            OverlayState overlay = Overlay.of(context);

            D.assert(overlay != null);
            this._handleController  = new AnimationController(duration: _fadeDuration, vsync: overlay);
            this._toolbarController = new AnimationController(duration: _fadeDuration, vsync: overlay);
        }
Пример #12
0
        public TextSelectionOverlay(
            TextEditingValue value                  = null,
            BuildContext context                    = null,
            Widget debugRequiredFor                 = null,
            LayerLink toolbarLayerLink              = null,
            LayerLink startHandleLayerLink          = null,
            LayerLink endHandleLayerLink            = null,
            RenderEditable renderObject             = null,
            TextSelectionControls selectionControls = null,
            bool?handlesVisible = false,
            TextSelectionDelegate selectionDelegate = null,
            DragStartBehavior dragStartBehavior     = DragStartBehavior.start,
            VoidCallback onSelectionHandleTapped    = null)
        {
            D.assert(value != null);
            D.assert(context != null);
            D.assert(handlesVisible != null);
            _handlesVisible              = handlesVisible.Value;
            this.context                 = context;
            this.debugRequiredFor        = debugRequiredFor;
            this.toolbarLayerLink        = toolbarLayerLink;
            this.startHandleLayerLink    = startHandleLayerLink;
            this.endHandleLayerLink      = endHandleLayerLink;
            this.renderObject            = renderObject;
            this.selectionControls       = selectionControls;
            this.selectionDelegate       = selectionDelegate;
            this.onSelectionHandleTapped = onSelectionHandleTapped;
            _value = value;
            OverlayState overlay = Overlay.of(context, rootOverlay: true);

            D.assert(overlay != null, () => $"No Overlay widget exists above {context}.\n" +
                     "Usually the Navigator created by WidgetsApp provides the overlay. Perhaps your " +
                     "app content was created above the Navigator with the WidgetsApp builder parameter.");
            _toolbarController     = new AnimationController(duration: fadeDuration, vsync: overlay);
            this.dragStartBehavior = dragStartBehavior;
        }
Пример #13
0
 public bool canCopy(TextSelectionDelegate _delegate)
 {
     return(_delegate.copyEnabled && !_delegate.textEditingValue.selection.isCollapsed);
 }
Пример #14
0
        public override Widget buildToolbar(
            BuildContext context,
            Rect globalEditableRegion,
            float textLineHeight,
            Offset position,
            List <TextSelectionPoint> endpoints,
            TextSelectionDelegate _delegate
            )
        {
            D.assert(WidgetsD.debugCheckHasMediaQuery(context));
            MediaQueryData mediaQuery = MediaQuery.of(context);

            float toolbarHeightNeeded = mediaQuery.padding.top
                                        + CupertinoTextSelectionUtils._kToolbarScreenPadding
                                        + CupertinoTextSelectionUtils._kToolbarHeight
                                        + CupertinoTextSelectionUtils._kToolbarContentDistance;
            float availableHeight     = globalEditableRegion.top + endpoints.first().point.dy - textLineHeight;
            bool  isArrowPointingDown = toolbarHeightNeeded <= availableHeight;

            float arrowTipX = (position.dx + globalEditableRegion.left).clamp(
                CupertinoTextSelectionUtils._kArrowScreenPadding + mediaQuery.padding.left,
                mediaQuery.size.width - mediaQuery.padding.right - CupertinoTextSelectionUtils._kArrowScreenPadding
                );
            float localBarTopY = isArrowPointingDown
                  ? endpoints.first().point.dy - textLineHeight - CupertinoTextSelectionUtils._kToolbarContentDistance - CupertinoTextSelectionUtils._kToolbarHeight
                  : endpoints.last().point.dy + CupertinoTextSelectionUtils._kToolbarContentDistance;

            List <Widget> items = new List <Widget> {
            };
            Widget onePhysicalPixelVerticalDivider = new SizedBox(width: 1.0f / MediaQuery.of(context).devicePixelRatio);
            CupertinoLocalizations localizations   = CupertinoLocalizations.of(context);
            EdgeInsets             arrowPadding    = isArrowPointingDown
                  ? EdgeInsets.only(bottom: CupertinoTextSelectionUtils._kToolbarArrowSize.height)
                  : EdgeInsets.only(top: CupertinoTextSelectionUtils._kToolbarArrowSize.height);

            void addToolbarButtonIfNeeded(
                string text,
                Predicate predicate,
                OnPressed onPressed)
            {
                if (!predicate(_delegate))
                {
                    return;
                }

                if (items.isNotEmpty())
                {
                    items.Add(onePhysicalPixelVerticalDivider);
                }

                items.Add(new CupertinoButton(
                              child: new Text(text, style: CupertinoTextSelectionUtils._kToolbarButtonFontStyle),
                              color: CupertinoTextSelectionUtils._kToolbarBackgroundColor,
                              minSize: CupertinoTextSelectionUtils._kToolbarHeight,
                              padding: CupertinoTextSelectionUtils._kToolbarButtonPadding.add(arrowPadding),
                              borderRadius: null,
                              pressedOpacity: 0.7f,
                              onPressed: () => onPressed(_delegate)
                              ));
            }

            addToolbarButtonIfNeeded(localizations.cutButtonLabel, canCut, handleCut);
            addToolbarButtonIfNeeded(localizations.copyButtonLabel, canCopy, handleCopy);
            addToolbarButtonIfNeeded(localizations.pasteButtonLabel, canPaste, handlePaste);
            addToolbarButtonIfNeeded(localizations.selectAllButtonLabel, canSelectAll, handleSelectAll);
            return(new CupertinoTextSelectionToolbar(
                       barTopY: localBarTopY + globalEditableRegion.top,
                       arrowTipX: arrowTipX,
                       isArrowPointingDown: isArrowPointingDown,
                       child: items.isEmpty() ? null : new DecoratedBox(
                           decoration: new BoxDecoration(color: CupertinoTextSelectionUtils._kToolbarDividerColor),
                           child: new Row(mainAxisSize: MainAxisSize.min, children: items)
                           )
                       ));
        }
Пример #15
0
 public virtual bool canSelectAll(TextSelectionDelegate selectionDelegate)
 {
     return(selectionDelegate.textEditingValue.text.isNotEmpty() &&
            selectionDelegate.textEditingValue.selection.isCollapsed);
 }
Пример #16
0
 public virtual bool canPaste(TextSelectionDelegate selectionDelegate)
 {
     // TODO in flutter: return false when clipboard is empty
     return(true);
 }
Пример #17
0
 public virtual bool canCopy(TextSelectionDelegate selectionDelegate)
 {
     return(!selectionDelegate.textEditingValue.selection.isCollapsed);
 }
Пример #18
0
 public abstract Widget buildToolbar(BuildContext context, Rect globalEditableRegion, Offset position,
                                     TextSelectionDelegate selectionDelegate);
Пример #19
0
        public override Widget buildToolbar(BuildContext context, Rect globalEditableRegion, float textLineHeight,
                                            Offset selectionMidpoint, List <TextSelectionPoint> endpoints, TextSelectionDelegate selectionDelegate)
        {
            D.assert(WidgetsD.debugCheckHasMediaQuery(context));
            D.assert(material_.debugCheckHasMaterialLocalizations(context));

            TextSelectionPoint startTextSelectionPoint = endpoints[0];
            TextSelectionPoint endTextSelectionPoint   = endpoints.Count > 1
                ? endpoints[1]
                : endpoints[0];
            const float closedToolbarHeightNeeded = MaterialUtils._kToolbarScreenPadding
                                                    + MaterialUtils._kToolbarHeight
                                                    + MaterialUtils._kToolbarContentDistance;
            float paddingTop      = MediaQuery.of(context).padding.top;
            float availableHeight = globalEditableRegion.top
                                    + startTextSelectionPoint.point.dy
                                    - textLineHeight
                                    - paddingTop;
            bool   fitsAbove = closedToolbarHeightNeeded <= availableHeight;
            Offset anchor    = new Offset(
                globalEditableRegion.left + selectionMidpoint.dx,
                fitsAbove
                    ? globalEditableRegion.top + startTextSelectionPoint.point.dy - textLineHeight -
                MaterialUtils._kToolbarContentDistance
                    : globalEditableRegion.top + endTextSelectionPoint.point.dy +
                MaterialUtils._kToolbarContentDistanceBelow
                );

            return(new Stack(
                       children: new List <Widget>()
            {
                new CustomSingleChildLayout(
                    layoutDelegate: new _TextSelectionToolbarLayout(
                        anchor,
                        MaterialUtils._kToolbarScreenPadding + paddingTop,
                        fitsAbove
                        ),
                    child: new _TextSelectionToolbar(
                        handleCut: canCut(selectionDelegate)
                                ? () => handleCut(selectionDelegate)
                                : (VoidCallback)null,
                        handleCopy: canCopy(selectionDelegate)
                                ? () => handleCopy(selectionDelegate)
                                : (VoidCallback)null,
                        handlePaste: canPaste(selectionDelegate)
                                ? () => handlePaste(selectionDelegate)
                                : (VoidCallback)null,
                        handleSelectAll: canSelectAll(selectionDelegate)
                                ? () => handleSelectAll(selectionDelegate)
                                : (VoidCallback)null,
                        isAbove: fitsAbove
                        )
                    ),
            }
                       ));
        }
Пример #20
0
 public bool canSelectAll(TextSelectionDelegate _delegate)
 {
     return(_delegate.selectAllEnabled &&
            _delegate.textEditingValue.text.isNotEmpty() &&
            _delegate.textEditingValue.selection.isCollapsed);
 }
Пример #21
0
 public bool canPaste(TextSelectionDelegate _delegate)
 {
     // TODO(goderbauer): return false when clipboard is empty, https://github.com/flutter/flutter/issues/11254
     return(_delegate.pasteEnabled);
 }
Пример #22
0
 public virtual bool canCut(TextSelectionDelegate _delegate)
 {
     return(_delegate.cutEnabled && !_delegate.textEditingValue.selection.isCollapsed);
 }