|
|
@ -12,18 +12,21 @@ using System.Diagnostics; |
|
|
|
using System.Windows; |
|
|
|
using System.Windows; |
|
|
|
using System.Windows.Controls; |
|
|
|
using System.Windows.Controls; |
|
|
|
using System.Windows.Documents; |
|
|
|
using System.Windows.Documents; |
|
|
|
|
|
|
|
using System.Windows.Input; |
|
|
|
using System.Windows.Media; |
|
|
|
using System.Windows.Media; |
|
|
|
|
|
|
|
using System.Windows.Threading; |
|
|
|
|
|
|
|
|
|
|
|
namespace ICSharpCode.Profiler.Controls |
|
|
|
namespace ICSharpCode.Profiler.Controls |
|
|
|
{ |
|
|
|
{ |
|
|
|
public struct TimeLineInfo { |
|
|
|
public class TimeLineSegment { |
|
|
|
public double value; |
|
|
|
public float Value { get; set; } |
|
|
|
public bool displayMarker; |
|
|
|
public bool DisplayMarker { get; set; } |
|
|
|
|
|
|
|
public long TimeOffset { get; set; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public class TimeLineControl : FrameworkElement |
|
|
|
public class TimeLineControl : FrameworkElement |
|
|
|
{ |
|
|
|
{ |
|
|
|
ObservableCollection<TimeLineInfo> valuesList; |
|
|
|
ObservableCollection<TimeLineSegment> valuesList; |
|
|
|
int selectedStartIndex, selectedEndIndex; |
|
|
|
int selectedStartIndex, selectedEndIndex; |
|
|
|
double pieceWidth; |
|
|
|
double pieceWidth; |
|
|
|
|
|
|
|
|
|
|
@ -37,6 +40,12 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public int SelectedPerformanceCounter { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public float MaxValue { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public string Unit { get; set; } |
|
|
|
|
|
|
|
|
|
|
|
public int SelectedEndIndex |
|
|
|
public int SelectedEndIndex |
|
|
|
{ |
|
|
|
{ |
|
|
|
get { return selectedEndIndex; } |
|
|
|
get { return selectedEndIndex; } |
|
|
@ -59,23 +68,32 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public ObservableCollection<TimeLineInfo> ValuesList |
|
|
|
public ObservableCollection<TimeLineSegment> ValuesList |
|
|
|
{ |
|
|
|
{ |
|
|
|
get { return valuesList; } |
|
|
|
get { return valuesList; } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public TimeLineControl() |
|
|
|
public TimeLineControl() |
|
|
|
{ |
|
|
|
{ |
|
|
|
this.valuesList = new ObservableCollection<TimeLineInfo>(); |
|
|
|
this.valuesList = new ObservableCollection<TimeLineSegment>(); |
|
|
|
this.valuesList.CollectionChanged += delegate { this.InvalidateMeasure(); this.InvalidateVisual(); }; |
|
|
|
this.valuesList.CollectionChanged += delegate { this.InvalidateMeasure(); this.InvalidateVisual(); }; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override Size MeasureOverride(Size availableSize) |
|
|
|
protected override Size MeasureOverride(Size availableSize) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return new Size(1, base.MeasureOverride(availableSize).Height + 10); |
|
|
|
this.pieceWidth = 25; |
|
|
|
|
|
|
|
Size calculatedSize = base.MeasureOverride(availableSize); |
|
|
|
|
|
|
|
return new Size(Math.Max(this.pieceWidth * this.valuesList.Count + 1, calculatedSize.Width), calculatedSize.Height + 10); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected override void OnToolTipOpening(ToolTipEventArgs e) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Console.WriteLine("tooltip"); |
|
|
|
|
|
|
|
base.OnToolTipOpening(e); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const int offset = 15; |
|
|
|
const int offset = 0; |
|
|
|
|
|
|
|
const int offsetFromTop = 40; |
|
|
|
|
|
|
|
|
|
|
|
protected override void OnRender(DrawingContext drawingContext) |
|
|
|
protected override void OnRender(DrawingContext drawingContext) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -84,22 +102,22 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
if (this.valuesList.Count == 0) |
|
|
|
if (this.valuesList.Count == 0) |
|
|
|
return; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
this.pieceWidth = (this.RenderSize.Width - offset) / (double)this.valuesList.Count; |
|
|
|
double oldX = offsetFromTop, oldY = this.RenderSize.Height; |
|
|
|
|
|
|
|
|
|
|
|
double oldX = 0, oldY = this.RenderSize.Height - offset; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StreamGeometry geometry = new StreamGeometry(); |
|
|
|
StreamGeometry geometry = new StreamGeometry(); |
|
|
|
|
|
|
|
|
|
|
|
using (StreamGeometryContext ctx = geometry.Open()) |
|
|
|
using (StreamGeometryContext ctx = geometry.Open()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ctx.BeginFigure(new Point(offset, this.RenderSize.Height - offset), true, true); |
|
|
|
ctx.BeginFigure(new Point(0, this.RenderSize.Height), true, true); |
|
|
|
|
|
|
|
|
|
|
|
List<Point> points = new List<Point>(); |
|
|
|
List<Point> points = new List<Point>(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
double maxHeight = this.RenderSize.Height - offsetFromTop; |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < this.valuesList.Count; i++) |
|
|
|
for (int i = 0; i < this.valuesList.Count; i++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
double x = this.pieceWidth / 2.0 + this.pieceWidth * i + offset; |
|
|
|
double x = this.pieceWidth / 2.0 + this.pieceWidth * i; |
|
|
|
double y = this.RenderSize.Height - this.valuesList[i].value * (this.RenderSize.Height - offset) - offset; |
|
|
|
double y = offsetFromTop + (maxHeight - maxHeight * (this.valuesList[i].Value / this.MaxValue)); |
|
|
|
|
|
|
|
|
|
|
|
points.Add(new Point(x, y)); |
|
|
|
points.Add(new Point(x, y)); |
|
|
|
|
|
|
|
|
|
|
@ -107,7 +125,7 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
oldY = y; |
|
|
|
oldY = y; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
points.Add(new Point(oldX, this.RenderSize.Height - offset)); |
|
|
|
points.Add(new Point(oldX, offsetFromTop + this.RenderSize.Height)); |
|
|
|
|
|
|
|
|
|
|
|
ctx.PolyLineTo(points, true, true); |
|
|
|
ctx.PolyLineTo(points, true, true); |
|
|
|
} |
|
|
|
} |
|
|
@ -116,51 +134,41 @@ 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, offsetFromTop), this.RenderSize)); |
|
|
|
drawingContext.DrawLine(new Pen(Brushes.Black, 1), new Point(offset / 2, this.RenderSize.Height - offset / 2), new Point(this.RenderSize.Width - offset, this.RenderSize.Height - offset / 2)); |
|
|
|
|
|
|
|
drawingContext.DrawLine(new Pen(Brushes.Black, 1), new Point(offset / 2, 0), new Point(offset / 2, this.RenderSize.Height - offset / 2)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var p = new Pen(Brushes.DarkRed, 2); |
|
|
|
var p = new Pen(Brushes.DarkRed, 2); |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < this.valuesList.Count; i++) { |
|
|
|
|
|
|
|
drawingContext.DrawLine(new Pen(Brushes.Black, 1), |
|
|
|
|
|
|
|
new Point(offset + pieceWidth / 2 + pieceWidth * i, this.RenderSize.Height - offset / 4), |
|
|
|
|
|
|
|
new Point(offset + pieceWidth / 2 + pieceWidth * i, this.RenderSize.Height - (offset / 4 * 3 + 3))); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.valuesList[i].displayMarker) { |
|
|
|
|
|
|
|
drawingContext.DrawLine(p, new Point(offset + pieceWidth * i, 0), |
|
|
|
|
|
|
|
new Point(offset + pieceWidth * i, this.RenderSize.Height - offset)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
drawingContext.DrawGeometry(b, new Pen(b, 3), geometry); |
|
|
|
drawingContext.DrawGeometry(b, new Pen(b, 3), geometry); |
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < this.valuesList.Count; i++) { |
|
|
|
for (int i = 0; i < this.valuesList.Count; i++) { |
|
|
|
if (this.valuesList[i].displayMarker) |
|
|
|
if (this.valuesList[i].DisplayMarker) |
|
|
|
drawingContext.DrawLine(p, new Point(offset + pieceWidth * i, 0), |
|
|
|
drawingContext.DrawLine(p, new Point(pieceWidth * i, offsetFromTop), |
|
|
|
new Point(offset + pieceWidth * i, this.RenderSize.Height - offset)); |
|
|
|
new Point(pieceWidth * i, this.RenderSize.Height)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
drawingContext.DrawRectangle( |
|
|
|
drawingContext.DrawRectangle( |
|
|
|
new SolidColorBrush(Color.FromArgb(64, Colors.CornflowerBlue.R, |
|
|
|
new SolidColorBrush(Color.FromArgb(64, Colors.Blue.R, Colors.Blue.G, Colors.Blue.B)), |
|
|
|
Colors.CornflowerBlue.G, Colors.CornflowerBlue.B)), |
|
|
|
|
|
|
|
new Pen(Brushes.Blue, 1), |
|
|
|
new Pen(Brushes.Blue, 1), |
|
|
|
new Rect( |
|
|
|
new Rect( |
|
|
|
new Point(this.selectedStartIndex * this.pieceWidth + offset, 0), |
|
|
|
new Point(Math.Min(this.selectedStartIndex, this.selectedEndIndex) * pieceWidth + offset, 0), |
|
|
|
new Point(this.selectedEndIndex * this.pieceWidth + offset, this.RenderSize.Height - offset) |
|
|
|
new Point(Math.Max(this.selectedStartIndex, this.selectedEndIndex) * pieceWidth + offset + pieceWidth, this.RenderSize.Height - offset) |
|
|
|
) |
|
|
|
) |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e) |
|
|
|
protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e) |
|
|
|
{ |
|
|
|
{ |
|
|
|
int index = TransformToIndex(e.GetPosition(this)); |
|
|
|
bool valid; |
|
|
|
index = (index < 0) ? 0 : index; |
|
|
|
int index = TransformToIndex(e.GetPosition(this), out valid); |
|
|
|
index = (index > this.valuesList.Count) ? this.valuesList.Count : index; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (index < this.selectedStartIndex) { |
|
|
|
|
|
|
|
this.selectedEndIndex = this.selectedStartIndex; |
|
|
|
|
|
|
|
this.selectedStartIndex = index; |
|
|
|
|
|
|
|
} else |
|
|
|
this.selectedEndIndex = index; |
|
|
|
this.selectedEndIndex = index; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("start: {0} end: {1} count: {2}", SelectedStartIndex, SelectedEndIndex, valuesList.Count); |
|
|
|
|
|
|
|
|
|
|
|
this.InvalidateMeasure(); |
|
|
|
this.InvalidateMeasure(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
this.ReleaseMouseCapture(); |
|
|
|
this.ReleaseMouseCapture(); |
|
|
@ -169,43 +177,128 @@ namespace ICSharpCode.Profiler.Controls |
|
|
|
protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e) |
|
|
|
protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e) |
|
|
|
{ |
|
|
|
{ |
|
|
|
this.CaptureMouse(); |
|
|
|
this.CaptureMouse(); |
|
|
|
|
|
|
|
bool valid; |
|
|
|
int index = TransformToIndex(e.GetPosition(this)); |
|
|
|
int index = TransformToIndex(e.GetPosition(this), out valid); |
|
|
|
index = (index < 0) ? 0 : index; |
|
|
|
|
|
|
|
index = (index > this.valuesList.Count) ? this.valuesList.Count : index; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.selectedStartIndex = this.selectedEndIndex = index; |
|
|
|
this.selectedStartIndex = this.selectedEndIndex = index; |
|
|
|
|
|
|
|
|
|
|
|
this.InvalidateMeasure(); |
|
|
|
this.InvalidateMeasure(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e) |
|
|
|
ToolTip tooltip; |
|
|
|
{ |
|
|
|
|
|
|
|
int index = TransformToIndex(e.GetPosition(this)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
index = (index < 0) ? 0 : index; |
|
|
|
|
|
|
|
index = (index > this.valuesList.Count) ? this.valuesList.Count : index; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed) |
|
|
|
void HandleMovement(MouseEventArgs e) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
bool valid; |
|
|
|
|
|
|
|
int index = TransformToIndex(e.GetPosition(this), out valid); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (e.LeftButton == MouseButtonState.Pressed) { |
|
|
|
this.selectedEndIndex = index; |
|
|
|
this.selectedEndIndex = index; |
|
|
|
this.InvalidateMeasure(); |
|
|
|
this.InvalidateMeasure(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
this.InvalidateVisual(); |
|
|
|
|
|
|
|
} else if (tooltip == null && valid) { |
|
|
|
|
|
|
|
tooltip = new ToolTip(); |
|
|
|
|
|
|
|
tooltip.Content = "Value: " + this.valuesList[index].Value.ToString("0.00") + " " + this.Unit; |
|
|
|
|
|
|
|
tooltip .IsOpen = true; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected override void OnLostMouseCapture(System.Windows.Input.MouseEventArgs e) |
|
|
|
protected override void OnLostMouseCapture(MouseEventArgs e) |
|
|
|
{ |
|
|
|
{ |
|
|
|
base.OnLostMouseCapture(e); |
|
|
|
base.OnLostMouseCapture(e); |
|
|
|
if (this.selectedEndIndex == this.selectedStartIndex) |
|
|
|
|
|
|
|
this.selectedEndIndex++; |
|
|
|
|
|
|
|
OnRangeChanged(new RangeEventArgs(this.selectedStartIndex, this.selectedEndIndex)); |
|
|
|
OnRangeChanged(new RangeEventArgs(this.selectedStartIndex, this.selectedEndIndex)); |
|
|
|
Debug.Print("lost capture"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private int TransformToIndex(Point point) |
|
|
|
int TransformToIndex(Point point, out bool valid) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int value = (int)Math.Floor(point.X / this.pieceWidth); |
|
|
|
|
|
|
|
valid = (0 <= value && value <= this.valuesList.Count - 1); |
|
|
|
|
|
|
|
return Math.Min(Math.Max(0, value), this.valuesList.Count - 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#region MouseHover
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// The MouseHover event.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
public static readonly RoutedEvent MouseHoverEvent = |
|
|
|
|
|
|
|
EventManager.RegisterRoutedEvent("MouseHover", RoutingStrategy.Bubble, |
|
|
|
|
|
|
|
typeof(MouseEventHandler), typeof(TimeLineControl)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// The MouseHoverStopped event.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
public static readonly RoutedEvent MouseHoverStoppedEvent = |
|
|
|
|
|
|
|
EventManager.RegisterRoutedEvent("MouseHoverStopped", RoutingStrategy.Bubble, |
|
|
|
|
|
|
|
typeof(MouseEventHandler), typeof(TimeLineControl)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Occurs when the mouse has hovered over a fixed location for some time.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
public event MouseEventHandler MouseHover { |
|
|
|
|
|
|
|
add { AddHandler(MouseHoverEvent, value); } |
|
|
|
|
|
|
|
remove { RemoveHandler(MouseHoverEvent, value); } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
/// Occurs when the mouse had previously hovered but now started moving again.
|
|
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
|
public event MouseEventHandler MouseHoverStopped { |
|
|
|
|
|
|
|
add { AddHandler(MouseHoverStoppedEvent, value); } |
|
|
|
|
|
|
|
remove { RemoveHandler(MouseHoverStoppedEvent, value); } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DispatcherTimer mouseHoverTimer; |
|
|
|
|
|
|
|
Point mouseHoverStartPoint; |
|
|
|
|
|
|
|
MouseEventArgs mouseHoverLastEventArgs; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
|
|
protected override void OnMouseMove(MouseEventArgs e) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
base.OnMouseMove(e); |
|
|
|
|
|
|
|
Point newPosition = e.GetPosition(this); |
|
|
|
|
|
|
|
Vector mouseMovement = mouseHoverStartPoint - newPosition; |
|
|
|
|
|
|
|
if (Math.Abs(mouseMovement.X) > SystemParameters.MouseHoverWidth |
|
|
|
|
|
|
|
|| Math.Abs(mouseMovement.Y) > SystemParameters.MouseHoverHeight) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
StopHovering(); |
|
|
|
|
|
|
|
mouseHoverStartPoint = newPosition; |
|
|
|
|
|
|
|
mouseHoverLastEventArgs = e; |
|
|
|
|
|
|
|
mouseHoverTimer = new DispatcherTimer(SystemParameters.MouseHoverTime, DispatcherPriority.Background, |
|
|
|
|
|
|
|
OnMouseHoverTimerElapsed, this.Dispatcher); |
|
|
|
|
|
|
|
mouseHoverTimer.Start(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HandleMovement(e); |
|
|
|
|
|
|
|
// do not set e.Handled - allow others to also handle MouseMove
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
|
|
|
|
protected override void OnMouseLeave(MouseEventArgs e) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
base.OnMouseLeave(e); |
|
|
|
|
|
|
|
StopHovering(); |
|
|
|
|
|
|
|
// do not set e.Handled - allow others to also handle MouseLeave
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void StopHovering() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (mouseHoverTimer != null) { |
|
|
|
|
|
|
|
mouseHoverTimer.Stop(); |
|
|
|
|
|
|
|
mouseHoverTimer = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.tooltip != null) { |
|
|
|
|
|
|
|
this.tooltip.IsOpen = false; |
|
|
|
|
|
|
|
this.tooltip = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void OnMouseHoverTimerElapsed(object sender, EventArgs e) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return (int)Math.Round(point.X / this.pieceWidth); |
|
|
|
mouseHoverTimer.Stop(); |
|
|
|
|
|
|
|
mouseHoverTimer = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endregion
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|