///////////////////////////////////////////////////////////////////////////////////////////////////// // NON-PUBLIC PROCEDURES ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Examines the cached elements, prunes ones that no longer have valid tags, and returns a match if found. /// </summary> /// <param name="tag">The target tag for which to search.</param> /// <returns>A cached element, if found.</returns> private AdornmentElement GetCachedElement(object tag) { AdornmentElement targetElement = null; if (tag != null) { for (var index = cachedElements.Count - 1; index >= 0; index--) { var tagRef = cachedElements[index].Item1; if (tagRef.IsAlive) { // If there is a tag match, use the cached element and remove the entry if (tagRef.Target == tag) { targetElement = cachedElements[index].Item2; cachedElements.RemoveAt(index); } } else { // Remove the entry cachedElements.RemoveAt(index); } } } return(targetElement); }
///////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC PROCEDURES ///////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Adds an adornment to the <see cref="AdornmentLayer"/>. /// </summary> /// <param name="viewLine">The current <see cref="ITextViewLine"/> being examined.</param> /// <param name="tagRange">The <see cref="ITag"/> and the range it covers.</param> protected override void AddAdornment(ITextViewLine viewLine, TagSnapshotRange <IntraLineViewportTag> tagRange) { // Determine the bounds var bounds = this.GetAdornmentBounds(tagRange.Tag); var charBounds = viewLine.GetCharacterBounds(tagRange.SnapshotRange.StartOffset); bounds.Y = charBounds.Bottom; // See if a cached version of the element for the tag is available var element = this.GetCachedElement(tagRange.Tag); if (element == null) { // Create the element element = new AdornmentElement(); } // Update the size element.Width = bounds.Width; element.Height = bounds.Height; element.Tag = tagRange.Tag; // Add the adornment this.AdornmentLayer.AddAdornment(AdornmentChangeReason.Other, element, bounds.Location, tagRange.Tag.Key, OnAdornmentRemoved); }