Example #1
0
 /// <summary>
 /// Get the SnapshotSpan for the ITextViewLineCollection.  This can throw when the ITextView is being
 /// laid out so we wrap the try / catch here
 /// </summary>
 public static Result <SnapshotSpan> GetFormattedSpan(this ITextViewLineCollection collection)
 {
     try
     {
         return(collection.FormattedSpan);
     }
     catch (Exception ex)
     {
         return(Result.CreateError(ex));
     }
 }
        /// <summary>
        /// See <see cref="ITextView2.TryGetTextViewLines(out ITextViewLineCollection)"/>.
        /// </summary>
        public static bool TryGetTextViewLines(this ITextView textView, out ITextViewLineCollection textViewLines)
        {
            if (textView == null)
            {
                throw new ArgumentNullException(nameof(textView));
            }

            if (textView is ITextView2 textView2)
            {
                return(textView2.TryGetTextViewLines(out textViewLines));
            }
            else
            {
                textViewLines = null;
                return(false);
            }
        }
Example #3
0
        public override void PreprocessMouseMove(MouseEventArgs e)
        {
            ITextViewLineCollection textViewLines = _view.TextViewLines;

            if (textViewLines != null)
            {
                Point position = e.GetPosition(this._view.VisualElement);
                position.X += this._view.ViewportLeft;
                position.Y += this._view.ViewportTop;
                ITextViewLine textViewLineContainingYCoordinate = textViewLines.GetTextViewLineContainingYCoordinate(position.Y);
                if (textViewLineContainingYCoordinate != null)
                {
                    MousePosition = textViewLineContainingYCoordinate.Start.Position;
                }
            }

            base.PreprocessMouseMove(e);
        }
        /////////////////////////////////////////////////////////////////////////////////////////////////////
        // PUBLIC PROCEDURES
        /////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Draws the margin and its content.
        /// </summary>
        /// <param name="context">The <see cref="TextViewDrawContext"/> to use for rendering.</param>
        public void Draw(TextViewDrawContext context)
        {
            Rect marginBounds = context.Bounds;

            // Loop through all the view lines
            ITextViewLineCollection visibleLines = view.VisibleViewLines;

            foreach (ITextViewLine viewLine in visibleLines)
            {
                // Get bounds relative to this element
                Rect bounds = view.TransformFromTextArea(viewLine.Bounds);

                // Get the number of characters on the line
                string characterCount = viewLine.CharacterCount.ToString(CultureInfo.CurrentCulture) + " chars";

                // Get the foreground
                var foreground = Colors.Black;
                if (viewLine.CharacterCount > 60)
                {
                    foreground = Colors.Red;
                }
                else if (viewLine.CharacterCount > 40)
                {
                    foreground = Colors.DarkGoldenrod;
                }
                else if (viewLine.CharacterCount > 20)
                {
                    foreground = Colors.DarkGreen;
                }

                // Get the line layout
                var firstLayoutLine = context.Canvas.CreateTextLayout(characterCount, 0, this.FontFamily.Source, (float)this.FontSize, foreground).Lines[0];

                // Get x/y
                double x = marginBounds.Right - firstLayoutLine.Width - this.Padding.Right;
                double y = marginBounds.Y + viewLine.TextBounds.Y + (int)Math.Round(viewLine.Baseline - firstLayoutLine.Baseline, MidpointRounding.AwayFromZero);

                // Draw the text
                context.DrawText(new Point(x, y), firstLayoutLine);
            }
        }
        public static bool TryGetClosestTextViewLine(this ITextView textView, double yCoordinate, out ITextViewLine closestLine)
        {
            if (textView == null)
            {
                throw new ArgumentNullException(nameof(textView));
            }

            if (textView.IsClosed || textView.InLayout)
            {
                closestLine = null;
                return(false);
            }

            ITextViewLine textLine = null;

            ITextViewLineCollection textLines = textView.TextViewLines;

            if (textLines != null && textLines.Count > 0)
            {
                textLine = textLines.GetTextViewLineContainingYCoordinate(yCoordinate);

                if (textLine == null)
                {
                    if (yCoordinate <= textLines.FirstVisibleLine.Bottom)
                    {
                        textLine = textLines.FirstVisibleLine;
                    }
                    else if (yCoordinate >= textLines.LastVisibleLine.Top)
                    {
                        textLine = textLines.LastVisibleLine;
                    }
                }

                closestLine = textLine;
                return(true);
            }

            closestLine = null;
            return(false);
        }
Example #6
0
 public bool TryGetTextViewLines(out ITextViewLineCollection textViewLines) =>
 _innerTextView.TryGetTextViewLines(out textViewLines);
Example #7
0
        private void renderColumnsForLines(GeometryGroup geometry, List <int> columns, ITextViewLineCollection lines)
        {
            double top = 0.0, bottom = _view.ViewportHeight;
            int    lineindex          = 0;
            bool   resetTopAtNextLine = true;

            int leftmostcolumn  = getFirstColumn();
            int rightmostcolumn = getLastColumn();

            foreach (var line in lines)
            {
                // Create new columns starting from this line
                if (resetTopAtNextLine)
                {
                    top = line.Top - _view.ViewportTop;
                }

                bottom = line.Bottom - _view.ViewportTop;

                // If next line is not starting at a different column than this
                // one we need to draw this line immediately, and disregard
                // the current line's top for when drawing the next lines.
                resetTopAtNextLine = (!line.IsLastTextViewLineForSnapshotLine ||
                                      !line.IsFirstTextViewLineForSnapshotLine);

                // We need to draw the current columns before next line
                if (resetTopAtNextLine)
                {
                    renderColumns(geometry, columns, top, bottom,
                                  _linesOffset[lineindex],
                                  leftmostcolumn,
                                  rightmostcolumn);
                }

                lineindex++;
            }

            if (!resetTopAtNextLine && ((lineindex - 1) < _linesOffset.Count))
            {
                renderColumns(geometry, columns, top, bottom,
                              _linesOffset[lineindex - 1],
                              leftmostcolumn,
                              rightmostcolumn);
            }
        }
        public override void PreprocessMouseMove(System.Windows.Input.MouseEventArgs e)
        {
            ITextViewLineCollection textLines = this.view.TextViewLines;

            if ((textLines != null) && (this.visibleBlocks.Count > 0))
            {
                ITextViewLine firstVisible = textLines.FirstVisibleLine;

                int screenTop = (firstVisible.VisibilityState == VisibilityState.FullyVisible)
                                ? firstVisible.Start
                                : firstVisible.EndIncludingLineBreak;
                Point pt = e.GetPosition(this.view.VisualElement);
                pt.X += this.view.ViewportLeft;
                pt.Y += this.view.ViewportTop;

                foreach (VisibleBlock block in this.visibleBlocks)
                {
                    if ((Math.Abs(pt.X - block.x) < 4.0) &&
                        (pt.Y >= block.yTop) && (pt.Y <= block.yBottom))
                    {
                        SnapshotPoint?statementStart = this.view.BufferGraph.MapUpToSnapshot(block.tag.StatementStart, PointTrackingMode.Positive, PositionAffinity.Successor, this.view.TextSnapshot);
                        if (statementStart.HasValue && (statementStart.Value < screenTop))
                        {
                            if (this.tipWindow == null)
                            {
                                this.tipWindow = new ToolTip();

                                this.tipWindow.ClipToBounds = true;

                                this.tipWindow.Placement                  = PlacementMode.Top;
                                this.tipWindow.PlacementTarget            = this.view.VisualElement;
                                this.tipWindow.HorizontalAlignment        = HorizontalAlignment.Left;
                                this.tipWindow.HorizontalContentAlignment = HorizontalAlignment.Left;

                                this.tipWindow.VerticalAlignment        = VerticalAlignment.Top;
                                this.tipWindow.VerticalContentAlignment = VerticalAlignment.Top;
                            }

                            this.tipWindow.PlacementRectangle = new Rect(block.x, 0.0, 0.0, 0.0);

                            this.tipWindow.IsOpen = true;
                            FrameworkElement context = block.tag.Context(this.blockColoring,
                                                                         this.view.FormattedLineSource.DefaultTextProperties.Typeface,
                                                                         this.view.FormattedLineSource.DefaultTextProperties.FontRenderingEmSize);

                            //The width of the view is in zoomed coordinates so factor the zoom factor into the tip window width computation.
                            double zoom = this.view.ZoomLevel / 100.0;
                            this.tipWindow.MaxWidth  = Math.Max(100.0, this.view.ViewportWidth * zoom * 0.5);
                            this.tipWindow.MinHeight = this.tipWindow.MaxHeight = context.Height + 12.0;

                            this.tipWindow.Content = context;

                            return;
                        }
                    }
                }
            }

            if (this.tipWindow != null)
            {
                this.tipWindow.IsOpen = false;
                this.tipWindow        = null;
            }
        }
        /// <summary>
        /// See <see cref="ITextView2.TryGetTextViewLineContainingBufferPosition(SnapshotPoint, out Formatting.ITextViewLine)"/>.
        /// </summary>
        public static bool TryGetTextViewLineContainingBufferPosition(this ITextView textView, SnapshotPoint bufferPosition, out ITextViewLineCollection textViewLines)
        {
            if (textView == null)
            {
                throw new ArgumentNullException(nameof(textView));
            }

            if (textView is ITextView2 textView2)
            {
                return(textView2.TryGetTextViewLineContainingBufferPosition(bufferPosition, out textViewLines));
            }
            else
            {
                textViewLines = null;
                return(false);
            }
        }
Example #10
0
        public override void PreprocessMouseMove(System.Windows.Input.MouseEventArgs e)
        {
            ITextViewLineCollection textLines = _view.TextViewLines;

            if ((textLines != null) && (_visibleBlocks.Count > 0))
            {
                ITextViewLine firstVisible = textLines.FirstVisibleLine;

                Point pt = e.GetPosition(_view.VisualElement);
                pt.X += _view.ViewportLeft;
                pt.Y += _view.ViewportTop;

                //Horrible hack for peek: prevent the tip from showing if the y coordinate is in the space below the bottom of a line's text
                //(which is where the peek adornment would be displayed).
                var line = textLines.GetTextViewLineContainingYCoordinate(pt.Y);
                if ((line != null) && (pt.Y <= line.TextBottom + 1.0))
                {
                    int screenTop = (firstVisible.VisibilityState == VisibilityState.FullyVisible)
                                    ? firstVisible.Start
                                    : firstVisible.EndIncludingLineBreak;

                    foreach (VisibleBlock block in _visibleBlocks)
                    {
                        if ((Math.Abs(pt.X - block.x) < 4.0) &&
                            (pt.Y >= block.yTop) && (pt.Y <= block.yBottom))
                        {
                            SnapshotPoint?statementStart = _view.BufferGraph.MapUpToSnapshot(block.tag.StatementStart, PointTrackingMode.Positive, PositionAffinity.Successor, _view.TextSnapshot);
                            if (statementStart.HasValue && (statementStart.Value < screenTop))
                            {
                                if (_tipWindow == null)
                                {
                                    _tipWindow = new ToolTip();

                                    _tipWindow.ClipToBounds = true;

                                    _tipWindow.Placement                  = PlacementMode.Top;
                                    _tipWindow.PlacementTarget            = _view.VisualElement;
                                    _tipWindow.HorizontalAlignment        = HorizontalAlignment.Left;
                                    _tipWindow.HorizontalContentAlignment = HorizontalAlignment.Left;

                                    _tipWindow.VerticalAlignment        = VerticalAlignment.Top;
                                    _tipWindow.VerticalContentAlignment = VerticalAlignment.Top;
                                }

                                _tipWindow.PlacementRectangle = new Rect(block.x, 0.0, 0.0, 0.0);

                                if (_tipWindow.IsOpen)
                                {
                                    var existingContext = _tipWindow.Content as FrameworkElement;
                                    if ((existingContext != null) && (existingContext.Tag == block.tag))
                                    {
                                        // No changes from the last time we opened the tip.
                                        return;
                                    }
                                }

                                FrameworkElement context = block.tag.Context(_coloring,
                                                                             _view.FormattedLineSource.DefaultTextProperties);
                                context.Tag = block.tag;

                                //The width of the view is in zoomed coordinates so factor the zoom factor into the tip window width computation.
                                double zoom = _view.ZoomLevel / 100.0;
                                _tipWindow.MaxWidth  = Math.Max(100.0, _view.ViewportWidth * zoom * 0.5);
                                _tipWindow.MinHeight = _tipWindow.MaxHeight = context.Height + 12.0;

                                var rd = _formatMap.GetProperties("TextView Background");
                                if (rd.Contains(EditorFormatDefinition.BackgroundBrushId))
                                {
                                    _tipWindow.Background = rd[EditorFormatDefinition.BackgroundBrushId] as Brush;
                                }

                                _tipWindow.Content = context;
                                _tipWindow.IsOpen  = true;

                                StructureMarginElement.LogTipOpened("VS/PPT-Structure/AdornmentTipOpened", context);

                                return;
                            }
                        }
                    }
                }
            }

            this.CloseTip();
        }
Example #11
0
        private void renderColumnsForLines(GeometryGroup geometry, List<int> columns, ITextViewLineCollection lines)
        {
            double top = 0.0, bottom = _view.ViewportHeight;
            int lineindex = 0;
            bool resetTopAtNextLine = true;

            int leftmostcolumn = getFirstColumn();
            int rightmostcolumn = getLastColumn();

            foreach (var line in lines)
            {
                // Create new columns starting from this line
                if (resetTopAtNextLine)
                {
                    top = line.Top - _view.ViewportTop;
                }

                bottom = line.Bottom - _view.ViewportTop;

                // If next line is not starting at a different column than this
                // one we need to draw this line immediately, and disregard
                // the current line's top for when drawing the next lines.
                resetTopAtNextLine = (!line.IsLastTextViewLineForSnapshotLine
                    || !line.IsFirstTextViewLineForSnapshotLine);

                // We need to draw the current columns before next line
                if (resetTopAtNextLine)
                {
                    renderColumns(geometry, columns, top, bottom,
                        _linesOffset[lineindex],
                        leftmostcolumn,
                        rightmostcolumn);
                }

                lineindex++;
            }

            if (!resetTopAtNextLine && ((lineindex - 1) < _linesOffset.Count))
            {
                renderColumns(geometry, columns, top, bottom,
                    _linesOffset[lineindex - 1],
                    leftmostcolumn,
                    rightmostcolumn);
            }
        }
Example #12
0
        public static bool MarkerGeometrySpansMultipleLines(ITextViewLineCollection collection, SnapshotSpan bufferSpan)
        {
            ITextViewLine start = collection.GetTextViewLineContainingBufferPosition(bufferSpan.Start);

            return(start == null || bufferSpan.End > start.EndIncludingLineBreak);
        }