diff options
author | Jeffrey Stedfast <jestedfa@microsoft.com> | 2019-11-07 00:57:24 +0300 |
---|---|---|
committer | monojenkins <jo.shields+jenkins@xamarin.com> | 2019-11-12 23:54:19 +0300 |
commit | 9e0c9dc858927ba199a7150fbb5d3fe89304afb6 (patch) | |
tree | 4886c65b23ae39f3a144735ed874d52ad3dd347b /main | |
parent | df7f3cd627aba348f62e933489c173aa248091cf (diff) |
[Debugger] Optimize OptimizeColumnWidths() by using cached values
Also, if we don't have values cached, measure things w/o the need
to create a view and doing layout.
Diffstat (limited to 'main')
7 files changed, 215 insertions, 31 deletions
diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/QuickInfo/MacDebuggerTooltipWindow.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/QuickInfo/MacDebuggerTooltipWindow.cs index dc60ce593e..64c05cb3a1 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/QuickInfo/MacDebuggerTooltipWindow.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/QuickInfo/MacDebuggerTooltipWindow.cs @@ -108,6 +108,7 @@ namespace MonoDevelop.Debugger void OnTreeViewResized (object sender, EventArgs e) { + Console.WriteLine ("OnTreeViewResized: treeView.Frame.Width = {0}", treeView.Frame.Width); var maxHeight = GetMaxHeight (treeView.Window); var height = treeView.FittingSize.Height; diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectCellViewBase.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectCellViewBase.cs index 6c5f3f2a12..117c6d61bb 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectCellViewBase.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectCellViewBase.cs @@ -158,6 +158,22 @@ namespace MonoDevelop.Debugger return new NSAttributedString (text ?? string.Empty, strokeColor: NSColor.PlaceholderTextColor); } + protected static nfloat GetWidthForString (NSFont font, string text, int sizeDelta = 0) + { + NSFont modified = null; + nfloat width; + + if (sizeDelta != 0) + modified = NSFont.FromDescription (font.FontDescriptor, font.PointSize + sizeDelta); + + using (var str = new NSAttributedString (text, font: modified ?? font)) + width = str.Size.Width; + + modified?.Dispose (); + + return width; + } + protected void UpdateFont (NSControl control, int sizeDelta = 0) { var font = TreeView.CustomFont; diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectNameView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectNameView.cs index ecac5dc836..b2ed813b45 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectNameView.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectNameView.cs @@ -108,6 +108,7 @@ namespace MonoDevelop.Debugger 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; @@ -166,9 +167,9 @@ namespace MonoDevelop.Debugger TextField.TextColor = textColor; TextField.Editable = editable; UpdateFont (TextField); - TextField.SizeToFit (); - OptimalWidth += TextField.Frame.Width; + var value = editable && string.IsNullOrEmpty (name) ? placeholder : name; + OptimalWidth += GetWidthForString (TextField.Font, value); constraints.Add (TextField.CenterYAnchor.ConstraintEqualToAnchor (CenterYAnchor)); constraints.Add (TextField.LeadingAnchor.ConstraintEqualToAnchor (firstView.TrailingAnchor, RowCellSpacing)); @@ -188,7 +189,7 @@ namespace MonoDevelop.Debugger constraints.Add (PreviewButton.HeightAnchor.ConstraintEqualToConstant (ImageSize)); OptimalWidth += RowCellSpacing; - OptimalWidth += PreviewButton.Frame.Width; + OptimalWidth += ImageSize; } else { if (previewIconVisible) { PreviewButton.RemoveFromSuperview (); @@ -202,6 +203,45 @@ namespace MonoDevelop.Debugger constraint.Active = true; OptimalWidth += MarginSize; + + wrapper.OptimalNameFont = TreeView.CustomFont; + wrapper.OptimalNameWidth = OptimalWidth; + wrapper.OptimalXOffset = Frame.X; + } + + public static nfloat GetOptimalWidth (MacObjectValueTreeView treeView, ObjectValueNode node) + { + nfloat optimalWidth = MarginSize; + + var editable = treeView.AllowWatchExpressions && node.Parent is RootObjectValueNode; + var placeholder = string.Empty; + var name = node.Name; + + if (node.IsUnknown) { + } else if (node.IsError || node.IsNotSupported) { + } else if (node.IsImplicitNotSupported) { + } else if (node.IsEvaluating) { + } else if (node.IsEnumerable) { + } else if (node is AddNewExpressionObjectValueNode) { + placeholder = GettextCatalog.GetString ("Add new expression"); + name = string.Empty; + editable = true; + } + + optimalWidth += ImageSize; + optimalWidth += RowCellSpacing; + + var value = editable && string.IsNullOrEmpty (name) ? placeholder : name; + optimalWidth += GetWidthForString (treeView.CustomFont, value); + + if (MacObjectValueTreeView.ValidObjectForPreviewIcon (node)) { + optimalWidth += RowCellSpacing; + optimalWidth += ImageSize; + } + + optimalWidth += MarginSize; + + return optimalWidth; } void OnAddNewExpressionButtonClicked (object sender, EventArgs e) diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectTypeView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectTypeView.cs index bd7251c58d..27bf4688c8 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectTypeView.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectTypeView.cs @@ -58,11 +58,12 @@ namespace MonoDevelop.Debugger protected override void UpdateContents () { - TextField.StringValue = Node?.TypeName ?? string.Empty; + var value = Node?.TypeName ?? string.Empty; + + TextField.StringValue = value; UpdateFont (TextField); - TextField.SizeToFit (); - OptimalWidth = MarginSize + TextField.Frame.Width + MarginSize; + OptimalWidth = MarginSize + GetWidthForString (TextField.Font, value) + MarginSize; } } } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectValueView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectValueView.cs index d6281de310..a7e294d348 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectValueView.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectValueView.cs @@ -116,6 +116,7 @@ namespace MonoDevelop.Debugger 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; @@ -238,7 +239,7 @@ namespace MonoDevelop.Debugger constraints.Add (colorPreview.HeightAnchor.ConstraintEqualToConstant (ImageSize)); views.Add (colorPreview); - OptimalWidth += colorPreview.Frame.Width; + OptimalWidth += ImageSize; OptimalWidth += RowCellSpacing; } else if (colorPreviewVisible) { colorPreview.RemoveFromSuperview (); @@ -290,7 +291,8 @@ namespace MonoDevelop.Debugger TextField.TextColor = textColor; TextField.Editable = editable; UpdateFont (TextField); - TextField.SizeToFit (); + + OptimalWidth += GetWidthForString (TextField.Font, strval); constraints.Add (TextField.CenterYAnchor.ConstraintEqualToAnchor (CenterYAnchor)); views.Add (TextField); @@ -310,8 +312,103 @@ namespace MonoDevelop.Debugger foreach (var constraint in constraints) constraint.Active = true; - OptimalWidth += TextField.Frame.Width; OptimalWidth += MarginSize; + + wrapper.OptimalValueFont = TreeView.CustomFont; + wrapper.OptimalValueWidth = OptimalWidth; + } + + public static nfloat GetOptimalWidth (MacObjectValueTreeView treeView, ObjectValueNode node, bool hideValueButton) + { + nfloat optimalWidth = MarginSize; + + 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); + } else if (node.IsImplicitNotSupported) { + strval = string.Empty;//val.Value; with new "Show Value" button we don't want to display message "Implicit evaluation is disabled" + if (node.CanRefresh) + valueButtonText = GettextCatalog.GetString ("Show Value"); + } else if (node.IsEvaluating) { + strval = GettextCatalog.GetString ("Evaluating\u2026"); + showSpinner = true; + } 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; + } else { + strval = treeView.Controller.GetDisplayValueWithVisualisers (node, out showViewerButton); + + 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", " "); + + // First item: Status Icon -or- Spinner + if (evaluateStatusIcon != null) { + optimalWidth += ImageSize; + optimalWidth += RowCellSpacing; + } + + if (showSpinner) { + optimalWidth += ImageSize; + optimalWidth += RowCellSpacing; + } + + // Second Item: Color Preview + if (previewColor.HasValue) { + optimalWidth += ImageSize; + optimalWidth += RowCellSpacing; + } + + // Third Item: Value Button + if (valueButtonText != null && !hideValueButton) { + // FIXME: what left/right padding do we need to add for the button around the button label? 6px? + optimalWidth += GetWidthForString (treeView.CustomFont, valueButtonText, -3) + 6; + optimalWidth += RowCellSpacing; + } + + // Fourth Item: Viewer Button + if (showViewerButton) { + optimalWidth += treeView.CompactView ? CompactImageSize : ImageSize; + optimalWidth += RowCellSpacing; + } + + // Fifth Item: Text Value + optimalWidth += GetWidthForString (treeView.CustomFont, strval); + + optimalWidth += MarginSize; + + return optimalWidth; } void OnValueButtonActivated (object sender, EventArgs e) diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueNode.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueNode.cs index 12359aee74..530247aad1 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueNode.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueNode.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using AppKit; using Foundation; namespace MonoDevelop.Debugger @@ -39,12 +40,47 @@ namespace MonoDevelop.Debugger public readonly List<MacObjectValueNode> Children = new List<MacObjectValueNode> (); public readonly MacObjectValueNode Parent; public readonly ObjectValueNode Target; + public nfloat OptimalValueWidth; + public NSFont OptimalValueFont; + public nfloat OptimalNameWidth; + public NSFont OptimalNameFont; + public nfloat OptimalXOffset; public bool HideValueButton; public MacObjectValueNode (MacObjectValueNode parent, ObjectValueNode target) { + OptimalValueWidth = -1.0f; + OptimalNameWidth = -1.0f; + OptimalValueFont = null; + OptimalNameFont = null; + OptimalXOffset = -1.0f; Parent = parent; Target = target; } + + public void Measure (MacObjectValueTreeView treeView) + { + if (OptimalXOffset < 0) { + nfloat offset = 17.0f; + var node = Target; + + while (!(node.Parent is RootObjectValueNode)) { + node = node.Parent; + offset += 16.0f; + } + + OptimalXOffset = offset; + } + + if (OptimalNameFont != treeView.CustomFont || OptimalNameWidth < 0) { + OptimalNameWidth = MacDebuggerObjectNameView.GetOptimalWidth (treeView, Target); + OptimalNameFont = treeView.CustomFont; + } + + if (OptimalValueFont != treeView.CustomFont || OptimalValueWidth < 0) { + OptimalValueWidth = MacDebuggerObjectValueView.GetOptimalWidth (treeView, Target, HideValueButton); + OptimalValueFont = treeView.CustomFont; + } + } } } diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueTreeView.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueTreeView.cs index 7663dbd793..df3a14b467 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueTreeView.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueTreeView.cs @@ -223,30 +223,16 @@ namespace MonoDevelop.Debugger nfloat valueWidth = MinimumValueColumnWidth; for (nint row = 0; row < RowCount; row++) { - var rowView = GetRowView (row, true); + var item = (MacObjectValueNode) ItemAtRow (row); - if (rowView == null) - continue; + item.Measure (this); - var nameView = (MacDebuggerObjectNameView) rowView.ViewAtColumn (0); - - if (nameView != null) { - // Note: the Name column's X-offset is the width of the expander which we need to take that into account - // when calculating the Name column's width. - var width = nameView.Frame.X + nameView.OptimalWidth; - - if (width > nameWidth) - nameWidth = NMath.Min (width, nameColumn.MaxWidth); - } - - var valueView = (MacDebuggerObjectValueView) rowView.ViewAtColumn (1); + var totalNameWidth = item.OptimalXOffset + item.OptimalNameWidth; + if (totalNameWidth > nameWidth) + nameWidth = NMath.Min (totalNameWidth, nameColumn.MaxWidth); - if (valueView != null) { - var width = valueView.OptimalWidth; - - if (width > valueWidth) - valueWidth = NMath.Min (width, valueColumn.MaxWidth); - } + if (item.OptimalValueWidth > valueWidth) + valueWidth = NMath.Min (item.OptimalValueWidth, valueColumn.MaxWidth); } bool changed = false; @@ -262,7 +248,14 @@ namespace MonoDevelop.Debugger } if (changed) { - SizeToFit (); + var optimalWidth = nameColumn.Width + valueColumn.Width + pinColumn.Width; + Console.WriteLine ("OptimizeColumnWidths: optimal width = {0}", optimalWidth); + + var size = Frame.Size; + size.Width = optimalWidth; + SetFrameSize (size); + + //SizeToFit (); if (emitResized) OnResized (); |