mirror of https://github.com/icsharpcode/ILSpy.git
8 changed files with 419 additions and 167 deletions
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using ICSharpCode.AvalonEdit; |
||||
using ICSharpCode.AvalonEdit.Utils; |
||||
|
||||
namespace ILSpy.Debugger.AvalonEdit |
||||
{ |
||||
public static class TextEditorWeakEventManager |
||||
{ |
||||
public sealed class MouseHover : WeakEventManagerBase<MouseHover, TextEditor> |
||||
{ |
||||
protected override void StopListening(TextEditor source) |
||||
{ |
||||
source.MouseHover -= DeliverEvent; |
||||
} |
||||
|
||||
protected override void StartListening(TextEditor source) |
||||
{ |
||||
source.MouseHover += DeliverEvent; |
||||
} |
||||
} |
||||
|
||||
public sealed class MouseHoverStopped : WeakEventManagerBase<MouseHoverStopped, TextEditor> |
||||
{ |
||||
protected override void StopListening(TextEditor source) |
||||
{ |
||||
source.MouseHoverStopped -= DeliverEvent; |
||||
} |
||||
|
||||
protected override void StartListening(TextEditor source) |
||||
{ |
||||
source.MouseHoverStopped += DeliverEvent; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,71 @@
@@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using ICSharpCode.AvalonEdit; |
||||
using ICSharpCode.NRefactory.CSharp; |
||||
|
||||
namespace ILSpy.Debugger.ToolTips |
||||
{ |
||||
public class ToolTipRequestEventArgs : EventArgs |
||||
{ |
||||
/// <summary>
|
||||
/// Gets whether the tool tip request was handled.
|
||||
/// </summary>
|
||||
public bool Handled { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the editor causing the request.
|
||||
/// </summary>
|
||||
public TextEditor Editor { get; private set; } |
||||
|
||||
/// <summary>
|
||||
/// Gets whether the mouse was inside the document bounds.
|
||||
/// </summary>
|
||||
public bool InDocument { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// The mouse position, in document coordinates.
|
||||
/// </summary>
|
||||
public AstLocation LogicalPosition { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the content to show as a tooltip.
|
||||
/// </summary>
|
||||
public object ContentToShow { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Sets the tooltip to be shown.
|
||||
/// </summary>
|
||||
public void SetToolTip(object content) |
||||
{ |
||||
if (content == null) |
||||
throw new ArgumentNullException("content"); |
||||
this.Handled = true; |
||||
this.ContentToShow = content; |
||||
} |
||||
|
||||
public ToolTipRequestEventArgs(TextEditor editor) |
||||
{ |
||||
if (editor == null) |
||||
throw new ArgumentNullException("editor"); |
||||
this.Editor = editor; |
||||
this.InDocument = true; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,197 @@
@@ -0,0 +1,197 @@
|
||||
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
// software and associated documentation files (the "Software"), to deal in the Software
|
||||
// without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
||||
// to whom the Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or
|
||||
// substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Controls.Primitives; |
||||
using System.Windows.Input; |
||||
|
||||
using ICSharpCode.AvalonEdit; |
||||
using ICSharpCode.AvalonEdit.Rendering; |
||||
using ICSharpCode.NRefactory.CSharp; |
||||
using ILSpy.Debugger.AvalonEdit; |
||||
using ILSpy.Debugger.Services; |
||||
|
||||
namespace ILSpy.Debugger.ToolTips |
||||
{ |
||||
/// <summary>
|
||||
/// Description of TextEditorListener.
|
||||
/// </summary>
|
||||
public class TextEditorListener : IWeakEventListener |
||||
{ |
||||
private static readonly TextEditorListener instance; |
||||
|
||||
static TextEditorListener() |
||||
{ |
||||
instance = new TextEditorListener(); |
||||
} |
||||
|
||||
private TextEditorListener() { } |
||||
|
||||
Popup popup; |
||||
ToolTip toolTip; |
||||
TextEditor editor; |
||||
|
||||
public static TextEditorListener Instance { |
||||
get { return instance; } |
||||
} |
||||
|
||||
public bool ReceiveWeakEvent(Type managerType, object sender, EventArgs e) |
||||
{ |
||||
if (managerType == typeof(ILSpy.Debugger.AvalonEdit.TextEditorWeakEventManager.MouseHover)) { |
||||
editor = (TextEditor)sender; |
||||
OnMouseHover((MouseEventArgs)e); |
||||
} |
||||
|
||||
if (managerType == typeof(ILSpy.Debugger.AvalonEdit.TextEditorWeakEventManager.MouseHoverStopped)) { |
||||
OnMouseHoverStopped((MouseEventArgs)e); |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
void OnMouseHoverStopped(MouseEventArgs e) |
||||
{ |
||||
if (popup != null) |
||||
popup.IsOpen = false; |
||||
|
||||
if (toolTip != null) |
||||
toolTip.IsOpen = false; |
||||
} |
||||
|
||||
void OnMouseHover(MouseEventArgs e) |
||||
{ |
||||
ToolTipRequestEventArgs args = new ToolTipRequestEventArgs(editor); |
||||
var pos = editor.GetPositionFromPoint(e.GetPosition(editor)); |
||||
args.InDocument = pos.HasValue; |
||||
|
||||
if (pos.HasValue) { |
||||
args.LogicalPosition = new AstLocation(pos.Value.Column, pos.Value.Line); |
||||
} |
||||
|
||||
DebuggerService.HandleToolTipRequest(args); |
||||
|
||||
if (args.ContentToShow != null) { |
||||
var contentToShowITooltip = args.ContentToShow as ITooltip; |
||||
|
||||
if (contentToShowITooltip != null && contentToShowITooltip.ShowAsPopup) { |
||||
if (!(args.ContentToShow is UIElement)) { |
||||
throw new NotSupportedException("Content to show in Popup must be UIElement: " + args.ContentToShow); |
||||
} |
||||
if (popup == null) { |
||||
popup = CreatePopup(); |
||||
} |
||||
if (TryCloseExistingPopup(false)) { |
||||
// when popup content decides to close, close the popup
|
||||
contentToShowITooltip.Closed += delegate { popup.IsOpen = false; }; |
||||
popup.Child = (UIElement)args.ContentToShow; |
||||
//ICSharpCode.SharpDevelop.Debugging.DebuggerService.CurrentDebugger.IsProcessRunningChanged
|
||||
SetPopupPosition(popup, e); |
||||
popup.IsOpen = true; |
||||
} |
||||
e.Handled = true; |
||||
} else { |
||||
if (toolTip == null) { |
||||
toolTip = new ToolTip(); |
||||
toolTip.Closed += delegate { toolTip = null; }; |
||||
} |
||||
toolTip.PlacementTarget = editor; // required for property inheritance
|
||||
|
||||
if(args.ContentToShow is string) { |
||||
toolTip.Content = new TextBlock |
||||
{ |
||||
Text = args.ContentToShow as string, |
||||
TextWrapping = TextWrapping.Wrap |
||||
}; |
||||
} |
||||
else |
||||
toolTip.Content = args.ContentToShow; |
||||
|
||||
toolTip.IsOpen = true; |
||||
e.Handled = true; |
||||
} |
||||
} else { |
||||
// close popup if mouse hovered over empty area
|
||||
if (popup != null) { |
||||
e.Handled = true; |
||||
} |
||||
TryCloseExistingPopup(false); |
||||
} |
||||
} |
||||
|
||||
bool TryCloseExistingPopup(bool mouseClick) |
||||
{ |
||||
bool canClose = true; |
||||
if (popup != null) { |
||||
var popupContentITooltip = popup.Child as ITooltip; |
||||
if (popupContentITooltip != null) { |
||||
canClose = popupContentITooltip.Close(mouseClick); |
||||
} |
||||
if (canClose) { |
||||
popup.IsOpen = false; |
||||
} |
||||
} |
||||
return canClose; |
||||
} |
||||
|
||||
void SetPopupPosition(Popup popup, MouseEventArgs mouseArgs) |
||||
{ |
||||
var popupPosition = GetPopupPosition(mouseArgs); |
||||
popup.HorizontalOffset = popupPosition.X; |
||||
popup.VerticalOffset = popupPosition.Y; |
||||
} |
||||
|
||||
/// <summary> Returns Popup position based on mouse position, in device independent units </summary>
|
||||
Point GetPopupPosition(MouseEventArgs mouseArgs) |
||||
{ |
||||
Point mousePos = mouseArgs.GetPosition(editor); |
||||
Point positionInPixels; |
||||
// align Popup with line bottom
|
||||
TextViewPosition? logicalPos = editor.GetPositionFromPoint(mousePos); |
||||
if (logicalPos.HasValue) { |
||||
var textView = editor.TextArea.TextView; |
||||
positionInPixels = |
||||
textView.PointToScreen( |
||||
textView.GetVisualPosition(logicalPos.Value, VisualYPosition.LineBottom) - textView.ScrollOffset); |
||||
positionInPixels.X -= 4; |
||||
} else { |
||||
positionInPixels = editor.PointToScreen(mousePos + new Vector(-4, 6)); |
||||
} |
||||
// use device independent units, because Popup Left/Top are in independent units
|
||||
return positionInPixels.TransformFromDevice(editor); |
||||
} |
||||
|
||||
Popup CreatePopup() |
||||
{ |
||||
popup = new Popup(); |
||||
popup.Closed += delegate { popup = null; }; |
||||
popup.AllowsTransparency = true; |
||||
popup.PlacementTarget = editor; // required for property inheritance
|
||||
popup.Placement = PlacementMode.Absolute; |
||||
popup.StaysOpen = true; |
||||
return popup; |
||||
} |
||||
|
||||
|
||||
bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e) |
||||
{ |
||||
return ReceiveWeakEvent(managerType, sender, e); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue