Ejemplo n.º 1
0
        void Initialize()
        {
            _bufferGraph = _factoryService.BufferGraphFactoryService.CreateBufferGraph(this.TextViewModel.VisualBuffer);

            _editorFormatMap = _factoryService.EditorFormatMapService.GetEditorFormatMap(this);

            _baseLayer    = new ViewStack(_factoryService.OrderedViewLayerDefinitions, this);
            _overlayLayer = new ViewStack(_factoryService.OrderedOverlayLayerDefinitions, this, isOverlayLayer: true);

            // Create selection and make sure it's created before the caret as the caret relies on the selection being
            // available in its constructor
            _selection = new SkiaTextSelection(this, _editorFormatMap, _factoryService.GuardedOperations);

            // Create caret
            _caretElement = new SkiaTextCaret(this, _selection,
                                              _factoryService.SmartIndentationService,
                                              _editorFormatMap,
                                              _factoryService.GuardedOperations);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Calculate the selection rectangles that should be drawn on an ITextViewLine.
        /// </summary>
        /// <param name="line">The line on which the selection rectangles are to be calculated.</param>
        /// <param name="span">The span of the selection on that line.</param>
        /// <param name="selectionEnd">The end of the entire selection.</param>
        /// <param name="isBoxSelection">Is this a box selection?</param>
        /// <param name="isVirtualSpaceEnabled">Is virtual space turned on?</param>
        /// <remarks>internal for testability</remarks>
        internal static IList <Tuple <double, double> > CalculateVisualOverlapsForLine(ITextViewLine line, VirtualSnapshotSpan span, SnapshotPoint selectionEnd, bool isBoxSelection, bool isVirtualSpaceEnabled)
        {
            VirtualSnapshotPoint start = span.Start;
            VirtualSnapshotPoint end   = span.End;

            // if the requested start and ending points are the same, then simply return a caret wide bound on the line
            if (start == end)
            {
                double xLeft = SkiaTextCaret.GetXCoordinateFromVirtualBufferPosition(line, start);
                return(new FrugalList <Tuple <double, double> > ()
                {
                    new Tuple <double, double> (xLeft, xLeft + 2)
                });                                                                                                              //TODO: SystemParameters.CaretWidth) };
            }

            //If box selection is on, then every line is the "last" line of the selection.
            bool isLastLineOfSelection = isBoxSelection ||
                                         (selectionEnd < line.EndIncludingLineBreak) ||                                             //Selection ends before the end of line
                                         ((line.LineBreakLength == 0) && line.IsLastTextViewLineForSnapshotLine);                   //Or this is the last line.

            IList <Tuple <double, double> > leftRightPairs;

            //Draw the appropriate bits of the selection for virtual space.
            if (start.Position.Position == line.End.Position)
            {
                //The start is at (or beyond) the end of the line (therefore nothing inside the line is selected).
                double xStart = SkiaTextCaret.GetXCoordinateFromVirtualBufferPosition(line, start);

                double xEnd;
                if (isLastLineOfSelection)
                {
                    //Selection ends on this line as well ... draw a rectangle between them.
                    xEnd = SkiaTextCaret.GetXCoordinateFromVirtualBufferPosition(line, end);
                }
                else
                {
                    //Selection ends on a subsequent line. Show things differently when virtual space is turned on.
                    xEnd = isVirtualSpaceEnabled ? double.MaxValue : (xStart + line.EndOfLineWidth);
                }

                leftRightPairs = new FrugalList <Tuple <double, double> > ();

                if (xEnd > xStart)
                {
                    leftRightPairs.Add(new Tuple <double, double> (xStart, xEnd));
                }
            }
            else
            {
                //Add the bounds for the text in the line's interior.
                var bounds = line.GetNormalizedTextBounds(new SnapshotSpan(start.Position, end.Position));
                leftRightPairs = new List <Tuple <double, double> > (bounds.Count + 1);
                foreach (var bound in bounds)
                {
                    leftRightPairs.Add(new Tuple <double, double> (bound.Left, bound.Right));
                }

                double xEnd = double.MinValue;
                if (isLastLineOfSelection)
                {
                    if (end.IsInVirtualSpace)
                    {
                        xEnd = SkiaTextCaret.GetXCoordinateFromVirtualBufferPosition(line, end);
                    }
                }
                else if (isVirtualSpaceEnabled)
                {
                    xEnd = double.MaxValue;
                }

                double xStart = line.TextRight;
                if (xEnd > xStart)
                {
                    if ((leftRightPairs.Count > 0) && (leftRightPairs [leftRightPairs.Count - 1].Item2 >= xStart))
                    {
                        xStart = leftRightPairs [leftRightPairs.Count - 1].Item1;
                        leftRightPairs.RemoveAt(leftRightPairs.Count - 1);
                    }

                    leftRightPairs.Add(new Tuple <double, double> (xStart, xEnd));
                }
            }

            return(leftRightPairs);
        }