bool AddAdornment(AdornmentTagInfo adornmentInfo, HexViewLine line) { SizeChangedEventHandler sizeChanged = (a, e) => { var bounds = line.GetAdornmentBounds(adornmentInfo); if (bounds == null) { return; } // Sometimes the size just gets changed very little, eg. from 400 to 399.95..... const double d = 0.5; if (e.NewSize.Height <= bounds.Value.Height + d && e.NewSize.Width <= bounds.Value.Width + d) { return; } tagger?.RefreshSpans(new HexBufferSpanEventArgs(adornmentInfo.BufferSpan)); }; adornmentInfo.TopUIElement.SizeChanged += sizeChanged; VSTE.AdornmentRemovedCallback removedCallback = (a, b) => { adornmentTagInfos.Remove(adornmentInfo); adornmentInfo.TopUIElement.SizeChanged -= sizeChanged; adornmentInfo.TopUIElement.OnRemoved(); if (adornmentInfo.HexTagSpan != null) { adornmentInfo.HexTagSpan.Tag.RemovalCallback?.Invoke(adornmentInfo.HexTagSpan, b); } else { adornmentInfo.HexTextTagSpan.Tag.RemovalCallback?.Invoke(adornmentInfo.HexTextTagSpan, b); } }; Debug.Assert(!adornmentTagInfos.Contains(adornmentInfo)); adornmentTagInfos.Add(adornmentInfo); // Use OwnerControlled because there are corner cases that the adornment layer can't handle, // eg. an adornment with buffer span length == 0 that is shown on its own line (word wrap). bool added = layer.AddAdornment(VSTE.AdornmentPositioningBehavior.OwnerControlled, (HexBufferSpan?)null, adornmentInfo, adornmentInfo.TopUIElement, removedCallback); if (!added) { removedCallback(null, adornmentInfo.TopUIElement); } return(added); }
bool AddAdornment(AdornmentTagInfo adornmentInfo) { var oldSize = adornmentInfo.TopUIElement.DesiredSize; SizeChangedEventHandler sizeChanged = (a, e) => { if (e.NewSize == oldSize) { return; } // Sometimes the size just gets changed very little, eg. from 400 to 399.95..... const double d = 0.5; if (Math.Abs(e.NewSize.Height - oldSize.Height) < d && Math.Abs(e.NewSize.Width - oldSize.Width) < d) { return; } oldSize = e.NewSize; tagger?.RefreshSpans(new SnapshotSpanEventArgs(adornmentInfo.Span)); }; adornmentInfo.TopUIElement.SizeChanged += sizeChanged; AdornmentRemovedCallback removedCallback = (a, b) => { adornmentTagInfos.Remove(adornmentInfo); adornmentInfo.TopUIElement.SizeChanged -= sizeChanged; adornmentInfo.TopUIElement.OnRemoved(); adornmentInfo.TagSpan.Tag.RemovalCallback?.Invoke(adornmentInfo.TagSpan, b); }; Debug.Assert(!adornmentTagInfos.Contains(adornmentInfo)); adornmentTagInfos.Add(adornmentInfo); // Use OwnerControlled because there are corner cases that the adornment layer can't handle, // eg. an adornment with buffer span length == 0 that is shown on its own line (word wrap). bool added = layer.AddAdornment(AdornmentPositioningBehavior.OwnerControlled, null, adornmentInfo, adornmentInfo.TopUIElement, removedCallback); if (!added) { removedCallback(null, adornmentInfo.TopUIElement); } return(added); }