Example #1
0
 public SnapshotSpan GetTextElementSpan(SnapshotPoint position) => TextViewLines.GetTextElementSpan(position);
        internal void HandleMouseMove(Point pt)
        {
            if (_mouseHoverEvents.Count > 0)
            {
                int?newPosition = null;

                if ((pt.X >= 0.0) && (pt.X < this.ViewportWidth) &&
                    (pt.Y >= 0.0) && (pt.Y < this.ViewportHeight))
                {
                    double y = pt.Y + this.ViewportTop;

                    var line = TextViewLines.GetTextViewLineContainingYCoordinate(y);
                    if ((line != null) && (y >= line.TextTop) && (y <= line.TextBottom))
                    {
                        double x = pt.X + this.ViewportLeft;
                        newPosition = line.GetBufferPositionFromXCoordinate(x, true);
                        if ((!newPosition.HasValue) && (line.LineBreakLength == 0) && line.IsLastTextViewLineForSnapshotLine)
                        {
                            //For purposes of hover events, pretend the last line in the buffer
                            //actually is padded by the EndOfLineWidth (even though it is not).
                            if ((line.TextRight <= x) && (x < line.TextRight + line.EndOfLineWidth))
                            {
                                newPosition = line.End;
                            }
                        }
                    }
                }

                if (newPosition != _lastHoverPosition)
                {
                    _lastHoverPosition = newPosition;

                    //The mouse moved to a different character, reset the timer.
                    _mouseHoverTimer.Stop();

                    //If the mouse is over a character, reset the events & restart the timer.
                    if (newPosition.HasValue)
                    {
                        int delay = int.MaxValue;
                        lock (_mouseHoverEvents) {
                            foreach (var eventData in _mouseHoverEvents)
                            {
                                eventData.Fired = false;
                                if (eventData.Attribute.Delay < delay)
                                {
                                    delay = eventData.Attribute.Delay;
                                }
                            }
                        }

                        //In theory the last event could have been removed on a background thread after we checked the count.
                        if (delay != int.MaxValue)
                        {
                            _millisecondsSinceMouseMove = 0;
                            _mouseHoverTimer.Interval   = Math.Max(50, delay);
                            _mouseHoverTimer.Start();
                        }
                    }
                }
            }
        }