Skip to content

Commit 5b18b61

Browse files
committed
Reposition tooltip to fit on screen, where possible
1 parent a2c268d commit 5b18b61

File tree

3 files changed

+54
-23
lines changed

3 files changed

+54
-23
lines changed

Source/ExcelDna.IntelliSense.Host/ExcelDna.IntelliSense.Host-AddIn.IntelliSense.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<IntelliSense xmlns="http://schemas.excel-dna.net/intellisense/1.0">
22
<FunctionInfo>
3-
<Function Name="AdxThem" Description="A function described in XML"
3+
<Function Name="AdxThem" Description="A function described in XML with a very long description that goes on and on for a very long time, until it scrolls off the screen no matter which side we pick to display it on."
44
HelpTopic="MyFile.chm!100" >
55
<Argument Name="tag" Description="Whatever you want to put in here" />
66
<Argument Name="Addend" Description="Actually the second arg" />

Source/ExcelDna.IntelliSense/IntelliSenseDisplay.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ void FormulaEditMove(Rect editWindowBounds, IntPtr excelToolTipWindow)
277277
Logger.Display.Warn("FormulaEditMode Unexpected null Arguments ToolTip!?");
278278
return;
279279
}
280-
_argumentsToolTip.MoveToolTip((int)editWindowBounds.Left, (int)editWindowBounds.Bottom + 5);
280+
_argumentsToolTip.MoveToolTip((int)editWindowBounds.Left, (int)editWindowBounds.Bottom + 5, null);
281281
}
282282

283283
// Runs on the main thread
@@ -315,7 +315,7 @@ void FormulaEditTextChange(string formulaPrefix, Rect editWindowBounds, IntPtr e
315315
}
316316

317317
var infoText = GetFunctionIntelliSense(functionInfo, currentArgIndex);
318-
_argumentsToolTip.ShowToolTip(infoText, (int)editWindowBounds.Left, (int)editWindowBounds.Bottom + 5 + moveDown);
318+
_argumentsToolTip.ShowToolTip(infoText, (int)editWindowBounds.Left, (int)editWindowBounds.Bottom + 5 + moveDown, null);
319319
}
320320
else
321321
{
@@ -377,7 +377,8 @@ void FunctionListSelectedItemChange(string selectedItemText, Rect selectedItemBo
377377
_descriptionToolTip.ShowToolTip(
378378
text: new FormattedText { GetFunctionDescriptionOrNull(functionInfo) },
379379
left: (int)listBounds.Right + DescriptionLeftMargin,
380-
top: (int)selectedItemBounds.Bottom - 18);
380+
top: (int)selectedItemBounds.Bottom - 18,
381+
listLeft: (int)selectedItemBounds.Left);
381382
return;
382383
}
383384
}
@@ -388,7 +389,7 @@ void FunctionListSelectedItemChange(string selectedItemText, Rect selectedItemBo
388389

389390
void FunctionListMove(Rect selectedItemBounds, Rect listBounds)
390391
{
391-
_descriptionToolTip.MoveToolTip((int)listBounds.Right + DescriptionLeftMargin, (int)selectedItemBounds.Bottom - 18);
392+
_descriptionToolTip.MoveToolTip((int)listBounds.Right + DescriptionLeftMargin, (int)selectedItemBounds.Bottom - 18, (int)selectedItemBounds.Left);
392393
}
393394

394395
// TODO: Performance / efficiency - cache these somehow

Source/ExcelDna.IntelliSense/ToolTipForm.cs

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ class ToolTipForm : Form
2525
Point _mouseDownScreenLocation;
2626
Point _mouseDownFormLocation;
2727
// We keep track of this, else Visibility seems to confuse things...
28-
int _left;
29-
int _top;
28+
int _currentLeft;
29+
int _currentTop;
3030
int _showLeft;
3131
int _showTop;
32+
int? _listLeft;
3233
// Various graphics object cached
3334
Brush _textBrush;
3435
Brush _linkBrush;
@@ -107,22 +108,23 @@ void ShowToolTip()
107108
}
108109
}
109110

110-
public void ShowToolTip(FormattedText text, int left, int top)
111+
public void ShowToolTip(FormattedText text, int left, int top, int? listLeft)
111112
{
112113
_text = text;
113-
if (left != _showLeft || top != _showTop)
114+
if (left != _showLeft || top != _showTop || listLeft != _listLeft)
114115
{
115116
// Update the start position and the current position
116-
_left = left;
117-
_top = top;
118-
_showLeft = _left;
119-
_showTop = _top;
117+
_currentLeft = left;
118+
_currentTop = top;
119+
_showLeft = left;
120+
_showTop = top;
121+
_listLeft = listLeft;
120122
}
121123
if (!Visible)
122124
{
123125
Debug.Print($"ShowToolTip - Showing ToolTipForm: {_text.ToString()}");
124126
// Make sure we're in the right position before we're first shown
125-
SetBounds(_left, _top, 0, 0);
127+
SetBounds(_currentLeft, _currentTop, 0, 0);
126128
ShowToolTip();
127129
}
128130
else
@@ -133,13 +135,14 @@ public void ShowToolTip(FormattedText text, int left, int top)
133135
}
134136

135137

136-
public void MoveToolTip(int left, int top)
138+
public void MoveToolTip(int left, int top, int? listLeft)
137139
{
138140
// We might consider checking the new position against earlier mouse movements
139-
_left = left;
140-
_top = top;
141-
_showLeft = _left;
142-
_showTop = _top;
141+
_currentLeft = left;
142+
_currentTop = top;
143+
_showLeft = left;
144+
_showTop = top;
145+
_listLeft = listLeft;
143146
Invalidate();
144147
}
145148

@@ -176,7 +179,7 @@ void MouseButtonDown(Point screenLocation)
176179
_captured = true;
177180
Win32Helper.SetCapture(Handle);
178181
_mouseDownScreenLocation = screenLocation;
179-
_mouseDownFormLocation = new Point(_left, _top);
182+
_mouseDownFormLocation = new Point(_currentLeft, _currentTop);
180183
}
181184
}
182185

@@ -186,8 +189,8 @@ void MouseMoved(Point screenLocation)
186189
{
187190
int dx = screenLocation.X - _mouseDownScreenLocation.X;
188191
int dy = screenLocation.Y - _mouseDownScreenLocation.Y;
189-
_left = _mouseDownFormLocation.X + dx;
190-
_top = _mouseDownFormLocation.Y + dy;
192+
_currentLeft = _mouseDownFormLocation.X + dx;
193+
_currentTop = _mouseDownFormLocation.Y + dy;
191194
Invalidate();
192195
return;
193196
}
@@ -321,7 +324,7 @@ protected override void OnPaint(PaintEventArgs e)
321324
}
322325
var width = lineWidths.Max() + widthPadding;
323326
var height = totalHeight + heightPadding;
324-
SetBounds(_left, _top, width, height);
327+
UpdateLocation(width, height);
325328
DrawRoundedRectangle(e.Graphics, new RectangleF(0,0, Width - 1, Height - 1), 2, 2);
326329
}
327330

@@ -363,6 +366,33 @@ void DrawRoundedRectangle(Graphics g, RectangleF r, float radiusX, float radiusY
363366

364367
g.SmoothingMode = oldMode;
365368
}
369+
370+
void UpdateLocation(int width, int height)
371+
{
372+
var workingArea = Screen.GetWorkingArea(new Point(_currentLeft, _currentTop));
373+
bool tipFits = workingArea.Contains(new Rectangle(_currentLeft, _currentTop, width, height));
374+
if (!tipFits && (_currentLeft == _showLeft && _currentTop == _showTop))
375+
{
376+
// It doesn't fit and it's still where we initially tried to show it
377+
// (so it probably hasn't been moved).
378+
if (_listLeft == null)
379+
{
380+
// Not in list selection mode - probably FormulaEdit
381+
_currentLeft = Math.Max(0, (_currentLeft + width) - workingArea.Right);
382+
// CONSIDER: Move up too???
383+
}
384+
else
385+
{
386+
const int leftPadding = 4;
387+
// Check if it fits on the left
388+
if (width < _listLeft.Value - leftPadding)
389+
{
390+
_currentLeft = _listLeft.Value - width - leftPadding;
391+
}
392+
}
393+
}
394+
SetBounds(_currentLeft, _currentTop, width, height);
395+
}
366396
#endregion
367397

368398
protected override CreateParams CreateParams

0 commit comments

Comments
 (0)