|
|
@ -2,11 +2,10 @@ |
|
|
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
|
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
|
|
|
|
|
|
|
|
|
|
|
using System; |
|
|
|
using System; |
|
|
|
using System.Linq; |
|
|
|
|
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Collections.ObjectModel; |
|
|
|
using System.Collections.ObjectModel; |
|
|
|
using System.Diagnostics; |
|
|
|
|
|
|
|
using System.Globalization; |
|
|
|
using System.Globalization; |
|
|
|
|
|
|
|
using System.Linq; |
|
|
|
using System.Windows; |
|
|
|
using System.Windows; |
|
|
|
using System.Windows.Controls; |
|
|
|
using System.Windows.Controls; |
|
|
|
using System.Windows.Documents; |
|
|
|
using System.Windows.Documents; |
|
|
@ -55,8 +54,8 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
get { return selectedEndIndex; } |
|
|
|
get { return selectedEndIndex; } |
|
|
|
set { |
|
|
|
set { |
|
|
|
selectedEndIndex = value; |
|
|
|
selectedEndIndex = value; |
|
|
|
this.InvalidateMeasure(); |
|
|
|
InvalidateMeasure(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
InvalidateVisual(); |
|
|
|
OnRangeChanged(new RangeEventArgs(selectedStartIndex, selectedEndIndex)); |
|
|
|
OnRangeChanged(new RangeEventArgs(selectedStartIndex, selectedEndIndex)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -66,8 +65,8 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
get { return selectedStartIndex; } |
|
|
|
get { return selectedStartIndex; } |
|
|
|
set { |
|
|
|
set { |
|
|
|
selectedStartIndex = value; |
|
|
|
selectedStartIndex = value; |
|
|
|
this.InvalidateMeasure(); |
|
|
|
InvalidateMeasure(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
InvalidateVisual(); |
|
|
|
OnRangeChanged(new RangeEventArgs(selectedStartIndex, selectedEndIndex)); |
|
|
|
OnRangeChanged(new RangeEventArgs(selectedStartIndex, selectedEndIndex)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -85,9 +84,9 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
|
|
|
|
|
|
|
|
protected override Size MeasureOverride(Size availableSize) |
|
|
|
protected override Size MeasureOverride(Size availableSize) |
|
|
|
{ |
|
|
|
{ |
|
|
|
this.pieceWidth = 25; |
|
|
|
pieceWidth = 25; |
|
|
|
Size calculatedSize = base.MeasureOverride(availableSize); |
|
|
|
Size calculatedSize = base.MeasureOverride(availableSize); |
|
|
|
return new Size(Math.Max(this.pieceWidth * this.valuesList.Count + 1, calculatedSize.Width), calculatedSize.Height + 10); |
|
|
|
return new Size(Math.Max(pieceWidth * valuesList.Count + 1, calculatedSize.Width), calculatedSize.Height + 10); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const int offset = 0; |
|
|
|
const int offset = 0; |
|
|
@ -97,26 +96,26 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
{ |
|
|
|
{ |
|
|
|
base.OnRender(drawingContext); |
|
|
|
base.OnRender(drawingContext); |
|
|
|
|
|
|
|
|
|
|
|
if (this.valuesList.Count == 0) |
|
|
|
if (valuesList.Count == 0) |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
double oldX = offsetFromTop, oldY = this.RenderSize.Height; |
|
|
|
double oldX = offsetFromTop, oldY = RenderSize.Height; |
|
|
|
|
|
|
|
|
|
|
|
StreamGeometry geometry = new StreamGeometry(); |
|
|
|
StreamGeometry geometry = new StreamGeometry(); |
|
|
|
|
|
|
|
|
|
|
|
using (StreamGeometryContext ctx = geometry.Open()) |
|
|
|
using (StreamGeometryContext ctx = geometry.Open()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ctx.BeginFigure(new Point(0, this.RenderSize.Height), true, true); |
|
|
|
ctx.BeginFigure(new Point(0, RenderSize.Height), true, true); |
|
|
|
|
|
|
|
|
|
|
|
List<Point> points = new List<Point>(); |
|
|
|
List<Point> points = new List<Point>(); |
|
|
|
|
|
|
|
|
|
|
|
double maxHeight = this.RenderSize.Height - offsetFromTop; |
|
|
|
double maxHeight = RenderSize.Height - offsetFromTop; |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < this.valuesList.Count; i++) |
|
|
|
for (int i = 0; i < valuesList.Count; i++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
double x = this.pieceWidth / 2.0 + this.pieceWidth * i; |
|
|
|
double x = pieceWidth / 2.0 + pieceWidth * i; |
|
|
|
// TODO : support MinValues other than 0
|
|
|
|
// TODO : support MinValues other than 0
|
|
|
|
double y = offsetFromTop + (maxHeight - maxHeight * (this.valuesList[i].Value / this.MaxValue)); |
|
|
|
double y = offsetFromTop + (maxHeight - maxHeight * (valuesList[i].Value / MaxValue)); |
|
|
|
|
|
|
|
|
|
|
|
points.Add(new Point(x, y)); |
|
|
|
points.Add(new Point(x, y)); |
|
|
|
|
|
|
|
|
|
|
@ -124,7 +123,7 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
oldY = y; |
|
|
|
oldY = y; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
points.Add(new Point(oldX, offsetFromTop + this.RenderSize.Height)); |
|
|
|
points.Add(new Point(oldX, offsetFromTop + RenderSize.Height)); |
|
|
|
|
|
|
|
|
|
|
|
ctx.PolyLineTo(points, true, true); |
|
|
|
ctx.PolyLineTo(points, true, true); |
|
|
|
} |
|
|
|
} |
|
|
@ -133,7 +132,7 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
|
|
|
|
|
|
|
|
Brush b = new LinearGradientBrush(Colors.Red, Colors.Orange, 90); |
|
|
|
Brush b = new LinearGradientBrush(Colors.Red, Colors.Orange, 90); |
|
|
|
|
|
|
|
|
|
|
|
drawingContext.DrawRectangle(Brushes.White, new Pen(Brushes.White, 1), new Rect(new Point(0, 0), this.RenderSize)); |
|
|
|
drawingContext.DrawRectangle(Brushes.White, new Pen(Brushes.White, 1), new Rect(new Point(0, 0), RenderSize)); |
|
|
|
|
|
|
|
|
|
|
|
var p = new Pen(Brushes.DarkRed, 2); |
|
|
|
var p = new Pen(Brushes.DarkRed, 2); |
|
|
|
|
|
|
|
|
|
|
@ -141,10 +140,10 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
|
|
|
|
|
|
|
|
DateTime time = new DateTime(1,1,1,0,0,0,0); |
|
|
|
DateTime time = new DateTime(1,1,1,0,0,0,0); |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < this.valuesList.Count; i++) { |
|
|
|
for (int i = 0; i < valuesList.Count; i++) { |
|
|
|
if (this.valuesList[i].DisplayMarker) |
|
|
|
if (valuesList[i].DisplayMarker) |
|
|
|
drawingContext.DrawLine(p, new Point(pieceWidth * i, offsetFromTop), |
|
|
|
drawingContext.DrawLine(p, new Point(pieceWidth * i, offsetFromTop), |
|
|
|
new Point(pieceWidth * i, this.RenderSize.Height)); |
|
|
|
new Point(pieceWidth * i, RenderSize.Height)); |
|
|
|
|
|
|
|
|
|
|
|
if (i % 3 == 0) { |
|
|
|
if (i % 3 == 0) { |
|
|
|
FormattedText textFormat = new FormattedText( |
|
|
|
FormattedText textFormat = new FormattedText( |
|
|
@ -156,7 +155,7 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
drawingContext.DrawText(textFormat, new Point(pieceWidth * i, 0)); |
|
|
|
drawingContext.DrawText(textFormat, new Point(pieceWidth * i, 0)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var events = this.valuesList[i].Events; |
|
|
|
var events = valuesList[i].Events; |
|
|
|
|
|
|
|
|
|
|
|
if (events != null && events.Length > 0) { |
|
|
|
if (events != null && events.Length > 0) { |
|
|
|
foreach (EventDataEntry @event in events) { |
|
|
|
foreach (EventDataEntry @event in events) { |
|
|
@ -178,43 +177,43 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
new SolidColorBrush(Color.FromArgb(64, Colors.Blue.R, Colors.Blue.G, Colors.Blue.B)), |
|
|
|
new SolidColorBrush(Color.FromArgb(64, Colors.Blue.R, Colors.Blue.G, Colors.Blue.B)), |
|
|
|
new Pen(Brushes.Blue, 1), |
|
|
|
new Pen(Brushes.Blue, 1), |
|
|
|
new Rect( |
|
|
|
new Rect( |
|
|
|
new Point(Math.Min(this.selectedStartIndex, this.selectedEndIndex) * pieceWidth + offset, offsetFromTop), |
|
|
|
new Point(Math.Min(selectedStartIndex, selectedEndIndex) * pieceWidth + offset, offsetFromTop), |
|
|
|
new Point(Math.Max(this.selectedStartIndex, this.selectedEndIndex) * pieceWidth + offset + pieceWidth, this.RenderSize.Height) |
|
|
|
new Point(Math.Max(selectedStartIndex, selectedEndIndex) * pieceWidth + offset + pieceWidth, RenderSize.Height) |
|
|
|
) |
|
|
|
) |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e) |
|
|
|
protected override void OnMouseUp(MouseButtonEventArgs e) |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool valid; |
|
|
|
bool valid; |
|
|
|
Point pos = e.GetPosition(this); |
|
|
|
Point pos = e.GetPosition(this); |
|
|
|
int index = TransformToIndex(pos, out valid); |
|
|
|
int index = TransformToIndex(pos, out valid); |
|
|
|
|
|
|
|
|
|
|
|
if (pos.Y >= 40) { |
|
|
|
if (pos.Y >= 40) { |
|
|
|
if (index < this.selectedStartIndex) { |
|
|
|
if (index < selectedStartIndex) { |
|
|
|
this.selectedEndIndex = this.selectedStartIndex; |
|
|
|
selectedEndIndex = selectedStartIndex; |
|
|
|
this.selectedStartIndex = index; |
|
|
|
selectedStartIndex = index; |
|
|
|
} else |
|
|
|
} else |
|
|
|
this.selectedEndIndex = index; |
|
|
|
selectedEndIndex = index; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.InvalidateMeasure(); |
|
|
|
InvalidateMeasure(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
InvalidateVisual(); |
|
|
|
this.ReleaseMouseCapture(); |
|
|
|
ReleaseMouseCapture(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e) |
|
|
|
protected override void OnMouseDown(MouseButtonEventArgs e) |
|
|
|
{ |
|
|
|
{ |
|
|
|
this.CaptureMouse(); |
|
|
|
CaptureMouse(); |
|
|
|
Point pos = e.GetPosition(this); |
|
|
|
Point pos = e.GetPosition(this); |
|
|
|
bool valid; |
|
|
|
bool valid; |
|
|
|
int index = TransformToIndex(pos, out valid); |
|
|
|
int index = TransformToIndex(pos, out valid); |
|
|
|
|
|
|
|
|
|
|
|
if (pos.Y >= 40) |
|
|
|
if (pos.Y >= 40) |
|
|
|
this.selectedStartIndex = this.selectedEndIndex = index; |
|
|
|
selectedStartIndex = selectedEndIndex = index; |
|
|
|
|
|
|
|
|
|
|
|
this.InvalidateMeasure(); |
|
|
|
InvalidateMeasure(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
InvalidateVisual(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ToolTip tooltip; |
|
|
|
ToolTip tooltip; |
|
|
@ -226,9 +225,9 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
int index = TransformToIndex(pos, out valid); |
|
|
|
int index = TransformToIndex(pos, out valid); |
|
|
|
|
|
|
|
|
|
|
|
if (e.LeftButton == MouseButtonState.Pressed) { |
|
|
|
if (e.LeftButton == MouseButtonState.Pressed) { |
|
|
|
this.selectedEndIndex = index; |
|
|
|
selectedEndIndex = index; |
|
|
|
this.InvalidateMeasure(); |
|
|
|
InvalidateMeasure(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
InvalidateVisual(); |
|
|
|
} else if (tooltip == null && valid) { |
|
|
|
} else if (tooltip == null && valid) { |
|
|
|
tooltip = new ToolTip(); |
|
|
|
tooltip = new ToolTip(); |
|
|
|
if (pos.Y < 20) |
|
|
|
if (pos.Y < 20) |
|
|
@ -236,14 +235,14 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
else if (pos.Y < 40) |
|
|
|
else if (pos.Y < 40) |
|
|
|
tooltip.Content = CreateTooltipForEvents(index); |
|
|
|
tooltip.Content = CreateTooltipForEvents(index); |
|
|
|
else |
|
|
|
else |
|
|
|
tooltip.Content = "Value: " + this.valuesList[index].Value.ToString(this.Format) + " " + this.Unit; |
|
|
|
tooltip.Content = "Value: " + valuesList[index].Value.ToString(Format) + " " + Unit; |
|
|
|
tooltip .IsOpen = tooltip.Content != null; |
|
|
|
tooltip .IsOpen = tooltip.Content != null; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
object CreateTooltipForEvents(int index) |
|
|
|
object CreateTooltipForEvents(int index) |
|
|
|
{ |
|
|
|
{ |
|
|
|
EventDataEntry[] events = this.ValuesList[index].Events; |
|
|
|
EventDataEntry[] events = ValuesList[index].Events; |
|
|
|
|
|
|
|
|
|
|
|
TextBlock block = events.Any() ? new TextBlock() : null; |
|
|
|
TextBlock block = events.Any() ? new TextBlock() : null; |
|
|
|
|
|
|
|
|
|
|
@ -281,14 +280,14 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
protected override void OnLostMouseCapture(MouseEventArgs e) |
|
|
|
protected override void OnLostMouseCapture(MouseEventArgs e) |
|
|
|
{ |
|
|
|
{ |
|
|
|
base.OnLostMouseCapture(e); |
|
|
|
base.OnLostMouseCapture(e); |
|
|
|
OnRangeChanged(new RangeEventArgs(this.selectedStartIndex, this.selectedEndIndex)); |
|
|
|
OnRangeChanged(new RangeEventArgs(selectedStartIndex, selectedEndIndex)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int TransformToIndex(Point point, out bool valid) |
|
|
|
int TransformToIndex(Point point, out bool valid) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int value = (int)Math.Floor(point.X / this.pieceWidth); |
|
|
|
int value = (int)Math.Floor(point.X / pieceWidth); |
|
|
|
valid = (0 >= value && value <= this.valuesList.Count - 1); |
|
|
|
valid = (0 >= value && value <= valuesList.Count - 1); |
|
|
|
return Math.Min(Math.Max(0, value), this.valuesList.Count - 1); |
|
|
|
return Math.Min(Math.Max(0, value), valuesList.Count - 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#region MouseHover
|
|
|
|
#region MouseHover
|
|
|
@ -339,7 +338,7 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
mouseHoverStartPoint = newPosition; |
|
|
|
mouseHoverStartPoint = newPosition; |
|
|
|
mouseHoverLastEventArgs = e; |
|
|
|
mouseHoverLastEventArgs = e; |
|
|
|
mouseHoverTimer = new DispatcherTimer(SystemParameters.MouseHoverTime, DispatcherPriority.Background, |
|
|
|
mouseHoverTimer = new DispatcherTimer(SystemParameters.MouseHoverTime, DispatcherPriority.Background, |
|
|
|
OnMouseHoverTimerElapsed, this.Dispatcher); |
|
|
|
OnMouseHoverTimerElapsed, Dispatcher); |
|
|
|
mouseHoverTimer.Start(); |
|
|
|
mouseHoverTimer.Start(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -362,9 +361,9 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
mouseHoverTimer = null; |
|
|
|
mouseHoverTimer = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (this.tooltip != null) { |
|
|
|
if (tooltip != null) { |
|
|
|
this.tooltip.IsOpen = false; |
|
|
|
tooltip.IsOpen = false; |
|
|
|
this.tooltip = null; |
|
|
|
tooltip = null; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|