diff --git a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin index 79c009707e..a17ec6120e 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin +++ b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin @@ -15,13 +15,6 @@ - - - - EditBreakpointScriptWindow.xaml Code - DebuggerTooltipControl.xaml - - - PinCloseControl.xaml - - - PinDebuggerControl.xaml - - - - VisualizerPicker.xaml @@ -205,6 +194,7 @@ + @@ -267,7 +257,6 @@ DebuggeeExceptionForm.cs - @@ -372,9 +361,6 @@ - - - diff --git a/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptions.cs b/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptions.cs index 17ab1144f6..d8de070030 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptions.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Options/DebuggingOptions.cs @@ -10,7 +10,7 @@ using ICSharpCode.Core; namespace ICSharpCode.SharpDevelop.Services { - public enum ShowIntegersAs { Auto, Decimal, Hexadecimal }; + public enum ShowIntegersAs { Decimal, Hexadecimal, Both, Auto }; [Serializable] public class DebuggingOptions: Options diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs index b391df174f..ccc20a9464 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/WatchPadCommands.cs @@ -94,8 +94,8 @@ namespace Debugger.AddIn if (this.Owner is WatchPad) { WatchPad pad = (WatchPad)this.Owner; var node = pad.WatchList.SelectedNode; - if (node != null && node.Node is ExpressionNode) { - string text = ((ExpressionNode)node.Node).FullText; + if (node != null && node.Node is ValueNode) { + string text = ((ValueNode)node.Node).FullText; ClipboardWrapper.SetText(text); } } diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/TreeNodeWrapper.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/TreeNodeWrapper.cs index 3bd353e36c..3b624fe16b 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/TreeNodeWrapper.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/TreeNodeWrapper.cs @@ -32,7 +32,7 @@ namespace Debugger.AddIn.Pads.Controls } public override object Icon { - get { return this.Node.ImageSource; } + get { return this.Node.Image.ImageSource; } } public override bool ShowExpander { diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml index f31b220086..d88e84eef2 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml @@ -21,7 +21,7 @@ - + @@ -32,7 +32,7 @@ - + @@ -41,8 +41,8 @@ - - + + diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml.cs index 07ad0ec678..f382c435f9 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/Controls/WatchList.xaml.cs @@ -53,9 +53,9 @@ namespace Debugger.AddIn.Pads.Controls } if (e.Key == Key.Enter) { - if(SelectedNode.Node is ExpressionNode) { - var node = (ExpressionNode)SelectedNode.Node; - node.SetText(((TextBox)sender).Text); + if(SelectedNode.Node is ValueNode) { + var node = (ValueNode)SelectedNode.Node; + node.Value = ((TextBox)sender).Text; } } if (e.Key == Key.Enter || e.Key == Key.Escape) { diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs index d1fb38c508..7d3987e18e 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/LocalVarPad.cs @@ -71,7 +71,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads debuggedProcess.EnqueueForEach( Dispatcher.CurrentDispatcher, - Utils.GetLocalVariableNodes(frame).ToList(), + ValueNode.GetLocalVariables().ToList(), n => localVarList.WatchItems.Add(n.ToSharpTreeNode()) ); } catch (Exception ex) { diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs index 99b236f3b1..5669593f99 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/WatchPad.cs @@ -192,7 +192,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads LoggingService.Info("Evaluating: " + (string.IsNullOrEmpty(node.Node.Name) ? "is null or empty!" : node.Node.Name)); //Value val = ExpressionEvaluator.Evaluate(nod.Name, nod.Language, debuggedProcess.SelectedStackFrame); - ExpressionNode valNode = new ExpressionNode(null, node.Node.Name, () => debugger.GetExpression(node.Node.Name).Evaluate(debuggedProcess)); + ValueNode valNode = new ValueNode(null, node.Node.Name, () => debugger.GetExpression(node.Node.Name).Evaluate(debuggedProcess)); return valNode.ToSharpTreeNode(); } catch (GetValueException) { string error = String.Format(StringParser.Parse("${res:MainWindow.Windows.Debug.Watch.InvalidExpression}"), node.Node.Name); diff --git a/src/AddIns/Debugger/Debugger.AddIn/Service/RemotingConfigurationHelpper.cs b/src/AddIns/Debugger/Debugger.AddIn/Service/RemotingConfigurationHelpper.cs deleted file mode 100644 index b77f20be6b..0000000000 --- a/src/AddIns/Debugger/Debugger.AddIn/Service/RemotingConfigurationHelpper.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the BSD license (for details please see \src\AddIns\Debugger\Debugger.AddIn\license.txt) - -using System; -using System.IO; -using System.Reflection; -using System.Runtime.Remoting; -using System.Security.Policy; - -namespace ICSharpCode.SharpDevelop.Services -{ - [Serializable] - class RemotingConfigurationHelpper - { - public string path; - - public RemotingConfigurationHelpper(string path) - { - this.path = path; - } - - public static string GetLoadedAssemblyPath(string assemblyName) - { - string path = null; - foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { - try { - string fullFilename = assembly.Location; - if (Path.GetFileName(fullFilename).Equals(assemblyName, StringComparison.OrdinalIgnoreCase)) { - path = Path.GetDirectoryName(fullFilename); - break; - } - } catch (NotSupportedException) { - // assembly.Location throws NotSupportedException for assemblies emitted using - // Reflection.Emit by custom controls used in the forms designer - } - } - if (path == null) { - throw new Exception("Assembly " + assemblyName + " is not loaded"); - } - return path; - } - - public void Configure() - { - AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; - - RemotingConfiguration.Configure(Path.Combine(path, "Client.config"), false); - - string baseDir = Directory.GetDirectoryRoot(AppDomain.CurrentDomain.BaseDirectory); - string relDirs = AppDomain.CurrentDomain.BaseDirectory + ";" + path; - AppDomain serverAppDomain = AppDomain.CreateDomain("Debugging server", - new Evidence(AppDomain.CurrentDomain.Evidence), - baseDir, - relDirs, - AppDomain.CurrentDomain.ShadowCopyFiles); - serverAppDomain.DoCallBack(new CrossAppDomainDelegate(ConfigureServer)); - } - - private void ConfigureServer() - { - AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; - RemotingConfiguration.Configure(Path.Combine(path, "Server.config"), false); - } - - Assembly AssemblyResolve(object sender, ResolveEventArgs args) - { - foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { - try { - string fullFilename = assembly.Location; - if (Path.GetFileNameWithoutExtension(fullFilename).Equals(args.Name, StringComparison.OrdinalIgnoreCase) || - assembly.FullName == args.Name) { - return assembly; - } - } catch (NotSupportedException) { - // assembly.Location throws NotSupportedException for assemblies emitted using - // Reflection.Emit by custom controls used in the forms designer - } - } - return null; - } - } -} diff --git a/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs b/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs index acf29b606b..f8bfe43bcc 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Service/WindowsDebugger.cs @@ -28,6 +28,7 @@ using ICSharpCode.SharpDevelop.Gui.OptionPanels; using ICSharpCode.SharpDevelop.Project; using Mono.Cecil; using Process = Debugger.Process; +using TreeNode = Debugger.AddIn.TreeModel.TreeNode; namespace ICSharpCode.SharpDevelop.Services { @@ -39,7 +40,6 @@ namespace ICSharpCode.SharpDevelop.Services Cancel = 2 } - bool useRemotingForThreadInterop = false; bool attached; NDebugger debugger; @@ -491,18 +491,18 @@ namespace ICSharpCode.SharpDevelop.Services { try { var tooltipExpression = GetExpression(variableName); - ExpressionNode expressionNode = new ExpressionNode("Icons.16x16.Local", variableName, () => tooltipExpression.Evaluate(this.DebuggedProcess)); - return new DebuggerTooltipControl(logicalPosition, expressionNode) { ShowPins = debuggedProcess.GetCurrentExecutingFrame().HasSymbols }; + var valueNode = new ValueNode("Icons.16x16.Local", variableName, () => tooltipExpression.Evaluate(this.DebuggedProcess)); + return new DebuggerTooltipControl(new TreeNode[] { valueNode }); } catch (System.Exception ex) { LoggingService.Error("Error on GetTooltipControl: " + ex.Message); return null; } } - public ITreeNode GetNode(string variable, string currentImageName = null) + public Debugger.AddIn.TreeModel.TreeNode GetNode(string variable, string currentImageName = null) { try { - return new ExpressionNode(currentImageName ?? "Icons.16x16.Local", variable, () => GetExpression(variable).Evaluate(this.DebuggedProcess)); + return new ValueNode(currentImageName ?? "Icons.16x16.Local", variable, () => GetExpression(variable).Evaluate(this.DebuggedProcess)); } catch (GetValueException) { return null; } @@ -539,12 +539,6 @@ namespace ICSharpCode.SharpDevelop.Services public void InitializeService() { - if (useRemotingForThreadInterop) { - // This needs to be called before instance of NDebugger is created - string path = RemotingConfigurationHelpper.GetLoadedAssemblyPath("Debugger.Core.dll"); - new RemotingConfigurationHelpper(path).Configure(); - } - // get decompiler service var items = AddInTree.BuildItems("/SharpDevelop/Services/DebuggerDecompilerService", null, false); if (items.Count > 0) diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerPopup.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerPopup.cs deleted file mode 100644 index acf3663258..0000000000 --- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerPopup.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls.Primitives; -using System.Windows.Input; - -using ICSharpCode.Core; -using ICSharpCode.NRefactory; -using ICSharpCode.SharpDevelop.Debugging; -using ICSharpCode.SharpDevelop.Gui; - -namespace Debugger.AddIn.Tooltips -{ - /// - /// Popup containing . - /// - public class DebuggerPopup : Popup - { - internal DebuggerTooltipControl innerControl; - - public DebuggerPopup(DebuggerTooltipControl parentControl, Location logicalPosition, bool showPins = true) - { - this.innerControl = new DebuggerTooltipControl(parentControl, logicalPosition) { ShowPins = showPins }; - this.innerControl.containingPopup = this; - this.Child = this.innerControl; - this.IsLeaf = false; - - //this.KeyDown += new KeyEventHandler(DebuggerPopup_KeyDown); - - //this.innerControl.Focusable = true; - //Keyboard.Focus(this.innerControl); - //this.AllowsTransparency = true; - //this.PopupAnimation = PopupAnimation.Slide; - } - - // attempt to propagate shortcuts to main windows when Popup is focusable (needed for keyboard scrolling + editing) - /*void DebuggerPopup_KeyDown(object sender, KeyEventArgs e) - { - LoggingService.Debug("Unhandled popup key down: " + e.Key); - RaiseEventPair(WorkbenchSingleton.MainWindow, PreviewKeyDownEvent, KeyDownEvent, - new KeyEventArgs(e.KeyboardDevice, e.InputSource, e.Timestamp, e.Key)); - } - - // copied from CompletionWindowBase - static bool RaiseEventPair(UIElement target, RoutedEvent previewEvent, RoutedEvent @event, RoutedEventArgs args) - { - if (target == null) - throw new ArgumentNullException("target"); - if (previewEvent == null) - throw new ArgumentNullException("previewEvent"); - if (@event == null) - throw new ArgumentNullException("event"); - if (args == null) - throw new ArgumentNullException("args"); - args.RoutedEvent = previewEvent; - target.RaiseEvent(args); - args.RoutedEvent = @event; - target.RaiseEvent(args); - return args.Handled; - }*/ - - public IEnumerable ItemsSource - { - get { return this.innerControl.ItemsSource; } - set { this.innerControl.SetItemsSource(value); } - } - - private bool isLeaf; - public bool IsLeaf - { - get { return isLeaf; } - set - { - isLeaf = value; - // leaf popup closes on lost focus - this.StaysOpen = !isLeaf; - } - } - - protected override void OnClosed(EventArgs e) - { - base.OnClosed(e); - if (isLeaf) { - this.innerControl.CloseOnLostFocus(); - } - } - - public void Open() - { - this.IsOpen = true; - } - - public void CloseSelfAndChildren() - { - this.innerControl.CloseChildPopups(); - this.IsOpen = false; - } - } -} \ No newline at end of file diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml index b28e746732..1ad63cf46b 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml +++ b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml @@ -1,29 +1,123 @@ - - - + xmlns:debugging="clr-namespace:Debugger.AddIn.Tooltips" + AllowsTransparency="True" +> + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - - - - + + + + + - - + - - - + + + Margin="0" + Focusable="False" + Width="19" + Height="13" + > + + + + + + + + + + + + + + + + + + + + + + + - - + + @@ -133,24 +225,16 @@ - + - - + + - - + + @@ -159,82 +243,48 @@ - + - - + + - - + + + Text="{Binding Value}" + > - + - - - - - - - - - - - - - - + - \ No newline at end of file + \ No newline at end of file diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml.cs index 62f76b5141..9785ef6763 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/DebuggerTooltipControl.xaml.cs @@ -3,426 +3,117 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; -using System.Windows.Documents; +using System.Windows.Data; using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Animation; -using System.Windows.Shapes; + using Debugger.AddIn.TreeModel; -using ICSharpCode.Core; -using ICSharpCode.NRefactory; using ICSharpCode.SharpDevelop; -using ICSharpCode.SharpDevelop.Bookmarks; -using ICSharpCode.SharpDevelop.Debugging; using ICSharpCode.SharpDevelop.Editor; -using ICSharpCode.SharpDevelop.Gui; namespace Debugger.AddIn.Tooltips { - /// - /// Default Control used as content of SharpDevelop debugger tooltips. - /// - public partial class DebuggerTooltipControl : UserControl, ITooltip + public partial class DebuggerTooltipControl : Popup, ITooltip { - private const double ChildPopupOpenXOffet = 16; - private const double ChildPopupOpenYOffet = 15; - private const int InitialItemsCount = 12; - private const int VisibleItemsCount = 11; + static Point ChildPopupOffset = new Point(16, 15); - private bool showPins = true; - private LazyItemsControl lazyGrid; - private IEnumerable itemsSource; - readonly Location logicalPosition; + public DebuggerTooltipControl ChildTooltip { get; private set; } + public IEnumerable TreeNodes { get; set; } - public DebuggerTooltipControl(Location logicalPosition) + public DebuggerTooltipControl(IEnumerable treeNodes) { - this.logicalPosition = logicalPosition; InitializeComponent(); - Loaded += new RoutedEventHandler(OnLoaded); - } - - public DebuggerTooltipControl(Location logicalPosition, ITreeNode node) - : this(logicalPosition, new ITreeNode[] { node }) - { + this.TreeNodes = treeNodes; + this.dataGrid.ItemsSource = treeNodes; - } - - public DebuggerTooltipControl(Location logicalPosition, IEnumerable nodes) - : this(logicalPosition) - { - this.itemsSource = nodes; - } - - public DebuggerTooltipControl(DebuggerTooltipControl parentControl, Location logicalPosition) - : this(logicalPosition) - { - this.parentControl = parentControl; + // Only the leaf of the tooltip has this set to false + // Therefore it will automatically close if something else gets focus + this.StaysOpen = false; + this.Placement = PlacementMode.Absolute; } - private void OnLoaded(object sender, RoutedEventArgs e) - { - if (!showPins) { - dataGrid.Columns[5].Visibility = Visibility.Collapsed; - } - - SetItemsSource(this.itemsSource); - } - - public event RoutedEventHandler Closed; - protected void OnClosed() + private void Expand_Click(object sender, RoutedEventArgs e) { - if (this.Closed != null) { - this.Closed(this, new RoutedEventArgs()); - } - } - - public bool ShowPins { - get { return showPins; } - set { showPins = value; } - } - - public IEnumerable ItemsSource { - get { return this.itemsSource; } - } - - public void SetItemsSource(IEnumerable value) { - this.itemsSource = value; - this.lazyGrid = new LazyItemsControl(this.dataGrid, InitialItemsCount); - - // HACK for updating the pins in tooltip - var observable = new List(); - this.itemsSource.ForEach(item => observable.Add(item)); - - // verify if at the line of the root there's a pin bookmark - ITextEditor editor; - var viewContent = WorkbenchSingleton.Workbench.ActiveViewContent; - ITextEditorProvider provider = viewContent as ITextEditorProvider; - if (provider != null) { - editor = provider.TextEditor; - } else { - editor = viewContent.GetService(typeof(ITextEditor)) as ITextEditor; - } + var clickedButton = (ToggleButton)e.OriginalSource; + var clickedNode = (TreeNode)clickedButton.DataContext; - if (editor != null) { - var pin = BookmarkManager.Bookmarks.Find( - b => b is PinBookmark && - b.Location.Line == logicalPosition.Line && - b.FileName == editor.FileName) as PinBookmark; + if (clickedButton.IsChecked == true && clickedNode.GetChildren != null) { + Point popupPos = clickedButton.PointToScreen(ChildPopupOffset).TransformFromDevice(clickedButton); + this.ChildTooltip = new DebuggerTooltipControl(clickedNode.GetChildren().ToList()) { + // We can not use placement target otherwise we would get too deep logical tree + Placement = PlacementMode.Absolute, + HorizontalOffset = popupPos.X, + VerticalOffset = popupPos.Y, + }; - if (pin != null) { - observable.ForEach(item => { // TODO: find a way not to use "observable" - if (pin.ContainsNode(item)) - item.IsPinned = true; - }); - } - } - - var source = new VirtualizingIEnumerable(observable); - lazyGrid.ItemsSource = source; - this.dataGrid.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(handleScroll)); - - if (this.lazyGrid.ItemsSourceTotalCount != null) { - // hide up/down buttons if too few items - btnUp.Visibility = btnDown.Visibility = - this.lazyGrid.ItemsSourceTotalCount.Value <= VisibleItemsCount ? Visibility.Collapsed : Visibility.Visible; + // The child is now tracking the focus + this.StaysOpen = true; + this.ChildTooltip.StaysOpen = false; + + this.ChildTooltip.Closed += delegate { + // The null will have the effect of ignoring the next click + clickedButton.IsChecked = clickedButton.IsMouseOver ? (bool?)null : false; + // Either keep closing or make us the new leaf + if (this.IsMouseOver) { + this.StaysOpen = false; + } else { + this.IsOpen = false; + } + }; + this.ChildTooltip.IsOpen = true; } } - //public Location LogicalPosition { get; set; } - - /// - public bool ShowAsPopup - { - get - { - return true; - } - } - - /// - public bool Close(bool mouseClick) - { - if (mouseClick || (!mouseClick && !isChildExpanded)) { - CloseChildPopups(); - return true; - } else { - return false; - } - } - - private DebuggerPopup childPopup { get; set; } - private DebuggerTooltipControl parentControl { get; set; } - internal DebuggerPopup containingPopup { get; set; } - - bool isChildExpanded - { - get - { - return this.childPopup != null && this.childPopup.IsOpen; - } - } - - private ToggleButton expandedButton; - - /// - /// Closes the child popup of this control, if it exists. - /// - public void CloseChildPopups() - { - if (this.expandedButton != null) { - this.expandedButton.IsChecked = false; - this.expandedButton = null; - // nice simple example of indirect recursion - this.childPopup.CloseSelfAndChildren(); - } - } - - public void CloseOnLostFocus() - { - // when we close, parent becomes leaf - if (this.containingPopup != null) { - this.containingPopup.IsLeaf = true; - } - if (!this.IsMouseOver) { - if (this.containingPopup != null) { - this.containingPopup.IsOpen = false; - this.containingPopup.IsLeaf = false; - } - if (this.parentControl != null) { - this.parentControl.CloseOnLostFocus(); - } - OnClosed(); - } else { - // leaf closed because of click inside this control - stop the closing chain - if (this.expandedButton != null && !this.expandedButton.IsMouseOver) { - this.expandedButton.IsChecked = false; - this.expandedButton = null; - } + bool ITooltip.CloseOnHoverEnd { + get { + return this.ChildTooltip == null; } } - private void btnExpander_Click(object sender, RoutedEventArgs e) + protected override void OnClosed(EventArgs e) { - var clickedButton = (ToggleButton)e.OriginalSource; - var clickedNode = (ITreeNode)clickedButton.DataContext; - // use device independent units, because child popup Left/Top are in independent units - Point buttonPos = clickedButton.PointToScreen(new Point(0, 0)).TransformFromDevice(clickedButton); - - if (clickedButton.IsChecked.GetValueOrDefault(false)) { - CloseChildPopups(); - this.expandedButton = clickedButton; - - // open child Popup - if (this.childPopup == null) { - this.childPopup = new DebuggerPopup(this, logicalPosition, showPins); - this.childPopup.Placement = PlacementMode.Absolute; - } - if (this.containingPopup != null) { - this.containingPopup.IsLeaf = false; - } - this.childPopup.IsLeaf = true; - this.childPopup.HorizontalOffset = buttonPos.X + ChildPopupOpenXOffet; - this.childPopup.VerticalOffset = buttonPos.Y + ChildPopupOpenYOffet; - if (clickedNode.GetChildren != null) { - this.childPopup.ItemsSource = clickedNode.GetChildren().ToList(); - this.childPopup.Open(); - } - } else { - CloseChildPopups(); + // Closing the popup does not normally cause LostFocus on the textbox so we have to update it manually + TextBox textBox = FocusManager.GetFocusedElement(this) as TextBox; + if (textBox != null) { + BindingExpression be = textBox.GetBindingExpression(TextBox.TextProperty); + be.UpdateSource(); } - } - - private void handleScroll(object sender, ScrollChangedEventArgs e) - { - btnUp.IsEnabled = !this.lazyGrid.IsScrolledToStart; - btnDown.IsEnabled = !this.lazyGrid.IsScrolledToEnd; - } - void BtnUp_Click(object sender, RoutedEventArgs e) - { - this.lazyGrid.ScrollViewer.ScrollUp(1); - } - - void BtnDown_Click(object sender, RoutedEventArgs e) - { - this.lazyGrid.ScrollViewer.ScrollDown(1); - } - - #region Edit value in tooltip - - void TextBox_KeyUp(object sender, KeyEventArgs e) - { - if (e.Key == Key.Escape) { - dataGrid.Focus(); - return; - } + base.OnClosed(e); - if (e.Key == Key.Enter) { - dataGrid.Focus(); - // set new value - var textBox = (TextBox)e.OriginalSource; - var newValue = textBox.Text; - var node = ((FrameworkElement)sender).DataContext as ITreeNode; - SaveNewValue(node, textBox.Text); - } - } - - void TextBox_LostFocus(object sender, RoutedEventArgs e) - { - var textBox = (TextBox)e.OriginalSource; - var newValue = textBox.Text; - var node = ((FrameworkElement)sender).DataContext as ITreeNode; - SaveNewValue(node, textBox.Text); - } - - void SaveNewValue(ITreeNode node, string newValue) - { - if(node != null && node.SetText(newValue)) { - // show adorner - var adornerLayer = AdornerLayer.GetAdornerLayer(dataGrid); - var adorners = adornerLayer.GetAdorners(dataGrid); - if (adorners != null && adorners.Length != 0) - adornerLayer.Remove(adorners[0]); - SavedAdorner adorner = new SavedAdorner(dataGrid); - adornerLayer.Add(adorner); - } - } - - #endregion - - #region Pining checked/unchecked - - void PinButton_Checked(object sender, RoutedEventArgs e) - { - ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider; - var editor = provider.TextEditor; - if (editor == null) return; - var node = (ITreeNode)(((ToggleButton)(e.OriginalSource)).DataContext); - - if (!string.IsNullOrEmpty(editor.FileName)) { - - // verify if at the line of the root there's a pin bookmark - var pin = BookmarkManager.Bookmarks.Find( - b => b is PinBookmark && - b.LineNumber == logicalPosition.Line && - b.FileName == editor.FileName) as PinBookmark; - - if (pin == null) { - pin = new PinBookmark(editor.FileName, logicalPosition); - // show pinned DebuggerPopup - if (pin.Popup == null) { - pin.Popup = new PinDebuggerControl(); - pin.Popup.Mark = pin; - Rect rect = new Rect(this.DesiredSize); - var point = this.PointToScreen(rect.TopRight); - pin.Popup.Location = new Point { X = 500, Y = point.Y - 150 }; - pin.Nodes.Add(node); - pin.Popup.ItemsSource = pin.Nodes; - } - - // do actions - pin.Popup.Open(); - BookmarkManager.AddMark(pin); - } - else - { - if (!pin.ContainsNode(node)) { - pin.Nodes.Add(node); - pin.Popup.ItemsSource = pin.Nodes; - } - } - } - } - - void PinButton_Unchecked(object sender, RoutedEventArgs e) - { - ITextEditorProvider provider = WorkbenchSingleton.Workbench.ActiveViewContent as ITextEditorProvider; - var editor = provider.TextEditor; - if (editor == null) return; - - if (!string.IsNullOrEmpty(editor.FileName)) { - // remove from pinned DebuggerPopup - var pin = BookmarkManager.Bookmarks.Find( - b => b is PinBookmark && - b.LineNumber == logicalPosition.Line && - b.FileName == editor.FileName) as PinBookmark; - if (pin == null) return; - - ToggleButton button = (ToggleButton)e.OriginalSource; - pin.RemoveNode((ITreeNode)button.DataContext); - pin.Popup.ItemsSource = pin.Nodes; - // remove if no more data pins are available - if (pin.Nodes.Count == 0) { - pin.Popup.Close(); - - BookmarkManager.RemoveMark(pin); - } + if (this.ChildTooltip != null) { + this.ChildTooltip.IsOpen = false; } } void CopyMenuItemClick(object sender, RoutedEventArgs e) { - ExpressionNode node = ((MenuItem)sender).DataContext as ExpressionNode; + ValueNode node = ((MenuItem)sender).DataContext as ValueNode; if (node != null) { Clipboard.SetText(node.FullText); } } - #endregion - - #region Saved Adorner - - class SavedAdorner : Adorner + /* + void AnimateCloseControl(bool show) { - public SavedAdorner(UIElement adornedElement) : base(adornedElement) - { - Loaded += delegate { Show(); }; - } + DoubleAnimation animation = new DoubleAnimation(); + animation.From = show ? 0 : 1; + animation.To = show ? 1 : 0; + animation.BeginTime = new TimeSpan(0, 0, show ? 0 : 1); + animation.Duration = new Duration(TimeSpan.FromMilliseconds(500)); + animation.SetValue(Storyboard.TargetProperty, this.PinCloseControl); + animation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(Rectangle.OpacityProperty)); - protected override void OnRender(DrawingContext drawingContext) - { - Rect adornedElementRect = new Rect(this.AdornedElement.DesiredSize); - - // Some arbitrary drawing implements. - var formatedText = new FormattedText(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Debugging.SavedString}"), - CultureInfo.CurrentCulture, - FlowDirection.LeftToRight, - new Typeface(new FontFamily("Arial"), - FontStyles.Normal, - FontWeights.Black, - FontStretches.Expanded), - 8d, - Brushes.Black); - - - drawingContext.DrawText(formatedText, - new Point(adornedElementRect.TopRight.X - formatedText.Width - 2, - adornedElementRect.TopRight.Y)); - } + Storyboard board = new Storyboard(); + board.Children.Add(animation); - private void Show() - { - DoubleAnimation animation = new DoubleAnimation(); - animation.From = 1; - animation.To = 0; - - animation.Duration = new Duration(TimeSpan.FromSeconds(2)); - animation.SetValue(Storyboard.TargetProperty, this); - animation.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath(Rectangle.OpacityProperty)); - - Storyboard board = new Storyboard(); - board.Children.Add(animation); - - board.Begin(this); - } + board.Begin(this); } - - #endregion + */ } } \ No newline at end of file diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/LazyItemsControl.cs b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/LazyItemsControl.cs deleted file mode 100644 index f4af8a0aa7..0000000000 --- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/LazyItemsControl.cs +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System; -using System.Collections.Generic; -using System.Windows.Controls; - -using ICSharpCode.SharpDevelop; - -namespace Debugger.AddIn.Tooltips -{ - /// - /// ItemsControl wrapper that takes VirtualizingIEnumerable as source, - /// and adds additional items from the source to underlying ItemsControl when scrolled to bottom. - /// - public class LazyItemsControl - { - private ItemsControl itemsControl; - private int initialItemsCount; - - /// - /// Creates new instance of LazyItemsControl. - /// - /// ItemsControl to wrap and add items to it when scrolled to bottom. - /// Number of items to be initially displayed in wrapped ItemsControl. - public LazyItemsControl(ItemsControl wrappedItemsControl, int initialItemsCount) - { - if (wrappedItemsControl == null) - throw new ArgumentNullException("wrappedItemsControl"); - - this.initialItemsCount = initialItemsCount; - this.itemsControl = wrappedItemsControl; - this.itemsControl.AddHandler(ScrollViewer.ScrollChangedEvent, new ScrollChangedEventHandler(handleScroll)); - } - - private ScrollViewer scrollViewerCached; - public ScrollViewer ScrollViewer - { - get - { - if (this.scrollViewerCached == null) - this.scrollViewerCached = this.itemsControl.GetScrollViewer(); - return this.scrollViewerCached; - } - } - - public bool IsScrolledToStart - { - get - { - if (ScrollViewer == null) // Visual tree not initialized yet - return false; - return ScrollViewer.VerticalOffset == 0; - } - } - - public bool IsScrolledToEnd - { - get - { - if (itemsSourceTotalCount == null) { - // not scrolled to end of IEnumerable yet - return false; - } - // already scrolled to end of IEnumerable - int totalItems = itemsSourceTotalCount.Value; - return (ScrollViewer.VerticalOffset >= totalItems - ScrollViewer.ViewportHeight); - } - } - - private int? itemsSourceTotalCount = null; - /// Items count of underlying IEnumerable. Null until scrolled to the end of IEnumerable. - public int? ItemsSourceTotalCount - { - get - { - return this.itemsSourceTotalCount; - } - } - - private VirtualizingIEnumerable itemsSource; - /// The collection that underlying ItemsControl sees. - public VirtualizingIEnumerable ItemsSource - { - get { return itemsSource; } - set - { - this.itemsSource = value; - addNextItems(this.itemsSource, initialItemsCount); - this.itemsControl.ItemsSource = value; - } - } - - private void addNextItems(VirtualizingIEnumerable sourceToAdd, int nItems) - { - sourceToAdd.AddNextItems(nItems); - if (!sourceToAdd.HasNext) { - // all items from IEnumerable have been added - this.itemsSourceTotalCount = sourceToAdd.Count; - } - } - - private void handleScroll(object sender, ScrollChangedEventArgs e) - { - if (e.VerticalChange > 0) { - // scrolled to bottom - if (e.VerticalOffset >= this.itemsSource.Count - e.ViewportHeight) { - addNextItems(this.itemsSource, (int)e.VerticalChange); - } - } - } - } -} diff --git a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinCloseControl.xaml b/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinCloseControl.xaml deleted file mode 100644 index c2fc077e1e..0000000000 --- a/src/AddIns/Debugger/Debugger.AddIn/Tooltips/PinCloseControl.xaml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - -