From e54926242a12ea6227af5c691702d6c4e9fa4a46 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 17 Dec 2005 21:10:23 +0000 Subject: [PATCH] Fixed SD2-574: tooltip delay (using system setting for MouseHoverTime) git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@909 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/ICSharpCode.TextEditor.csproj | 1 + .../Project/Src/Gui/TextArea.cs | 98 ++++++++++++---- .../Project/Src/Gui/TextAreaMouseHandler.cs | 74 ++++++------ .../Src/Gui/ToolTipRequestEventArgs.cs | 65 +++++++++++ .../Src/Services/Debugger/DebuggerService.cs | 105 +++++++----------- 5 files changed, 226 insertions(+), 117 deletions(-) create mode 100644 src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/ToolTipRequestEventArgs.cs diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/ICSharpCode.TextEditor.csproj b/src/Libraries/ICSharpCode.TextEditor/Project/ICSharpCode.TextEditor.csproj index 4bf492a694..4fd4fc0993 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/ICSharpCode.TextEditor.csproj +++ b/src/Libraries/ICSharpCode.TextEditor/Project/ICSharpCode.TextEditor.csproj @@ -184,6 +184,7 @@ + \ No newline at end of file diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs index d8a11e6f8d..a9a888df01 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextArea.cs @@ -296,12 +296,15 @@ namespace ICSharpCode.TextEditor lastMouseInMargin.HandleMouseLeave(EventArgs.Empty); lastMouseInMargin = null; } + CloseToolTip(); } protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e) { base.OnMouseDown(e); + CloseToolTip(); + foreach (AbstractMargin margin in leftMargins) { if (margin.DrawingPosition.Contains(e.X, e.Y)) { margin.HandleMouseDown(new Point(e.X, e.Y), e.Button); @@ -314,23 +317,11 @@ namespace ICSharpCode.TextEditor // tooltips of text areas from inactive tabs floating around. static DeclarationViewWindow toolTip; static string oldToolTip; - bool toolTipSet; - - public bool ToolTipVisible { - get { - return toolTipSet; - } - } - public void SetToolTip(string text) + void SetToolTip(string text, int lineNumber) { - SetToolTip(text, -1); - } - - public void SetToolTip(string text, int lineNumber) - { - if (toolTip == null || toolTip.IsDisposed) toolTip = new DeclarationViewWindow(this.FindForm()); - toolTipSet = (text != null); + if (toolTip == null || toolTip.IsDisposed) + toolTip = new DeclarationViewWindow(this.FindForm()); if (oldToolTip == text) return; if (text == null) { @@ -351,12 +342,79 @@ namespace ICSharpCode.TextEditor oldToolTip = text; } - protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e) + public event ToolTipRequestEventHandler ToolTipRequest; + + protected virtual void OnToolTipRequest(ToolTipRequestEventArgs e) + { + if (ToolTipRequest != null) { + ToolTipRequest(this, e); + } + } + + bool toolTipActive; + /// + /// Rectangle in text area that caused the current tool tip. + /// Prevents tooltip from re-showing when it was closed because of a click or keyboard + /// input and the mouse was not used. + /// + Rectangle toolTipRectangle; + + void CloseToolTip() + { + if (toolTipActive) { + //Console.WriteLine("Closing tooltip"); + toolTipActive = false; + SetToolTip(null, -1); + } + ResetMouseEventArgs(); + } + + protected override void OnMouseHover(EventArgs e) + { + base.OnMouseHover(e); + //Console.WriteLine("Hover raised at " + PointToClient(Control.MousePosition)); + if (MouseButtons == MouseButtons.None) { + RequestToolTip(PointToClient(Control.MousePosition)); + } else { + CloseToolTip(); + } + } + + protected void RequestToolTip(Point mousePos) + { + if (toolTipRectangle.Contains(mousePos)) { + if (!toolTipActive) + ResetMouseEventArgs(); + return; + } + + //Console.WriteLine("Request tooltip for " + mousePos); + + toolTipRectangle = new Rectangle(mousePos.X - 4, mousePos.Y - 4, 8, 8); + + Point logicPos = textView.GetLogicalPosition(mousePos.X - textView.DrawingPosition.Left, + mousePos.Y - textView.DrawingPosition.Top); + bool inDocument = textView.DrawingPosition.Contains(mousePos) + && logicPos.Y >= 0 && logicPos.Y < Document.TotalNumberOfLines; + ToolTipRequestEventArgs args = new ToolTipRequestEventArgs(mousePos, logicPos, inDocument); + OnToolTipRequest(args); + if (args.ToolTipShown) { + //Console.WriteLine("Set tooltip to " + args.toolTipText); + toolTipActive = true; + SetToolTip(args.toolTipText, inDocument ? logicPos.Y + 1 : -1); + } else { + CloseToolTip(); + } + } + + protected override void OnMouseMove(MouseEventArgs e) { - toolTipSet = false; base.OnMouseMove(e); - if (!toolTipSet) - SetToolTip(null); + if (!toolTipRectangle.Contains(e.Location)) { + toolTipRectangle = Rectangle.Empty; + if (toolTipActive) + RequestToolTip(e.Location); + } foreach (AbstractMargin margin in leftMargins) { if (margin.DrawingPosition.Contains(e.X, e.Y)) { this.Cursor = margin.Cursor; @@ -500,7 +558,7 @@ namespace ICSharpCode.TextEditor HiddenMouseCursor = true; Cursor.Hide(); } - SetToolTip(null); + CloseToolTip(); motherTextEditorControl.BeginUpdate(); // INSERT char diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaMouseHandler.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaMouseHandler.cs index 99acdf3382..64a920fc6f 100644 --- a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaMouseHandler.cs +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/TextAreaMouseHandler.cs @@ -53,6 +53,45 @@ namespace ICSharpCode.TextEditor textArea.MouseLeave += new EventHandler(OnMouseLeave); textArea.MouseUp += new MouseEventHandler(OnMouseUp); textArea.LostFocus += new EventHandler(TextAreaLostFocus); + textArea.ToolTipRequest += new ToolTipRequestEventHandler(OnToolTipRequest); + } + + void OnToolTipRequest(object sender, ToolTipRequestEventArgs e) + { + if (e.ToolTipShown) + return; + Point mousepos = e.MousePosition; + FoldMarker marker = textArea.TextView.GetFoldMarkerFromPosition(mousepos.X - textArea.TextView.DrawingPosition.X, + mousepos.Y - textArea.TextView.DrawingPosition.Y); + if (marker != null && marker.IsFolded) { + StringBuilder sb = new StringBuilder(marker.InnerText); + + // max 10 lines + int endLines = 0; + for (int i = 0; i < sb.Length; ++i) { + if (sb[i] == '\n') { + ++endLines; + if (endLines >= 10) { + sb.Remove(i + 1, sb.Length - i - 1); + sb.Append(Environment.NewLine); + sb.Append("..."); + break; + + } + } + } + sb.Replace("\t", " "); + e.ShowToolTip(sb.ToString()); + return; + } + + List markers = textArea.Document.MarkerStrategy.GetMarkers(e.LogicalPosition); + foreach (TextMarker tm in markers) { + if (tm.ToolTip != null) { + e.ShowToolTip(tm.ToolTip.Replace("\t", " ")); + return; + } + } } void ShowHiddenCursor() @@ -127,41 +166,6 @@ namespace ICSharpCode.TextEditor return; } - if (e.Button == MouseButtons.None && !textArea.ToolTipVisible) { - FoldMarker marker = textArea.TextView.GetFoldMarkerFromPosition(mousepos.X - textArea.TextView.DrawingPosition.X, - mousepos.Y - textArea.TextView.DrawingPosition.Y); - if (marker != null && marker.IsFolded) { - StringBuilder sb = new StringBuilder(marker.InnerText); - - // max 10 lines - int endLines = 0; - for (int i = 0; i < sb.Length; ++i) { - if (sb[i] == '\n') { - ++endLines; - if (endLines >= 10) { - sb.Remove(i + 1, sb.Length - i - 1); - sb.Append(Environment.NewLine); - sb.Append("..."); - break; - - } - } - } - sb.Replace("\t", " "); - textArea.SetToolTip(sb.ToString()); - return; - } - - Point clickPosition2 = textArea.TextView.GetLogicalPosition(mousepos.X - textArea.TextView.DrawingPosition.X, - mousepos.Y - textArea.TextView.DrawingPosition.Y); - List markers = textArea.Document.MarkerStrategy.GetMarkers(clickPosition2); - foreach (TextMarker tm in markers) { - if (tm.ToolTip != null) { - textArea.SetToolTip(tm.ToolTip.Replace("\t", " ")); - return; - } - } - } if (e.Button == MouseButtons.Left) { if (gotmousedown) { diff --git a/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/ToolTipRequestEventArgs.cs b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/ToolTipRequestEventArgs.cs new file mode 100644 index 0000000000..fc3318f9d7 --- /dev/null +++ b/src/Libraries/ICSharpCode.TextEditor/Project/Src/Gui/ToolTipRequestEventArgs.cs @@ -0,0 +1,65 @@ +/* + * Created by SharpDevelop. + * User: DG + * Date: 17.12.2005 + * Time: 21:08 + * + * To change this template use Tools | Options | Coding | Edit Standard Headers. + */ + +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace ICSharpCode.TextEditor +{ + public delegate void ToolTipRequestEventHandler(object sender, ToolTipRequestEventArgs e); + + public class ToolTipRequestEventArgs + { + Point mousePosition; + Point logicalPosition; + bool inDocument; + + public Point MousePosition { + get { + return mousePosition; + } + } + + public Point LogicalPosition { + get { + return logicalPosition; + } + } + + public bool InDocument { + get { + return inDocument; + } + } + + /// + /// Gets if some client handling the event has already shown a tool tip. + /// + public bool ToolTipShown { + get { + return toolTipText != null; + } + } + + internal string toolTipText; + + public void ShowToolTip(string text) + { + toolTipText = text; + } + + public ToolTipRequestEventArgs(Point mousePosition, Point logicalPosition, bool inDocument) + { + this.mousePosition = mousePosition; + this.logicalPosition = logicalPosition; + this.inDocument = inDocument; + } + } +} diff --git a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs index 680ce2b515..c084e413bd 100644 --- a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs +++ b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs @@ -238,8 +238,8 @@ namespace ICSharpCode.Core if (e.Content.Control is TextEditor.TextEditorControl) { TextArea textArea = ((TextEditor.TextEditorControl)e.Content.Control).ActiveTextAreaControl.TextArea; - textArea.IconBarMargin.MouseDown += new MarginMouseEventHandler(IconBarMouseDown); - textArea.MouseMove += new MouseEventHandler(TextAreaMouseMove); + textArea.IconBarMargin.MouseDown += IconBarMouseDown; + textArea.ToolTipRequest += TextAreaToolTipRequest; } } @@ -248,8 +248,8 @@ namespace ICSharpCode.Core if (e.Content.Control is TextEditor.TextEditorControl) { TextArea textArea = ((TextEditor.TextEditorControl)e.Content.Control).ActiveTextAreaControl.TextArea; - textArea.IconBarMargin.MouseDown -= new MarginMouseEventHandler(IconBarMouseDown); - textArea.MouseMove -= new MouseEventHandler(TextAreaMouseMove); + textArea.IconBarMargin.MouseDown -= IconBarMouseDown; + textArea.ToolTipRequest -= TextAreaToolTipRequest; } } @@ -277,18 +277,16 @@ namespace ICSharpCode.Core } #region Tool tips - static string oldExpression, oldToolTip; static DebuggerGridControl oldToolTipControl; - static int oldLine; /// /// This function shows variable values as tooltips /// - static void TextAreaMouseMove(object sender, MouseEventArgs args) + static void TextAreaToolTipRequest(object sender, ToolTipRequestEventArgs e) { try { TextArea textArea = (TextArea)sender; - if (textArea.ToolTipVisible) return; + if (e.ToolTipShown) return; if (oldToolTipControl != null && !oldToolTipControl.AllowClose) return; if (!CodeCompletionOptions.TooltipsEnabled) return; @@ -297,64 +295,47 @@ namespace ICSharpCode.Core if (!currentDebugger.IsDebugging) return; } - Point mousepos = textArea.PointToClient(Control.MousePosition); - Rectangle viewRect = textArea.TextView.DrawingPosition; - if (viewRect.Contains(mousepos)) { - Point logicPos = textArea.TextView.GetLogicalPosition(mousepos.X - viewRect.Left, - mousepos.Y - viewRect.Top); - if (logicPos.Y >= 0 && logicPos.Y < textArea.Document.TotalNumberOfLines) { - IDocument doc = textArea.Document; - IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(textArea.MotherTextEditorControl.FileName); - if (expressionFinder == null) - return; - LineSegment seg = doc.GetLineSegment(logicPos.Y); - if (logicPos.X > seg.Length - 1) - return; - string textContent = doc.TextContent; - ExpressionResult expressionResult = expressionFinder.FindFullExpression(textContent, seg.Offset + logicPos.X); - string expression = expressionResult.Expression; - if (expression != null && expression.Length > 0) { - if (expression == oldExpression && oldLine == logicPos.Y) { - // same expression in same line -> reuse old tooltip - if (oldToolTip != null) { - textArea.SetToolTip(oldToolTip, oldLine + 1); - } - // SetToolTip must be called in every mousemove event, - // otherwise textArea will close the tooltip. - } else { - // Look if it is variable - ResolveResult result = ParserService.Resolve(expressionResult, logicPos.Y + 1, logicPos.X + 1, textArea.MotherTextEditorControl.FileName, textContent); - bool debuggerCanShowValue; - string toolTipText = GetText(result, expression, out debuggerCanShowValue); - DebuggerGridControl toolTipControl = null; - if (toolTipText != null) { - if (Control.ModifierKeys == Keys.Control) { - toolTipText = "expr: " + expressionResult.ToString() + "\n" + toolTipText; - } else if (debuggerCanShowValue && currentDebugger != null) { - toolTipControl = currentDebugger.GetTooltipControl(expressionResult.ToString().Replace("<","").Replace(">","")); - toolTipText = null; - } - } - if (toolTipText != null) { - textArea.SetToolTip(toolTipText, logicPos.Y + 1); - } - if (oldToolTipControl != null) { - Form frm = oldToolTipControl.FindForm(); - if (frm != null) frm.Close(); - } - if (toolTipControl != null) { - toolTipControl.ShowForm(textArea, logicPos); - } - oldToolTip = toolTipText; - oldToolTipControl = toolTipControl; + if (e.InDocument) { + Point logicPos = e.LogicalPosition; + IDocument doc = textArea.Document; + IExpressionFinder expressionFinder = ParserService.GetExpressionFinder(textArea.MotherTextEditorControl.FileName); + if (expressionFinder == null) + return; + LineSegment seg = doc.GetLineSegment(logicPos.Y); + if (logicPos.X > seg.Length - 1) + return; + string textContent = doc.TextContent; + ExpressionResult expressionResult = expressionFinder.FindFullExpression(textContent, seg.Offset + logicPos.X); + string expression = expressionResult.Expression; + if (expression != null && expression.Length > 0) { + // Look if it is variable + ResolveResult result = ParserService.Resolve(expressionResult, logicPos.Y + 1, logicPos.X + 1, textArea.MotherTextEditorControl.FileName, textContent); + bool debuggerCanShowValue; + string toolTipText = GetText(result, expression, out debuggerCanShowValue); + DebuggerGridControl toolTipControl = null; + if (toolTipText != null) { + if (Control.ModifierKeys == Keys.Control) { + toolTipText = "expr: " + expressionResult.ToString() + "\n" + toolTipText; + } else if (debuggerCanShowValue && currentDebugger != null) { + toolTipControl = currentDebugger.GetTooltipControl(expressionResult.Expression); + toolTipText = null; } } - oldLine = logicPos.Y; - oldExpression = expression; + if (toolTipText != null) { + e.ShowToolTip(toolTipText); + } + if (oldToolTipControl != null) { + Form frm = oldToolTipControl.FindForm(); + if (frm != null) frm.Close(); + } + if (toolTipControl != null) { + toolTipControl.ShowForm(textArea, logicPos); + } + oldToolTipControl = toolTipControl; } } - } catch (Exception e) { - ICSharpCode.Core.MessageService.ShowError(e); + } catch (Exception ex) { + ICSharpCode.Core.MessageService.ShowError(ex); } }