protected override void Dispose(bool disposing) { if (disposing) { _differenceViewerPreview?.Dispose(); _differenceViewerPreview = null; } base.Dispose(disposing); }
public PreviewPane(NSImage severityIcon, string id, string title, string description, Uri helpLink, string helpLinkToolTipText, IReadOnlyList <object> previewContent, bool logIdVerbatimInTelemetry, Guid?optionPageGuid = null) { _differenceViewerPreview = (DifferenceViewerPreview)previewContent[0]; var view = ((ICocoaDifferenceViewer)_differenceViewerPreview.Viewer).VisualElement; var originalSize = view.Frame.Size; this.TranslatesAutoresizingMaskIntoConstraints = false; // === Title === // Title is in a stack view to help with padding var titlePlaceholder = new NSStackView() { Orientation = NSUserInterfaceLayoutOrientation.Vertical, EdgeInsets = new NSEdgeInsets(5, 0, 5, 0), Alignment = NSLayoutAttribute.Leading, TranslatesAutoresizingMaskIntoConstraints = false }; // TODO: missing icon this.titleField = new NSTextField() { Editable = false, Bordered = false, BackgroundColor = NSColor.ControlBackground, DrawsBackground = false, }; titlePlaceholder.AddArrangedSubview(titleField); AddSubview(titlePlaceholder); // === Preview View === // This is the actual view, that shows the diff view.TranslatesAutoresizingMaskIntoConstraints = false; NSLayoutConstraint.Create(view, NSLayoutAttribute.Width, NSLayoutRelation.GreaterThanOrEqual, 1, originalSize.Width).Active = true; NSLayoutConstraint.Create(view, NSLayoutAttribute.Height, NSLayoutRelation.GreaterThanOrEqual, 1, originalSize.Height).Active = true; view.Subviews[0].TranslatesAutoresizingMaskIntoConstraints = false; view.WantsLayer = true; AddSubview(view); // === Constraints === var constraints = new NSLayoutConstraint[] { // Title NSLayoutConstraint.Create(titlePlaceholder, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this, NSLayoutAttribute.Top, 1, 0), NSLayoutConstraint.Create(titlePlaceholder, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this, NSLayoutAttribute.Leading, 1, 0), NSLayoutConstraint.Create(titlePlaceholder, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, this, NSLayoutAttribute.Trailing, 1, 0), // Preview View NSLayoutConstraint.Create(view, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, this, NSLayoutAttribute.Bottom, 1, 0), NSLayoutConstraint.Create(view, NSLayoutAttribute.Leading, NSLayoutRelation.Equal, this, NSLayoutAttribute.Leading, 1, 0), NSLayoutConstraint.Create(view, NSLayoutAttribute.Trailing, NSLayoutRelation.Equal, this, NSLayoutAttribute.Trailing, 1, 0), // subviews NSLayoutConstraint.Create(view.Subviews[0], NSLayoutAttribute.Top, NSLayoutRelation.Equal, view, NSLayoutAttribute.Top, 1, 0), NSLayoutConstraint.Create(view.Subviews[0], NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, view, NSLayoutAttribute.Bottom, 1, 0), NSLayoutConstraint.Create(view.Subviews[0], NSLayoutAttribute.Left, NSLayoutRelation.Equal, view, NSLayoutAttribute.Left, 1, 0), NSLayoutConstraint.Create(view.Subviews[0], NSLayoutAttribute.Right, NSLayoutRelation.Equal, view, NSLayoutAttribute.Right, 1, 0), }; if (GenerateAttributeString(id, title, helpLink, helpLinkToolTipText) is NSAttributedString attributedStringTitle) { this.titleField.AttributedStringValue = attributedStringTitle; // We do this separately, because the title sometimes isn't there (i.e. no diagnostics ID) // and we want the preview to stretch to the top NSLayoutConstraint.Create(view, NSLayoutAttribute.Top, NSLayoutRelation.Equal, titlePlaceholder, NSLayoutAttribute.Bottom, 1, 0).Active = true; } else { NSLayoutConstraint.Create(view, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this, NSLayoutAttribute.Top, 1, 0).Active = true; } NSLayoutConstraint.ActivateConstraints(constraints); _differenceViewerPreview.Viewer.InlineView.TryMoveCaretToAndEnsureVisible( new Microsoft.VisualStudio.Text.SnapshotPoint(_differenceViewerPreview.Viewer.InlineView.TextSnapshot, 0)); }
void IDisposable.Dispose() { // VS editor will call Dispose at which point we should Close() the embedded IWpfDifferenceViewer. _differenceViewerPreview?.Dispose(); _differenceViewerPreview = null; }
private FrameworkElement GetPreviewElement(object previewItem) { if (previewItem is DifferenceViewerPreview) { // Contract is there should be only 1 diff viewer, otherwise we leak. Contract.ThrowIfFalse(_differenceViewerPreview == null); // cache the diff viewer so that we can close it when panel goes away. // this is a bit wierd since we are mutating state here. _differenceViewerPreview = (DifferenceViewerPreview)previewItem; PreviewDockPanel.Background = _differenceViewerPreview.Viewer.InlineView.Background; var previewElement = _differenceViewerPreview.Viewer.VisualElement; return previewElement; } if (previewItem is string) { return GetPreviewForString((string)previewItem); } if (previewItem is FrameworkElement) { return (FrameworkElement)previewItem; } // preview item we don't know how to show to users return null; }