Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2311 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
8 changed files with 386 additions and 202 deletions
@ -1,37 +0,0 @@
@@ -1,37 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Forms; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public class DebuggerTreeListView: TreeListView |
||||
{ |
||||
static int updateInterval = 100; // ms
|
||||
|
||||
Timer refreshingTimer; |
||||
|
||||
public DebuggerTreeListView() |
||||
{ |
||||
refreshingTimer = new Timer(); |
||||
refreshingTimer.Interval = updateInterval; |
||||
refreshingTimer.Tick += delegate { |
||||
refreshingTimer.Enabled = false; |
||||
this.EndUpdate(); |
||||
}; |
||||
} |
||||
|
||||
public void DelayRefresh() |
||||
{ |
||||
if (!refreshingTimer.Enabled) { |
||||
this.BeginUpdate(); |
||||
refreshingTimer.Enabled = true; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,88 +0,0 @@
@@ -1,88 +0,0 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Drawing; |
||||
using System.Windows.Forms; |
||||
|
||||
using Debugger; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public class TreeListViewDebuggerItem: TreeListViewItem |
||||
{ |
||||
ListItem listItem; |
||||
|
||||
bool populated = false; |
||||
|
||||
public ListItem ListItem { |
||||
get { |
||||
return listItem; |
||||
} |
||||
} |
||||
|
||||
bool IsVisible { |
||||
get { |
||||
if (this.Parent == null) { |
||||
return true; |
||||
} else { |
||||
foreach(TreeListViewItem parent in this.ParentsInHierarch) { |
||||
if (!parent.IsExpanded) return false; |
||||
} |
||||
return true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public TreeListViewDebuggerItem(NamedValue val): this(new ValueItem(val)) |
||||
{ |
||||
|
||||
} |
||||
|
||||
public TreeListViewDebuggerItem(ListItem listItem) |
||||
{ |
||||
this.listItem = listItem; |
||||
|
||||
listItem.Changed += delegate { Update(); }; |
||||
|
||||
SubItems.Add(""); |
||||
SubItems.Add(""); |
||||
|
||||
Update(); |
||||
} |
||||
|
||||
public void Update() |
||||
{ |
||||
if (!IsVisible) return; |
||||
|
||||
if (this.TreeListView != null) { |
||||
((DebuggerTreeListView)this.TreeListView).DelayRefresh(); |
||||
} |
||||
|
||||
this.ImageIndex = listItem.ImageIndex; |
||||
this.SubItems[0].Text = listItem.Name; |
||||
this.SubItems[1].Text = listItem.Text; |
||||
this.SubItems[2].Text = listItem.Type; |
||||
|
||||
if (!IsExpanded && !populated && listItem.HasSubItems) { |
||||
Items.Add(new TreeListViewItem()); // Show plus sign
|
||||
} |
||||
} |
||||
|
||||
public void Populate() |
||||
{ |
||||
if (!populated) { |
||||
Items.Clear(); |
||||
this.Items.SortOrder = SortOrder.None; |
||||
foreach(ListItem subItem in listItem.SubItems) { |
||||
Items.Add(new TreeListViewDebuggerItem(subItem)); |
||||
} |
||||
populated = true; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace Debugger |
||||
{ |
||||
public class FunctionItem: ListItem |
||||
{ |
||||
Function function; |
||||
|
||||
public Function Function { |
||||
get { |
||||
return function; |
||||
} |
||||
} |
||||
|
||||
public override int ImageIndex { |
||||
get { |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
public override string Name { |
||||
get { |
||||
return function.Name; |
||||
} |
||||
} |
||||
|
||||
public override string Text { |
||||
get { |
||||
return String.Empty; |
||||
} |
||||
} |
||||
|
||||
public override bool CanEditText { |
||||
get { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
public override string Type { |
||||
get { |
||||
return String.Empty; |
||||
} |
||||
} |
||||
|
||||
public override bool HasSubItems { |
||||
get { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
public override IList<ListItem> SubItems { |
||||
get { |
||||
List<ListItem> ret = new List<ListItem>(); |
||||
foreach(NamedValue val in function.LocalVariables) { |
||||
ret.Add(new ValueItem(val)); |
||||
} |
||||
return ret.AsReadOnly(); |
||||
} |
||||
} |
||||
|
||||
public FunctionItem(Function function) |
||||
{ |
||||
this.function = function; |
||||
this.function.Process.DebuggeeStateChanged += delegate { |
||||
this.OnChanged(new ListItemEventArgs(this)); |
||||
}; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,197 @@
@@ -0,0 +1,197 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
using System.Drawing; |
||||
using System.Windows.Forms; |
||||
|
||||
using Aga.Controls.Tree; |
||||
|
||||
using ICSharpCode.Core; |
||||
|
||||
namespace Debugger |
||||
{ |
||||
public partial class TreeViewNode: TreeNodeAdv |
||||
{ |
||||
ListItem content; |
||||
Image icon; |
||||
string name; |
||||
string text; |
||||
bool canEditText; |
||||
string type; |
||||
|
||||
public ListItem Content { |
||||
get { |
||||
return content; |
||||
} |
||||
set { |
||||
if (content != null) { |
||||
content.Changed -= OnContentChanged; |
||||
} |
||||
content = value; |
||||
if (content != null) { |
||||
content.Changed += OnContentChanged; |
||||
} |
||||
Update(); |
||||
} |
||||
} |
||||
|
||||
public Image Icon { |
||||
get { return icon; } |
||||
} |
||||
|
||||
public string Name { |
||||
get { return name; } |
||||
} |
||||
|
||||
public string Text { |
||||
get { return text; } |
||||
} |
||||
|
||||
public bool CanEditText { |
||||
get { return canEditText; } |
||||
} |
||||
|
||||
public string Type { |
||||
get { return type; } |
||||
} |
||||
|
||||
void OnContentChanged(object sender, ListItemEventArgs e) |
||||
{ |
||||
//Update();
|
||||
} |
||||
|
||||
public TreeViewNode(TreeViewAdv tree, ListItem content): base(tree, new object()) |
||||
{ |
||||
this.Content = content; |
||||
} |
||||
|
||||
public void Update() |
||||
{ |
||||
DoApplicationEvents(); |
||||
|
||||
DateTime start = Debugger.Util.HighPrecisionTimer.Now; |
||||
|
||||
this.IsLeaf = !Content.HasSubItems; |
||||
this.icon = content.Image; |
||||
this.name = content.Name; |
||||
this.text = content.Text; |
||||
this.canEditText = content.CanEditText; |
||||
this.type = content.Type; |
||||
//DateTime time = Debugger.Util.HighPrecisionTimer.Now;
|
||||
//this.type = time.ToLongTimeString() + "." + time.Millisecond.ToString();
|
||||
|
||||
DateTime end = Debugger.Util.HighPrecisionTimer.Now; |
||||
|
||||
LoggingService.InfoFormatted("Updated node {0} ({1} ms)", FullName, (end - start).TotalMilliseconds); |
||||
|
||||
if (this.IsExpanded) { |
||||
UpdateNodes(Tree, this.Children, Content.SubItems); |
||||
} else { |
||||
Children.Clear(); |
||||
populated = false; |
||||
} |
||||
|
||||
this.Tree.FullUpdate(); |
||||
} |
||||
|
||||
public static void UpdateNodes(TreeViewAdv tree, Collection<TreeNodeAdv> collection, IList<ListItem> contents) |
||||
{ |
||||
// Add or overwrite existing items
|
||||
for(int i = 0; i < contents.Count; i++) { |
||||
if (i < collection.Count) { |
||||
// Overwrite
|
||||
((TreeViewNode)collection[i]).Content = contents[i]; |
||||
} else { |
||||
// Add
|
||||
collection.Add(new TreeViewNode(tree, contents[i])); |
||||
} |
||||
} |
||||
// Delete other nodes
|
||||
while(collection.Count > contents.Count) { |
||||
collection.RemoveAt(collection.Count - 1); |
||||
} |
||||
|
||||
tree.FullUpdate(); |
||||
} |
||||
|
||||
bool populated = false; |
||||
|
||||
public void OnExpanding() |
||||
{ |
||||
if (!populated) { |
||||
foreach(ListItem item in Content.SubItems) { |
||||
Children.Add(new TreeViewNode(Tree, item)); |
||||
} |
||||
populated = true; |
||||
this.IsExpandedOnce = true; |
||||
this.Tree.UpdateSelection(); |
||||
this.Tree.FullUpdate(); |
||||
} |
||||
} |
||||
|
||||
#region DoApplicationEvents()
|
||||
|
||||
static DateTime nextDoEventsTime = Debugger.Util.HighPrecisionTimer.Now; |
||||
const double workLoad = 0.75; // Fraction of getting variables vs. repainting
|
||||
const double maxFPS = 30; // ms this prevents too much drawing on good machine
|
||||
const double maxWorkTime = 250; // ms this ensures minimal response on bad machine
|
||||
|
||||
void DoApplicationEvents() |
||||
{ |
||||
if (Debugger.Util.HighPrecisionTimer.Now > nextDoEventsTime) { |
||||
DateTime start = Debugger.Util.HighPrecisionTimer.Now; |
||||
Application.DoEvents(); |
||||
DateTime end = Debugger.Util.HighPrecisionTimer.Now; |
||||
double doEventsDuration = (end - start).TotalMilliseconds; |
||||
double minWorkTime = 1000 / maxFPS - doEventsDuration; // ms
|
||||
double workTime = (doEventsDuration / (1 - workLoad)) * workLoad; |
||||
workTime = Math.Max(minWorkTime, Math.Min(maxWorkTime, workTime)); // Clamp
|
||||
nextDoEventsTime = end.AddMilliseconds(workTime); |
||||
double fps = 1000 / (doEventsDuration + workTime); |
||||
LoggingService.InfoFormatted("Rendering: {0} ms => work budget: {1} ms ({2:f1} FPS)", doEventsDuration, workTime, fps); |
||||
} |
||||
} |
||||
|
||||
#endregion
|
||||
|
||||
#region Maintain expanded state
|
||||
|
||||
static Dictionary<string, bool> expandedNodes = new Dictionary<string, bool>(); |
||||
|
||||
string FullName { |
||||
get { |
||||
if (this.Parent != null && this.Parent is TreeViewNode) { |
||||
return ((TreeViewNode)this.Parent).FullName + "." + Content.Name; |
||||
} else { |
||||
return Content.Name; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void OnExpanded() |
||||
{ |
||||
expandedNodes[FullName] = true; |
||||
// Expand children as well
|
||||
foreach(TreeViewNode child in Children) { |
||||
string name = child.FullName; |
||||
if (expandedNodes.ContainsKey(name) && expandedNodes[name]) { |
||||
child.IsExpanded = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public void OnCollapsed() |
||||
{ |
||||
expandedNodes[FullName] = false; |
||||
} |
||||
|
||||
#endregion
|
||||
} |
||||
} |
Loading…
Reference in new issue