File: VenusMargin\VenusMargin.cs
Web Access
Project: src\src\VisualStudio\VisualStudioDiagnosticsToolWindow\Roslyn.VisualStudio.DiagnosticsWindow.csproj (Roslyn.VisualStudio.DiagnosticsWindow)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Projection;
 
namespace Roslyn.Hosting.Diagnostics.VenusMargin
{
    internal class VenusMargin : IWpfTextViewMargin
    {
        public const string MarginName = "VenusMargin";
 
        private readonly IProjectionBuffer _projectionBuffer;
        private readonly ProjectionBufferViewModel _viewModel = new ProjectionBufferViewModel();
        private readonly ProjectionBufferMargin _control;
 
        private bool _isDisposed = false;
 
        public VenusMargin(IWpfTextView textView, ITextEditorFactoryService textEditorFactory)
        {
            _projectionBuffer = (IProjectionBuffer)textView.TextBuffer;
 
            _control = new ProjectionBufferMargin
            {
                DataContext = _viewModel,
                TextEditorFactory = textEditorFactory,
                TextView = textView,
            };
 
            _projectionBuffer.Changed += OnProjectionBufferChanged;
            _projectionBuffer.SourceSpansChanged += this.OnProjectionBufferSourceSpansChanged;
            _projectionBuffer.SourceBuffersChanged += OnProjectionBufferSourceBuffersChanged;
 
            foreach (var b in _projectionBuffer.SourceBuffers)
            {
                _viewModel.SourceBuffers.Add(b);
            }
        }
 
        private void OnProjectionBufferSourceBuffersChanged(object sender, ProjectionSourceBuffersChangedEventArgs e)
        {
            foreach (var b in e.RemovedBuffers)
            {
                _viewModel.SourceBuffers.Remove(b);
            }
 
            foreach (var b in e.AddedBuffers)
            {
                _viewModel.SourceBuffers.Add(b);
            }
 
            UpdateSourceSpans();
        }
 
        private void OnProjectionBufferSourceSpansChanged(object sender, ProjectionSourceSpansChangedEventArgs e)
        {
            UpdateSourceSpans();
        }
 
        private void OnProjectionBufferChanged(object sender, TextContentChangedEventArgs e)
        {
            UpdateSourceSpans();
        }
 
        private void UpdateSourceSpans()
        {
            _viewModel.SourceSpans.Clear();
            foreach (var ss in _projectionBuffer.CurrentSnapshot.GetSourceSpans())
            {
                _viewModel.SourceSpans.Add(ss);
            }
 
            _viewModel.SourceSpans.Add(new SnapshotSpan(_projectionBuffer.CurrentSnapshot, 0, 0));
        }
 
        private void ThrowIfDisposed()
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException(MarginName);
            }
        }
 
        public System.Windows.FrameworkElement VisualElement
        {
            get
            {
                ThrowIfDisposed();
                return _control;
            }
        }
 
        public double MarginSize
        {
            get
            {
                ThrowIfDisposed();
                return _control.ActualHeight;
            }
        }
 
        public bool Enabled
        {
            get
            {
                ThrowIfDisposed();
                return true;
            }
        }
 
        public ITextViewMargin GetTextViewMargin(string marginName)
        {
            return marginName == MarginName ? this : null;
        }
 
        public void Dispose()
        {
            if (!_isDisposed)
            {
                _isDisposed = true;
            }
        }
    }
}