Skip to content
This repository was archived by the owner on Oct 4, 2021. It is now read-only.

Commit 88a8f27

Browse files
authored
Merge pull request #9282 from mono/backport-pr-9270-to-release-8.4
[release-8.4] [Debugger] Optimize debugger tooltip resizing
2 parents ea125e7 + ee6b91a commit 88a8f27

File tree

9 files changed

+234
-68
lines changed

9 files changed

+234
-68
lines changed

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/PinnedWatches/PinnedWatchView.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ void OnTreeViewResized (object sender, EventArgs e)
126126

127127
var origin = textView.ConvertPointFromView (Frame.Location, this);
128128
var maxHeight = NMath.Max (textView.Frame.Bottom - origin.Y, treeView.RowHeight * 2);
129-
var height = treeView.FittingSize.Height;
130-
var width = treeView.Frame.Width;
129+
var height = (treeView.RowHeight + treeView.IntercellSpacing.Height) * treeView.RowCount;
130+
var width = treeView.OptimalTooltipWidth;
131131

132132
height = NMath.Min (height, maxHeight);
133133

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.VSTextView/QuickInfo/MacDebuggerTooltipWindow.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public MacDebuggerTooltipWindow (PinnedWatchLocation location, StackFrame frame,
6969
View = scrollView
7070
};
7171

72-
widthConstraint = scrollView.WidthAnchor.ConstraintEqualToAnchor (treeView.WidthAnchor);
72+
widthConstraint = scrollView.WidthAnchor.ConstraintEqualToConstant (treeView.Frame.Width);
7373
widthConstraint.Active = true;
7474

7575
heightConstraint = scrollView.HeightAnchor.ConstraintEqualToConstant (treeView.Frame.Height);
@@ -108,11 +108,12 @@ static nfloat GetMaxHeight (NSWindow window)
108108

109109
void OnTreeViewResized (object sender, EventArgs e)
110110
{
111+
var height = (treeView.RowHeight + treeView.IntercellSpacing.Height) * treeView.RowCount;
111112
var maxHeight = GetMaxHeight (treeView.Window);
112-
var height = treeView.FittingSize.Height;
113113

114114
height = NMath.Min (height, maxHeight);
115115

116+
widthConstraint.Constant = treeView.OptimalTooltipWidth;
116117
heightConstraint.Constant = height;
117118
}
118119

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectCellViewBase.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,22 @@ protected static NSAttributedString GetAttributedPlaceholderString (string text)
158158
return new NSAttributedString (text ?? string.Empty, strokeColor: NSColor.PlaceholderTextColor);
159159
}
160160

161+
protected static nfloat GetWidthForString (NSFont font, string text, int sizeDelta = 0)
162+
{
163+
NSFont modified = null;
164+
nfloat width;
165+
166+
if (sizeDelta != 0)
167+
modified = NSFont.FromDescription (font.FontDescriptor, font.PointSize + sizeDelta);
168+
169+
using (var str = new NSAttributedString (text, font: modified ?? font))
170+
width = str.Size.Width;
171+
172+
modified?.Dispose ();
173+
174+
return NMath.Ceiling (width + 2);
175+
}
176+
161177
protected void UpdateFont (NSControl control, int sizeDelta = 0)
162178
{
163179
var font = TreeView.CustomFont;

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectNameView.cs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ protected override void UpdateContents ()
108108
var editable = TreeView.AllowWatchExpressions && Node.Parent is RootObjectValueNode;
109109
var selected = Superview is NSTableRowView rowView && rowView.Selected;
110110
var iconName = ObjectValueTreeViewController.GetIcon (Node.Flags);
111+
var wrapper = (MacObjectValueNode) ObjectValue;
111112
var textColor = NSColor.ControlText;
112113
var showAddNewExpression = false;
113114
var placeholder = string.Empty;
@@ -166,9 +167,9 @@ protected override void UpdateContents ()
166167
TextField.TextColor = textColor;
167168
TextField.Editable = editable;
168169
UpdateFont (TextField);
169-
TextField.SizeToFit ();
170170

171-
OptimalWidth += TextField.Frame.Width;
171+
var value = editable && string.IsNullOrEmpty (name) ? placeholder : name;
172+
OptimalWidth += GetWidthForString (TextField.Font, value);
172173

173174
constraints.Add (TextField.CenterYAnchor.ConstraintEqualToAnchor (CenterYAnchor));
174175
constraints.Add (TextField.LeadingAnchor.ConstraintEqualToAnchor (firstView.TrailingAnchor, RowCellSpacing));
@@ -188,7 +189,7 @@ protected override void UpdateContents ()
188189
constraints.Add (PreviewButton.HeightAnchor.ConstraintEqualToConstant (ImageSize));
189190

190191
OptimalWidth += RowCellSpacing;
191-
OptimalWidth += PreviewButton.Frame.Width;
192+
OptimalWidth += ImageSize;
192193
} else {
193194
if (previewIconVisible) {
194195
PreviewButton.RemoveFromSuperview ();
@@ -202,6 +203,45 @@ protected override void UpdateContents ()
202203
constraint.Active = true;
203204

204205
OptimalWidth += MarginSize;
206+
207+
wrapper.OptimalNameFont = TreeView.CustomFont;
208+
wrapper.OptimalNameWidth = OptimalWidth;
209+
wrapper.OptimalXOffset = Frame.X;
210+
}
211+
212+
public static nfloat GetOptimalWidth (MacObjectValueTreeView treeView, ObjectValueNode node)
213+
{
214+
nfloat optimalWidth = MarginSize;
215+
216+
var editable = treeView.AllowWatchExpressions && node.Parent is RootObjectValueNode;
217+
var placeholder = string.Empty;
218+
var name = node.Name;
219+
220+
if (node.IsUnknown) {
221+
} else if (node.IsError || node.IsNotSupported) {
222+
} else if (node.IsImplicitNotSupported) {
223+
} else if (node.IsEvaluating) {
224+
} else if (node.IsEnumerable) {
225+
} else if (node is AddNewExpressionObjectValueNode) {
226+
placeholder = GettextCatalog.GetString ("Add new expression");
227+
name = string.Empty;
228+
editable = true;
229+
}
230+
231+
optimalWidth += ImageSize;
232+
optimalWidth += RowCellSpacing;
233+
234+
var value = editable && string.IsNullOrEmpty (name) ? placeholder : name;
235+
optimalWidth += GetWidthForString (treeView.CustomFont, value);
236+
237+
if (MacObjectValueTreeView.ValidObjectForPreviewIcon (node)) {
238+
optimalWidth += RowCellSpacing;
239+
optimalWidth += ImageSize;
240+
}
241+
242+
optimalWidth += MarginSize;
243+
244+
return optimalWidth;
205245
}
206246

207247
void OnAddNewExpressionButtonClicked (object sender, EventArgs e)

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectTypeView.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,12 @@ public MacDebuggerObjectTypeView (IntPtr handle) : base (handle)
5858

5959
protected override void UpdateContents ()
6060
{
61-
TextField.StringValue = Node?.TypeName ?? string.Empty;
61+
var value = Node?.TypeName ?? string.Empty;
62+
63+
TextField.StringValue = value;
6264
UpdateFont (TextField);
63-
TextField.SizeToFit ();
6465

65-
OptimalWidth = MarginSize + TextField.Frame.Width + MarginSize;
66+
OptimalWidth = MarginSize + GetWidthForString (TextField.Font, value) + MarginSize;
6667
}
6768
}
6869
}

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacDebuggerObjectValueView.cs

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ protected override void UpdateContents ()
116116
constraints.Clear ();
117117

118118
bool selected = Superview is NSTableRowView rowView && rowView.Selected;
119+
var wrapper = (MacObjectValueNode) ObjectValue;
119120
var editable = TreeView.GetCanEditNode (Node);
120121
var textColor = NSColor.ControlText;
121122
string evaluateStatusIcon = null;
@@ -238,7 +239,7 @@ protected override void UpdateContents ()
238239
constraints.Add (colorPreview.HeightAnchor.ConstraintEqualToConstant (ImageSize));
239240
views.Add (colorPreview);
240241

241-
OptimalWidth += colorPreview.Frame.Width;
242+
OptimalWidth += ImageSize;
242243
OptimalWidth += RowCellSpacing;
243244
} else if (colorPreviewVisible) {
244245
colorPreview.RemoveFromSuperview ();
@@ -290,7 +291,8 @@ protected override void UpdateContents ()
290291
TextField.TextColor = textColor;
291292
TextField.Editable = editable;
292293
UpdateFont (TextField);
293-
TextField.SizeToFit ();
294+
295+
OptimalWidth += GetWidthForString (TextField.Font, strval);
294296

295297
constraints.Add (TextField.CenterYAnchor.ConstraintEqualToAnchor (CenterYAnchor));
296298
views.Add (TextField);
@@ -310,8 +312,102 @@ protected override void UpdateContents ()
310312
foreach (var constraint in constraints)
311313
constraint.Active = true;
312314

313-
OptimalWidth += TextField.Frame.Width;
314315
OptimalWidth += MarginSize;
316+
317+
wrapper.OptimalValueFont = TreeView.CustomFont;
318+
wrapper.OptimalValueWidth = OptimalWidth;
319+
}
320+
321+
public static nfloat GetOptimalWidth (MacObjectValueTreeView treeView, ObjectValueNode node, bool hideValueButton)
322+
{
323+
nfloat optimalWidth = MarginSize;
324+
string evaluateStatusIcon = null;
325+
string valueButtonText = null;
326+
var showViewerButton = false;
327+
Color? previewColor = null;
328+
bool showSpinner = false;
329+
string strval;
330+
331+
if (node.IsUnknown) {
332+
if (treeView.DebuggerService.Frame != null) {
333+
strval = GettextCatalog.GetString ("The name '{0}' does not exist in the current context.", node.Name);
334+
} else {
335+
strval = string.Empty;
336+
}
337+
evaluateStatusIcon = Ide.Gui.Stock.Warning;
338+
} else if (node.IsError || node.IsNotSupported) {
339+
evaluateStatusIcon = Ide.Gui.Stock.Warning;
340+
strval = node.Value ?? string.Empty;
341+
int i = strval.IndexOf ('\n');
342+
if (i != -1)
343+
strval = strval.Substring (0, i);
344+
} else if (node.IsImplicitNotSupported) {
345+
strval = string.Empty;//val.Value; with new "Show Value" button we don't want to display message "Implicit evaluation is disabled"
346+
if (node.CanRefresh)
347+
valueButtonText = GettextCatalog.GetString ("Show Value");
348+
} else if (node.IsEvaluating) {
349+
strval = GettextCatalog.GetString ("Evaluating\u2026");
350+
showSpinner = true;
351+
} else if (node.IsEnumerable) {
352+
if (node is ShowMoreValuesObjectValueNode) {
353+
valueButtonText = GettextCatalog.GetString ("Show More");
354+
} else {
355+
valueButtonText = GettextCatalog.GetString ("Show Values");
356+
}
357+
strval = string.Empty;
358+
} else if (node is AddNewExpressionObjectValueNode) {
359+
strval = string.Empty;
360+
} else {
361+
strval = treeView.Controller.GetDisplayValueWithVisualisers (node, out showViewerButton);
362+
363+
var val = node.GetDebuggerObjectValue ();
364+
if (val != null && !val.IsNull && DebuggingService.HasGetConverter<Color> (val)) {
365+
try {
366+
previewColor = DebuggingService.GetGetConverter<Color> (val).GetValue (val);
367+
} catch {
368+
previewColor = null;
369+
}
370+
}
371+
}
372+
373+
strval = strval.Replace ("\r\n", " ").Replace ("\n", " ");
374+
375+
// First item: Status Icon -or- Spinner
376+
if (evaluateStatusIcon != null) {
377+
optimalWidth += ImageSize;
378+
optimalWidth += RowCellSpacing;
379+
}
380+
381+
if (showSpinner) {
382+
optimalWidth += ImageSize;
383+
optimalWidth += RowCellSpacing;
384+
}
385+
386+
// Second Item: Color Preview
387+
if (previewColor.HasValue) {
388+
optimalWidth += ImageSize;
389+
optimalWidth += RowCellSpacing;
390+
}
391+
392+
// Third Item: Value Button
393+
if (valueButtonText != null && !hideValueButton) {
394+
// FIXME: what left/right padding do we need to add for the button around the button label? 4px?
395+
optimalWidth += GetWidthForString (treeView.CustomFont, valueButtonText, -3) + 4;
396+
optimalWidth += RowCellSpacing;
397+
}
398+
399+
// Fourth Item: Viewer Button
400+
if (showViewerButton) {
401+
optimalWidth += treeView.CompactView ? CompactImageSize : ImageSize;
402+
optimalWidth += RowCellSpacing;
403+
}
404+
405+
// Fifth Item: Text Value
406+
optimalWidth += GetWidthForString (treeView.CustomFont, strval);
407+
408+
optimalWidth += MarginSize;
409+
410+
return optimalWidth;
315411
}
316412

317413
void OnValueButtonActivated (object sender, EventArgs e)

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/ObjectValue/Mac/MacObjectValueNode.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
using System;
2828
using System.Collections.Generic;
2929

30+
using AppKit;
3031
using Foundation;
3132

3233
namespace MonoDevelop.Debugger
@@ -39,12 +40,47 @@ class MacObjectValueNode : NSObject
3940
public readonly List<MacObjectValueNode> Children = new List<MacObjectValueNode> ();
4041
public readonly MacObjectValueNode Parent;
4142
public readonly ObjectValueNode Target;
43+
public nfloat OptimalValueWidth;
44+
public NSFont OptimalValueFont;
45+
public nfloat OptimalNameWidth;
46+
public NSFont OptimalNameFont;
47+
public nfloat OptimalXOffset;
4248
public bool HideValueButton;
4349

4450
public MacObjectValueNode (MacObjectValueNode parent, ObjectValueNode target)
4551
{
52+
OptimalValueWidth = -1.0f;
53+
OptimalNameWidth = -1.0f;
54+
OptimalValueFont = null;
55+
OptimalNameFont = null;
56+
OptimalXOffset = -1.0f;
4657
Parent = parent;
4758
Target = target;
4859
}
60+
61+
public void Measure (MacObjectValueTreeView treeView)
62+
{
63+
if (OptimalXOffset < 0) {
64+
nfloat offset = 17.0f;
65+
var node = Target;
66+
67+
while (!(node.Parent is RootObjectValueNode)) {
68+
node = node.Parent;
69+
offset += 16.0f;
70+
}
71+
72+
OptimalXOffset = offset;
73+
}
74+
75+
if (OptimalNameFont != treeView.CustomFont || OptimalNameWidth < 0) {
76+
OptimalNameWidth = MacDebuggerObjectNameView.GetOptimalWidth (treeView, Target);
77+
OptimalNameFont = treeView.CustomFont;
78+
}
79+
80+
if (OptimalValueFont != treeView.CustomFont || OptimalValueWidth < 0) {
81+
OptimalValueWidth = MacDebuggerObjectValueView.GetOptimalWidth (treeView, Target, HideValueButton);
82+
OptimalValueFont = treeView.CustomFont;
83+
}
84+
}
4985
}
5086
}

0 commit comments

Comments
 (0)