public void SetPreviewButtonIcon(PreviewButtonIcon icon)
        {
            if (!previewIconVisible || icon == currentIcon)
            {
                return;
            }

            var name = ObjectValueTreeViewController.GetPreviewButtonIcon(icon);

            PreviewButton.Image = GetImage(name, Gtk.IconSize.Menu);
            currentIcon         = icon;

            SetNeedsDisplayInRect(PreviewButton.Frame);
        }
        Widget CreateExceptionValueTreeView()
        {
            if (useNewTreeView)
            {
                controller = new ObjectValueTreeViewController();
                controller.SetStackFrame(DebuggingService.CurrentFrame);
                controller.AllowExpanding = true;

                exceptionValueTreeView = controller.GetGtkControl(allowPopupMenu: false);
            }
            else
            {
                var objValueTreeView = new ObjectValueTreeView();
                objValueTreeView.Frame          = DebuggingService.CurrentFrame;
                objValueTreeView.AllowPopupMenu = false;
                objValueTreeView.AllowExpanding = true;
                objValueTreeView.AllowPinning   = false;
                objValueTreeView.AllowEditing   = false;
                objValueTreeView.AllowAdding    = false;

                exceptionValueTreeView = objValueTreeView;
            }

            exceptionValueTreeView.ModifyBase(StateType.Normal, Styles.ExceptionCaughtDialog.ValueTreeBackgroundColor.ToGdkColor());
            exceptionValueTreeView.ModifyBase(StateType.Active, Styles.ObjectValueTreeActiveBackgroundColor.ToGdkColor());
            exceptionValueTreeView.ModifyFont(Pango.FontDescription.FromString(Platform.IsWindows ? "9" : "11"));
            exceptionValueTreeView.RulesHint = false;
            exceptionValueTreeView.CanFocus  = true;
            exceptionValueTreeView.Show();

            var scrolled = new ScrolledWindow {
                HeightRequest    = 180,
                CanFocus         = true,
                HscrollbarPolicy = PolicyType.Automatic,
                VscrollbarPolicy = PolicyType.Automatic
            };

            scrolled.ShadowType = ShadowType.None;
            scrolled.Add(exceptionValueTreeView);
            scrolled.Show();

            var vbox = new VBox();

            expanderProperties = WrapInExpander(GettextCatalog.GetString("Properties"), scrolled);
            vbox.PackStart(new VBox(), false, false, 5);
            vbox.PackStart(expanderProperties, true, true, 0);
            vbox.ShowAll();

            return(vbox);
        }
Exemple #3
0
        public ObjectValuePad()
        {
            scrolled = new ScrolledWindow();
            scrolled.HscrollbarPolicy = PolicyType.Automatic;
            scrolled.VscrollbarPolicy = PolicyType.Automatic;

            if (UseNewTreeView)
            {
                controller = new ObjectValueTreeViewController();
                controller.AllowEditing = true;

                var treeView = controller.GetControl() as GtkObjectValueTreeView;
                fontChanger = new PadFontChanger(treeView, treeView.SetCustomFont, treeView.QueueResize);

                scrolled.Add(treeView);
            }
            else
            {
                tree = new ObjectValueTreeView();
                tree.AllowEditing = true;
                tree.AllowAdding  = false;

                fontChanger = new PadFontChanger(tree, tree.SetCustomFont, tree.QueueResize);

                scrolled.Add(tree);
            }

            scrolled.ShowAll();

            DebuggingService.CurrentFrameChanged      += OnFrameChanged;
            DebuggingService.PausedEvent              += OnDebuggerPaused;
            DebuggingService.ResumedEvent             += OnDebuggerResumed;
            DebuggingService.StoppedEvent             += OnDebuggerStopped;
            DebuggingService.EvaluationOptionsChanged += OnEvaluationOptionsChanged;
            DebuggingService.VariableChanged          += OnVariableChanged;

            needsUpdateValues = false;
            needsUpdateFrame  = true;

            //If pad is created/opened while debugging...
            initialResume = !DebuggingService.IsDebugging;
        }
Exemple #4
0
        public async Task <CompletionContext> GetCompletionContextAsync(IAsyncCompletionSession session, CompletionTrigger trigger, SnapshotPoint triggerLocation, SnapshotSpan applicableToSpan, CancellationToken token)
        {
            var text = triggerLocation.Snapshot.GetText(0, triggerLocation.Position);
            var data = await DebuggingService.GetCompletionDataAsync(DebuggingService.CurrentFrame, text, token);

            if (data == null)
            {
                return(new CompletionContext(ImmutableArray <CompletionItem> .Empty));
            }

            var builder = ImmutableArray.CreateBuilder <CompletionItem> (data.Items.Count);

            foreach (var item in data.Items)
            {
                var image = new ImageElement(ObjectValueTreeViewController.GetImageId(item.Flags));

                builder.Add(new CompletionItem(item.Name, this, image));
            }

            return(new CompletionContext(builder.MoveToImmutable()));
        }
        public void SetPreviewButtonIcon(PreviewButtonIcon icon)
        {
            // When a11y is in use, always show an icon.
            if (IdeServices.DesktopService.AccessibilityInUse && icon == PreviewButtonIcon.Hidden)
            {
                var selected = Superview is NSTableRowView rowView && rowView.Selected;

                icon = selected ? PreviewButtonIcon.Selected : PreviewButtonIcon.Hover;
            }

            if (!previewIconVisible || icon == currentIcon)
            {
                return;
            }

            var name = ObjectValueTreeViewController.GetPreviewButtonIcon(icon);

            PreviewButton.Image = GetImage(name, Gtk.IconSize.Menu);
            currentIcon         = icon;

            SetNeedsDisplayInRect(PreviewButton.Frame);
        }
        public MacDebuggerTooltipWindow(PinnedWatchLocation location, StackFrame frame, ObjectValue value, PinnedWatch watch)
        {
            Animates = false;
            Behavior = NSPopoverBehavior.Semitransient;

            controller = new ObjectValueTreeViewController();
            controller.SetStackFrame(frame);
            controller.AllowEditing        = true;
            controller.PinnedWatch         = watch;
            controller.PinnedWatchLocation = location;

            treeView = controller.GetMacControl(ObjectValueTreeViewFlags.TooltipFlags);
            treeView.UIElementName = "Tooltip";
            treeView.NodePinned   += OnPinStatusChanged;
            treeView.StartEditing += OnStartEditing;
            treeView.EndEditing   += OnEndEditing;
            controller.AddValue(value);

            scrollView = new NSScrollView {
                HasVerticalScroller = true,
                AutohidesScrollers  = true,
                DocumentView        = treeView,
                Frame = treeView.Frame
            };

            ContentViewController = new NSViewController {
                View = scrollView
            };

            widthConstraint        = scrollView.WidthAnchor.ConstraintEqualToConstant(treeView.Frame.Width);
            widthConstraint.Active = true;

            heightConstraint        = scrollView.HeightAnchor.ConstraintEqualToConstant(treeView.Frame.Height);
            heightConstraint.Active = true;

            treeView.Resized += OnTreeViewResized;
        }
        public MacObjectValueTreeView(
            IObjectValueDebuggerService debuggerService,
            ObjectValueTreeViewController controller,
            bool allowEditing,
            ObjectValueTreeViewFlags flags)
        {
            DebuggerService = debuggerService;
            Controller      = controller;

            this.rootPinVisible = (flags & ObjectValueTreeViewFlags.RootPinVisible) != 0;
            this.allowPopupMenu = (flags & ObjectValueTreeViewFlags.AllowPopupMenu) != 0;
            this.compactView    = (flags & ObjectValueTreeViewFlags.CompactView) != 0;
            this.allowEditing   = allowEditing;

            DataSource = dataSource = new MacObjectValueTreeViewDataSource(this, controller.Root, controller.AllowWatchExpressions);
            Delegate   = treeViewDelegate = new MacObjectValueTreeViewDelegate(this);
            ColumnAutoresizingStyle            = compactView ? NSTableViewColumnAutoresizingStyle.None : NSTableViewColumnAutoresizingStyle.Uniform;
            AllowsSelection                    = (flags & ObjectValueTreeViewFlags.AllowSelection) != 0;
            treeViewDelegate.SelectionChanged += OnSelectionChanged;
            UsesAlternatingRowBackgroundColors = true;
            FocusRingType            = NSFocusRingType.None;
            AllowsColumnResizing     = !compactView;
            AutoresizesOutlineColumn = false;
            SetCustomFont(null);

            var resizingMask = compactView ? NSTableColumnResizing.None : NSTableColumnResizing.UserResizingMask | NSTableColumnResizing.Autoresizing;

            nameColumn = new NSTableColumn("name")
            {
                Editable = controller.AllowWatchExpressions, MinWidth = MinimumNameColumnWidth, ResizingMask = resizingMask
            };
            nameColumn.Title = GettextCatalog.GetString("Name");
            nameColumn.Width = MinimumNameColumnWidth * 2;
            AddColumn(nameColumn);

            OutlineTableColumn = nameColumn;

            valueColumn = new NSTableColumn("value")
            {
                Editable = controller.AllowEditing, MinWidth = MinimumValueColumnWidth, ResizingMask = resizingMask
            };
            valueColumn.Title = GettextCatalog.GetString("Value");
            valueColumn.Width = MinimumValueColumnWidth * 2;
            if (compactView)
            {
                valueColumn.MaxWidth = 800;
            }
            AddColumn(valueColumn);

            if (!compactView)
            {
                typeColumn = new NSTableColumn("type")
                {
                    Editable = false, MinWidth = MinimumTypeColumnWidth, ResizingMask = resizingMask
                };
                typeColumn.Title = GettextCatalog.GetString("Type");
                typeColumn.Width = MinimumTypeColumnWidth * 2;
                AddColumn(typeColumn);
            }

            if ((flags & ObjectValueTreeViewFlags.AllowPinning) != 0)
            {
                pinColumn = new NSTableColumn("pin")
                {
                    Editable = false, ResizingMask = NSTableColumnResizing.None
                };
                pinColumn.MinWidth = pinColumn.MaxWidth = pinColumn.Width = MacDebuggerObjectPinView.MinWidth;
                AddColumn(pinColumn);
            }

            if ((flags & ObjectValueTreeViewFlags.HeadersVisible) != 0)
            {
                HeaderView.AlphaValue = 1.0f;
            }
            else
            {
                HeaderView = null;
            }

            PreviewWindowManager.WindowClosed += OnPreviewWindowClosed;

            // disable implicit animations
            WantsLayer    = true;
            Layer.Actions = new NSDictionary(
                "actions", NSNull.Null,
                "contents", NSNull.Null,
                "hidden", NSNull.Null,
                "onLayout", NSNull.Null,
                "onOrderIn", NSNull.Null,
                "onOrderOut", NSNull.Null,
                "position", NSNull.Null,
                "sublayers", NSNull.Null,
                "transform", NSNull.Null,
                "bounds", NSNull.Null);
        }
Exemple #8
0
        public ObjectValuePad(bool allowWatchExpressions = false)
        {
            if (UseNewTreeView)
            {
                controller = new ObjectValueTreeViewController(allowWatchExpressions);
                controller.AllowEditing = true;

                if (Platform.IsMac)
                {
                    LoggingService.LogInfo("Using MacObjectValueTreeView for {0}", allowWatchExpressions ? "Watch Pad" : "Locals Pad");
                    var treeView = controller.GetMacControl(ObjectValueTreeViewFlags.ObjectValuePadFlags);
                    _treeview = treeView;

                    fontChanger = new PadFontChanger(treeView, treeView.SetCustomFont, treeView.QueueResize);

                    var scrolled = new AppKit.NSScrollView {
                        DocumentView          = treeView,
                        AutohidesScrollers    = false,
                        HasVerticalScroller   = true,
                        HasHorizontalScroller = true,
                    };

                    // disable implicit animations
                    scrolled.WantsLayer    = true;
                    scrolled.Layer.Actions = new NSDictionary(
                        "actions", NSNull.Null,
                        "contents", NSNull.Null,
                        "hidden", NSNull.Null,
                        "onLayout", NSNull.Null,
                        "onOrderIn", NSNull.Null,
                        "onOrderOut", NSNull.Null,
                        "position", NSNull.Null,
                        "sublayers", NSNull.Null,
                        "transform", NSNull.Null,
                        "bounds", NSNull.Null);

                    var host = new GtkNSViewHost(scrolled);
                    host.ShowAll();

                    control = host;
                }
                else
                {
                    LoggingService.LogInfo("Using GtkObjectValueTreeView for {0}", allowWatchExpressions ? "Watch Pad" : "Locals Pad");
                    var treeView = controller.GetGtkControl(ObjectValueTreeViewFlags.ObjectValuePadFlags);
                    treeView.Show();

                    fontChanger = new PadFontChanger(treeView, treeView.SetCustomFont, treeView.QueueResize);

                    var scrolled = new ScrolledWindow {
                        HscrollbarPolicy = PolicyType.Automatic,
                        VscrollbarPolicy = PolicyType.Automatic
                    };
                    scrolled.Add(treeView);
                    scrolled.Show();

                    control = scrolled;
                }
            }
            else
            {
                LoggingService.LogInfo("Using old ObjectValueTreeView for {0}", allowWatchExpressions ? "Watch Pad" : "Locals Pad");
                tree              = new ObjectValueTreeView();
                tree.AllowAdding  = allowWatchExpressions;
                tree.AllowEditing = true;
                tree.Show();

                fontChanger = new PadFontChanger(tree, tree.SetCustomFont, tree.QueueResize);

                var scrolled = new ScrolledWindow {
                    HscrollbarPolicy = PolicyType.Automatic,
                    VscrollbarPolicy = PolicyType.Automatic
                };
                scrolled.Add(tree);
                scrolled.Show();

                control = scrolled;
            }

            DebuggingService.CurrentFrameChanged      += OnFrameChanged;
            DebuggingService.PausedEvent              += OnDebuggerPaused;
            DebuggingService.ResumedEvent             += OnDebuggerResumed;
            DebuggingService.StoppedEvent             += OnDebuggerStopped;
            DebuggingService.EvaluationOptionsChanged += OnEvaluationOptionsChanged;
            DebuggingService.VariableChanged          += OnVariableChanged;

            needsUpdateValues = false;
            needsUpdateFrame  = true;

            //If pad is created/opened while debugging...
            IsInitialResume = !DebuggingService.IsDebugging;
        }
        protected override void UpdateContents()
        {
            if (Node == null)
            {
                return;
            }

            foreach (var constraint in constraints)
            {
                constraint.Active = false;
                constraint.Dispose();
            }
            constraints.Clear();

            OptimalWidth = MarginSize;

            bool selected = Superview is NSTableRowView rowView && rowView.Selected;
            var  iconName = ObjectValueTreeViewController.GetIcon(Node.Flags);

            ImageView.Image = GetImage(iconName, Gtk.IconSize.Menu, selected);
            constraints.Add(ImageView.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
            constraints.Add(ImageView.LeadingAnchor.ConstraintEqualToAnchor(LeadingAnchor, MarginSize));
            constraints.Add(ImageView.WidthAnchor.ConstraintEqualToConstant(ImageSize));
            constraints.Add(ImageView.HeightAnchor.ConstraintEqualToConstant(ImageSize));

            OptimalWidth += ImageView.Image.Size.Width;
            OptimalWidth += RowCellSpacing;

            var editable    = TreeView.AllowWatchExpressions && Node.Parent is RootObjectValueNode;
            var textColor   = NSColor.ControlText;
            var placeholder = string.Empty;
            var name        = Node.Name;

            if (Node.IsUnknown)
            {
                if (TreeView.DebuggerService.Frame != null)
                {
                    textColor = NSColor.FromCGColor(GetCGColor(Styles.ObjectValueTreeValueDisabledText));
                }
            }
            else if (Node.IsError || Node.IsNotSupported)
            {
            }
            else if (Node.IsImplicitNotSupported)
            {
            }
            else if (Node.IsEvaluating)
            {
                if (Node.GetIsEvaluatingGroup())
                {
                    textColor = NSColor.FromCGColor(GetCGColor(Styles.ObjectValueTreeValueDisabledText));
                }
            }
            else if (Node.IsEnumerable)
            {
            }
            else if (Node is AddNewExpressionObjectValueNode)
            {
                placeholder = GettextCatalog.GetString("Add new expression");
                name        = string.Empty;
                editable    = true;
            }
            else if (TreeView.Controller.GetNodeHasChangedSinceLastCheckpoint(Node))
            {
                textColor = NSColor.FromCGColor(GetCGColor(Styles.ObjectValueTreeValueModifiedText));
            }

            TextField.PlaceholderAttributedString = GetAttributedPlaceholderString(placeholder);
            TextField.AttributedStringValue       = GetAttributedString(name);
            TextField.TextColor = textColor;
            TextField.Editable  = editable;
            UpdateFont(TextField);
            TextField.SizeToFit();

            OptimalWidth += TextField.Frame.Width;

            constraints.Add(TextField.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
            constraints.Add(TextField.LeadingAnchor.ConstraintEqualToAnchor(ImageView.TrailingAnchor, RowCellSpacing));

            if (MacObjectValueTreeView.ValidObjectForPreviewIcon(Node))
            {
                SetPreviewButtonIcon(PreviewButtonIcon.Hidden);

                if (!previewIconVisible)
                {
                    AddSubview(PreviewButton);
                    previewIconVisible = true;
                }

                constraints.Add(TextField.WidthAnchor.ConstraintGreaterThanOrEqualToConstant(TextField.Frame.Width));
                constraints.Add(PreviewButton.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
                constraints.Add(PreviewButton.LeadingAnchor.ConstraintEqualToAnchor(TextField.TrailingAnchor, RowCellSpacing));
                constraints.Add(PreviewButton.WidthAnchor.ConstraintEqualToConstant(ImageSize));
                constraints.Add(PreviewButton.HeightAnchor.ConstraintEqualToConstant(ImageSize));

                OptimalWidth += RowCellSpacing;
                OptimalWidth += PreviewButton.Frame.Width;
            }
            else
            {
                if (previewIconVisible)
                {
                    PreviewButton.RemoveFromSuperview();
                    previewIconVisible = false;
                }

                constraints.Add(TextField.TrailingAnchor.ConstraintEqualToAnchor(TrailingAnchor, -MarginSize));
            }

            foreach (var constraint in constraints)
            {
                constraint.Active = true;
            }

            OptimalWidth += MarginSize;
        }
Exemple #10
0
        Widget CreateExceptionValueTreeView()
        {
            Widget scrolledWidget = null;

            if (useNewTreeView)
            {
                controller = new ObjectValueTreeViewController();
                controller.SetStackFrame(DebuggingService.CurrentFrame);
                controller.AllowExpanding = true;

                if (Platform.IsMac)
                {
                    macExceptionValueTreeView = controller.GetMacControl(ObjectValueTreeViewFlags.ObjectValuePadFlags);
                    macExceptionValueTreeView.UIElementName = "ExceptionCaughtDialog";
                }
                else
                {
                    exceptionValueTreeView = controller.GetGtkControl(ObjectValueTreeViewFlags.ExceptionCaughtFlags);
                }
            }
            else
            {
                var objValueTreeView = new ObjectValueTreeView();
                objValueTreeView.Frame          = DebuggingService.CurrentFrame;
                objValueTreeView.AllowPopupMenu = false;
                objValueTreeView.AllowExpanding = true;
                objValueTreeView.AllowPinning   = false;
                objValueTreeView.AllowEditing   = false;
                objValueTreeView.AllowAdding    = false;

                exceptionValueTreeView = objValueTreeView;
            }

            if (useNewTreeView && Platform.IsMac)
            {
                var scrolled = new AppKit.NSScrollView {
                    DocumentView          = macExceptionValueTreeView,
                    AutohidesScrollers    = true,
                    HasVerticalScroller   = true,
                    HasHorizontalScroller = true,
                };

                // disable implicit animations
                scrolled.WantsLayer    = true;
                scrolled.Layer.Actions = new NSDictionary(
                    "actions", NSNull.Null,
                    "contents", NSNull.Null,
                    "hidden", NSNull.Null,
                    "onLayout", NSNull.Null,
                    "onOrderIn", NSNull.Null,
                    "onOrderOut", NSNull.Null,
                    "position", NSNull.Null,
                    "sublayers", NSNull.Null,
                    "transform", NSNull.Null,
                    "bounds", NSNull.Null);

                var host = new GtkNSViewHost(scrolled);
                host.ShowAll();
                scrolledWidget = host;
            }
            else
            {
                exceptionValueTreeView.ModifyBase(StateType.Normal, Styles.ExceptionCaughtDialog.ValueTreeBackgroundColor.ToGdkColor());
                exceptionValueTreeView.ModifyBase(StateType.Active, Styles.ObjectValueTreeActiveBackgroundColor.ToGdkColor());
                exceptionValueTreeView.ModifyFont(Pango.FontDescription.FromString(Platform.IsWindows ? "9" : "11"));
                exceptionValueTreeView.RulesHint = false;
                exceptionValueTreeView.CanFocus  = true;
                exceptionValueTreeView.Show();

                var scrolled = new ScrolledWindow {
                    CanFocus         = true,
                    HscrollbarPolicy = PolicyType.Automatic,
                    VscrollbarPolicy = PolicyType.Automatic
                };

                scrolled.ShadowType = ShadowType.None;
                scrolled.Add(exceptionValueTreeView);
                scrolled.Show();
                scrolledWidget = scrolled;
            }

            var label = new Label();

            label.Markup = "<b>" + GettextCatalog.GetString("Properties") + "</b>";
            label.Xalign = 0;
            label.Xpad   = 10;

            if (exceptionValueTreeView != null)
            {
                exceptionValueTreeView.SetCommonAccessibilityAttributes("ExceptionCaughtDialog.ExceptionValueTreeView", label, null);
            }
            else
            {
                macExceptionValueTreeView.AccessibilityTitle = new NSString(label.Text);
            }

            var vbox = new VBox();

            vbox.PackStart(label, false, false, 12);
            vbox.PackStart(scrolledWidget, true, true, 0);
            vbox.ShowAll();

            return(vbox);
        }
Exemple #11
0
        public DebugValueWindow(Gtk.Window transientFor, PinnedWatchLocation location, StackFrame frame, ObjectValue value, PinnedWatch watch) : base(Gtk.WindowType.Toplevel)
        {
            TypeHint    = WindowTypeHint.PopupMenu;
            AllowShrink = false;
            AllowGrow   = false;
            Decorated   = false;

            TransientFor = transientFor;
            // Avoid getting the focus when the window is shown. We'll get it when the mouse enters the window
            AcceptFocus = false;

            sw = new ScrolledWindow {
                HscrollbarPolicy = PolicyType.Never,
                VscrollbarPolicy = PolicyType.Never
            };

            UpdateTreeStyle(Theme.BackgroundColor);

            if (useNewTreeView)
            {
                controller = new ObjectValueTreeViewController();
                controller.SetStackFrame(frame);
                controller.AllowEditing        = true;
                controller.PinnedWatch         = watch;
                controller.PinnedWatchLocation = location;

                treeView = controller.GetGtkControl(headersVisible: false, allowPinning: true, compactView: true, rootPinVisible: true);

                if (treeView is IObjectValueTreeView ovtv)
                {
                    ovtv.StartEditing += OnStartEditing;
                    ovtv.EndEditing   += OnEndEditing;
                    ovtv.NodePinned   += OnPinStatusChanged;
                }

                controller.AddValue(value);
            }
            else
            {
                objValueTreeView = new ObjectValueTreeView();
                objValueTreeView.RootPinAlwaysVisible = true;
                objValueTreeView.HeadersVisible       = false;
                objValueTreeView.AllowEditing         = true;
                objValueTreeView.AllowPinning         = true;
                objValueTreeView.CompactView          = true;
                objValueTreeView.PinnedWatch          = watch;
                objValueTreeView.PinnedWatchLocation  = location;
                objValueTreeView.Frame = frame;

                objValueTreeView.AddValue(value);

                objValueTreeView.PinStatusChanged += OnPinStatusChanged;
                objValueTreeView.StartEditing     += OnStartEditing;
                objValueTreeView.EndEditing       += OnEndEditing;

                treeView = objValueTreeView;
            }

            treeView.Name = innerTreeName;
            treeView.Selection.UnselectAll();
            treeView.SizeAllocated += OnTreeSizeChanged;

            sw.Add(treeView);
            ContentBox.Add(sw);
            sw.ShowAll();

            ShowArrow          = true;
            Theme.CornerRadius = 3;
            PreviewWindowManager.WindowClosed += PreviewWindowManager_WindowClosed;
        }
        protected override void UpdateContents()
        {
            if (Node == null)
            {
                return;
            }

            foreach (var constraint in constraints)
            {
                constraint.Active = false;
                constraint.Dispose();
            }
            constraints.Clear();

            OptimalWidth = MarginSize;

            var editable             = TreeView.AllowWatchExpressions && Node.Parent is RootObjectValueNode;
            var selected             = Superview is NSTableRowView rowView && rowView.Selected;
            var iconName             = ObjectValueTreeViewController.GetIcon(Node.Flags);
            var wrapper              = (MacObjectValueNode)ObjectValue;
            var textColor            = NSColor.ControlText;
            var showAddNewExpression = false;
            var placeholder          = string.Empty;
            var name = Node.Name;

            if (Node.IsUnknown)
            {
                if (!selected && TreeView.DebuggerService.Frame != null)
                {
                    textColor = NSColor.FromCGColor(GetCGColor(Styles.ObjectValueTreeValueDisabledText));
                }
            }
            else if (Node.IsError || Node.IsNotSupported)
            {
            }
            else if (Node.IsImplicitNotSupported)
            {
            }
            else if (Node.IsEvaluating)
            {
                if (!selected && Node.GetIsEvaluatingGroup())
                {
                    textColor = NSColor.FromCGColor(GetCGColor(Styles.ObjectValueTreeValueDisabledText));
                }
            }
            else if (Node.IsEnumerable)
            {
            }
            else if (Node is AddNewExpressionObjectValueNode)
            {
                placeholder          = GettextCatalog.GetString("Add item to watch");
                showAddNewExpression = true;
                name     = string.Empty;
                editable = true;
            }
            else if (!selected && TreeView.Controller.GetNodeHasChangedSinceLastCheckpoint(Node))
            {
                textColor = NSColor.FromCGColor(GetCGColor(Styles.ObjectValueTreeValueModifiedText));
            }

            NSView firstView;

            if (showAddNewExpression)
            {
                AddNewExpressionButton.Image = GetImage("gtk-add", Gtk.IconSize.Menu, selected);
                firstView = AddNewExpressionButton;

                if (!addNewExpressionVisible)
                {
                    ImageView.RemoveFromSuperview();
                    AddSubview(AddNewExpressionButton);
                    addNewExpressionVisible = true;
                }
            }
            else
            {
                ImageView.Image = GetImage(iconName, Gtk.IconSize.Menu, selected);
                firstView       = ImageView;

                if (addNewExpressionVisible)
                {
                    AddNewExpressionButton.RemoveFromSuperview();
                    addNewExpressionVisible = false;
                    AddSubview(ImageView);
                }
            }

            constraints.Add(firstView.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
            constraints.Add(firstView.LeadingAnchor.ConstraintEqualToAnchor(LeadingAnchor, MarginSize));
            constraints.Add(firstView.WidthAnchor.ConstraintEqualToConstant(ImageSize));
            constraints.Add(firstView.HeightAnchor.ConstraintEqualToConstant(ImageSize));

            OptimalWidth += ImageSize;
            OptimalWidth += RowCellSpacing;

            TextField.PlaceholderAttributedString = GetAttributedPlaceholderString(placeholder);
            TextField.StringValue = name;
            TextField.TextColor   = textColor;
            TextField.Editable    = editable;
            UpdateFont(TextField);
            TextField.SizeToFit();
            ImageView.AccessibilityTitle = ObjectValueTreeViewController.GetAccessibilityTitleForIcon(
                Node.Flags,
                GettextCatalog.GetString("Object Name"));

            var value     = editable && string.IsNullOrEmpty(name) ? placeholder : name;
            var textWidth = GetWidthForString(TextField.Font, value);

            OptimalWidth += textWidth;

            NSView textView;

            if (editing)
            {
                textView = editorTextView;

                var span = editor.TextBuffer.CurrentSnapshot.GetEntireSpan();
                editor.TextBuffer.Replace(span, name);

                if (!editorTextViewVisible)
                {
                    TextField.RemoveFromSuperview();
                    editorTextViewVisible = true;
                    AddSubview(textView);
                }

                constraints.Add(textView.TopAnchor.ConstraintEqualToAnchor(TopAnchor, (nfloat)editor.FormattedLineSource.BaseIndentation));
                constraints.Add(textView.BottomAnchor.ConstraintEqualToAnchor(BottomAnchor, (nfloat)editor.FormattedLineSource.BaseIndentation));
            }
            else
            {
                textView = TextField;

                if (editorTextViewVisible)
                {
                    editorTextView.RemoveFromSuperview();
                    editorTextViewVisible = false;
                    AddSubview(TextField);
                }

                constraints.Add(TextField.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
            }

            constraints.Add(textView.LeadingAnchor.ConstraintEqualToAnchor(firstView.TrailingAnchor, RowCellSpacing));

            if (!editing && MacObjectValueTreeView.ValidObjectForPreviewIcon(Node))
            {
                SetPreviewButtonIcon(PreviewButtonIcon.Hidden);

                if (!previewIconVisible)
                {
                    AddSubview(PreviewButton);
                    previewIconVisible = true;
                }

                constraints.Add(TextField.WidthAnchor.ConstraintGreaterThanOrEqualToConstant(textWidth));
                constraints.Add(PreviewButton.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
                constraints.Add(PreviewButton.LeadingAnchor.ConstraintEqualToAnchor(TextField.TrailingAnchor, RowCellSpacing));
                constraints.Add(PreviewButton.WidthAnchor.ConstraintEqualToConstant(ImageSize));
                constraints.Add(PreviewButton.HeightAnchor.ConstraintEqualToConstant(ImageSize));

                OptimalWidth += RowCellSpacing;
                OptimalWidth += ImageSize;
            }
            else
            {
                if (previewIconVisible)
                {
                    PreviewButton.RemoveFromSuperview();
                    previewIconVisible = false;
                }

                constraints.Add(textView.TrailingAnchor.ConstraintEqualToAnchor(TrailingAnchor, -MarginSize));
            }

            foreach (var constraint in constraints)
            {
                constraint.Active = true;
            }

            OptimalWidth += MarginSize;

            wrapper.OptimalNameFont  = TreeView.CustomFont;
            wrapper.OptimalNameWidth = OptimalWidth;
            wrapper.OptimalXOffset   = Frame.X;
        }
        protected override void UpdateContents()
        {
            if (Node == null)
            {
                return;
            }

            foreach (var constraint in constraints)
            {
                constraint.Active = false;
                constraint.Dispose();
            }
            constraints.Clear();

            bool   selected           = Superview is NSTableRowView rowView && rowView.Selected;
            var    wrapper            = (MacObjectValueNode)ObjectValue;
            var    editable           = TreeView.GetCanEditNode(Node);
            var    textColor          = NSColor.ControlText;
            string evaluateStatusIcon = null;
            string valueButtonText    = null;
            var    showViewerButton   = false;
            Color? previewColor       = null;
            bool   showSpinner        = false;
            string strval;

            if (Node.IsUnknown)
            {
                if (TreeView.DebuggerService.Frame != null)
                {
                    strval = GettextCatalog.GetString("The name '{0}' does not exist in the current context.", Node.Name);
                }
                else
                {
                    strval = string.Empty;
                }
                evaluateStatusIcon = Ide.Gui.Stock.Warning;
            }
            else if (Node.IsError || Node.IsNotSupported)
            {
                evaluateStatusIcon = Ide.Gui.Stock.Warning;
                strval             = Node.Value ?? string.Empty;
                int i = strval.IndexOf('\n');
                if (i != -1)
                {
                    strval = strval.Substring(0, i);
                }
                if (!selected)
                {
                    textColor = NSColor.FromCGColor(GetCGColor(Styles.ObjectValueTreeValueErrorText));
                }
            }
            else if (Node.IsImplicitNotSupported)
            {
                strval = string.Empty;
                if (!selected)
                {
                    textColor = NSColor.FromCGColor(GetCGColor(Styles.ObjectValueTreeValueDisabledText));
                }
                if (Node.CanRefresh)
                {
                    valueButtonText = GettextCatalog.GetString("Show Value");
                }
            }
            else if (Node.IsEvaluating)
            {
                strval      = GettextCatalog.GetString("Evaluating\u2026");
                showSpinner = true;
                if (!selected)
                {
                    textColor = NSColor.FromCGColor(GetCGColor(Styles.ObjectValueTreeValueDisabledText));
                }
            }
            else if (Node.IsEnumerable)
            {
                if (Node is ShowMoreValuesObjectValueNode)
                {
                    valueButtonText = GettextCatalog.GetString("Show More");
                }
                else
                {
                    valueButtonText = GettextCatalog.GetString("Show Values");
                }
                strval = string.Empty;
            }
            else if (Node is AddNewExpressionObjectValueNode)
            {
                strval   = string.Empty;
                editable = false;
            }
            else
            {
                strval = TreeView.Controller.GetDisplayValueWithVisualisers(Node, out showViewerButton);

                if (!selected && TreeView.Controller.GetNodeHasChangedSinceLastCheckpoint(Node))
                {
                    textColor = NSColor.FromCGColor(GetCGColor(Styles.ObjectValueTreeValueModifiedText));
                }

                var val = Node.GetDebuggerObjectValue();
                if (val != null && !val.IsNull && DebuggingService.HasGetConverter <Color> (val))
                {
                    try {
                        previewColor = DebuggingService.GetGetConverter <Color> (val).GetValue(val);
                    } catch {
                        previewColor = null;
                    }
                }
            }

            strval = strval.Replace("\r\n", " ").Replace("\n", " ");

            var views = new List <NSView> ();

            OptimalWidth = MarginSize;

            // First item: Status Icon -or- Spinner
            if (evaluateStatusIcon != null)
            {
                statusIcon.Image = GetImage(evaluateStatusIcon, Gtk.IconSize.Menu, selected);
                statusIcon.AccessibilityTitle = ObjectValueTreeViewController.GetAccessibilityTitleForIcon(
                    evaluateStatusIcon,
                    GettextCatalog.GetString("Object Value"));
                if (!statusIconVisible)
                {
                    AddSubview(statusIcon);
                    statusIconVisible = true;
                }

                constraints.Add(statusIcon.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
                constraints.Add(statusIcon.WidthAnchor.ConstraintEqualToConstant(ImageSize));
                constraints.Add(statusIcon.HeightAnchor.ConstraintEqualToConstant(ImageSize));
                views.Add(statusIcon);

                OptimalWidth += ImageSize;
                OptimalWidth += RowCellSpacing;
            }
            else if (statusIconVisible)
            {
                statusIcon.RemoveFromSuperview();
                statusIconVisible = false;
            }

            if (showSpinner)
            {
                if (!spinnerVisible)
                {
                    AddSubview(spinner);
                    spinner.StartAnimation(this);
                    spinnerVisible = true;
                }

                constraints.Add(spinner.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
                constraints.Add(spinner.WidthAnchor.ConstraintEqualToConstant(ImageSize));
                constraints.Add(spinner.HeightAnchor.ConstraintEqualToConstant(ImageSize));
                views.Add(spinner);

                OptimalWidth += ImageSize;
                OptimalWidth += RowCellSpacing;
            }
            else if (spinnerVisible)
            {
                spinner.RemoveFromSuperview();
                spinner.StopAnimation(this);
                spinnerVisible = false;
            }

            // Second Item: Color Preview
            if (previewColor.HasValue)
            {
                colorPreview.Layer.BackgroundColor = GetCGColor(previewColor.Value);

                if (!colorPreviewVisible)
                {
                    AddSubview(colorPreview);
                    colorPreviewVisible = true;
                }

                constraints.Add(colorPreview.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
                constraints.Add(colorPreview.WidthAnchor.ConstraintEqualToConstant(ImageSize));
                constraints.Add(colorPreview.HeightAnchor.ConstraintEqualToConstant(ImageSize));
                views.Add(colorPreview);

                OptimalWidth += ImageSize;
                OptimalWidth += RowCellSpacing;
            }
            else if (colorPreviewVisible)
            {
                colorPreview.RemoveFromSuperview();
                colorPreviewVisible = false;
            }

            // Third Item: Value Button
            if (valueButtonText != null && !((MacObjectValueNode)ObjectValue).HideValueButton)
            {
                valueButton.Title = valueButtonText;
                UpdateFont(valueButton, -3);
                valueButton.SizeToFit();

                if (!valueButtonVisible)
                {
                    AddSubview(valueButton);
                    valueButtonVisible = true;
                }

                constraints.Add(valueButton.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
                views.Add(valueButton);

                OptimalWidth += valueButton.Frame.Width;
                OptimalWidth += RowCellSpacing;
            }
            else if (valueButtonVisible)
            {
                valueButton.RemoveFromSuperview();
                valueButtonVisible = false;
            }

            // Fourth Item: Viewer Button
            if (showViewerButton)
            {
                if (!viewerButtonVisible)
                {
                    AddSubview(viewerButton);
                    viewerButtonVisible = true;
                }

                constraints.Add(viewerButton.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
                constraints.Add(viewerButton.WidthAnchor.ConstraintEqualToConstant(viewerButton.Image.Size.Width));
                constraints.Add(viewerButton.HeightAnchor.ConstraintEqualToConstant(viewerButton.Image.Size.Height));
                views.Add(viewerButton);

                OptimalWidth += viewerButton.Frame.Width;
                OptimalWidth += RowCellSpacing;
            }
            else if (viewerButtonVisible)
            {
                viewerButton.RemoveFromSuperview();
                viewerButtonVisible = false;
            }

            // Fifth Item: Text Value
            TextField.StringValue = strval;
            TextField.TextColor   = textColor;
            TextField.Editable    = editable;
            UpdateFont(TextField);
            TextField.SizeToFit();

            OptimalWidth += GetWidthForString(TextField.Font, strval);

            constraints.Add(TextField.CenterYAnchor.ConstraintEqualToAnchor(CenterYAnchor));
            views.Add(TextField);

            // lay out our views...
            var leadingAnchor = LeadingAnchor;

            for (int i = 0; i < views.Count; i++)
            {
                var view = views[i];

                constraints.Add(view.LeadingAnchor.ConstraintEqualToAnchor(leadingAnchor, i == 0 ? MarginSize : RowCellSpacing));
                leadingAnchor = view.TrailingAnchor;
            }

            constraints.Add(TextField.TrailingAnchor.ConstraintEqualToAnchor(TrailingAnchor, -MarginSize));

            foreach (var constraint in constraints)
            {
                constraint.Active = true;
            }

            OptimalWidth += MarginSize;

            wrapper.OptimalValueFont  = TreeView.CustomFont;
            wrapper.OptimalValueWidth = OptimalWidth;
        }