1 //-------------------------------------------------------------
2 // <copyright company=�Microsoft Corporation�>
3 //   Copyright � Microsoft Corporation. All Rights Reserved.
4 // </copyright>
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 //  File:		AnnotationCollection.cs
9 //
10 //  Namespace:	System.Web.UI.WebControls[Windows.Forms].Charting
11 //
12 //	Classes:	AnnotationCollection, AnnotationCollectionEditor
13 //
14 //  Purpose:	Collection of annotation objects.
15 //
16 //	Reviewed:
17 //
18 //===================================================================
19 
20 #region Used namespace
21 using System;
22 using System.Collections;
23 using System.Collections.Specialized;
24 using System.ComponentModel;
25 using System.ComponentModel.Design;
26 using System.Data;
27 using System.Drawing;
28 using System.Drawing.Design;
29 using System.Drawing.Text;
30 using System.Drawing.Drawing2D;
31 using System.Globalization;
32 using System.Diagnostics.CodeAnalysis;
33 
34 #if Microsoft_CONTROL
35 using System.Windows.Forms;
36 	using System.Windows.Forms.DataVisualization.Charting;
37 	using System.Windows.Forms.DataVisualization.Charting.Data;
38 	using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
39 	using System.Windows.Forms.DataVisualization.Charting.Utilities;
40 	using System.Windows.Forms.DataVisualization.Charting.Borders3D;
41 
42 #else
43 using System.Web;
44 using System.Web.UI;
45 using System.Web.UI.DataVisualization.Charting;
46 using System.Web.UI.DataVisualization.Charting.Data;
47 using System.Web.UI.DataVisualization.Charting.Utilities;
48 #endif
49 
50 
51 #endregion
52 
53 #if Microsoft_CONTROL
54 	namespace System.Windows.Forms.DataVisualization.Charting
55 #else
56     namespace System.Web.UI.DataVisualization.Charting
57 #endif
58 {
59 	/// <summary>
60 	/// <b>AnnotationCollection</b> is a collection that stores chart annotation objects.
61     /// <seealso cref="Charting.Chart.Annotations"/>
62 	/// </summary>
63 	/// <remarks>
64 	/// All chart annotations are stored in this collection.  It is exposed as
65     /// a <see cref="Charting.Chart.Annotations"/> property of the chart. It is also used to
66 	/// store annotations inside the <see cref="AnnotationGroup"/> class.
67 	/// <para>
68 	/// This class includes methods for adding, inserting, iterating and removing annotations.
69 	/// </para>
70 	/// </remarks>
71 	[
72 		SRDescription("DescriptionAttributeAnnotations3"),
73 	]
74 #if ASPPERM_35
75 	[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
76     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
77 #endif
78 	public class AnnotationCollection : ChartNamedElementCollection<Annotation>
79 	{
80 		#region Fields
81 
82 		/// <summary>
83         /// Group this collection belongs too
84 		/// </summary>
85         internal AnnotationGroup AnnotationGroup { get; set; }
86 
87 #if Microsoft_CONTROL
88 
89         // Annotation object that was last clicked on
90 		internal Annotation					lastClickedAnnotation = null;
91 
92 		// Start point of annotation moving or resizing
93 		private	PointF						_movingResizingStartPoint = PointF.Empty;
94 
95         // Current resizing mode
96         private ResizingMode _resizingMode = ResizingMode.None;
97 
98         // Annotation object which is currently placed on the chart
99 		internal		Annotation			placingAnnotation = null;
100 
101 #endif
102 
103         #endregion
104 
105         #region Construction and Initialization
106 
107         /// <summary>
108         /// Initializes a new instance of the <see cref="AnnotationCollection"/> class.
109         /// </summary>
110         /// <param name="parent">The parent chart element.</param>
AnnotationCollection(IChartElement parent)111 		internal AnnotationCollection(IChartElement parent) : base(parent)
112 		{
113 		}
114 
115 		#endregion
116 
117 		#region Items Inserting and Removing Notification methods
118 
119         /// <summary>
120         /// Initializes the specified item.
121         /// </summary>
122         /// <param name="item">The item.</param>
Initialize(Annotation item)123         internal override void Initialize(Annotation item)
124         {
125             if (item != null)
126             {
127                 TextAnnotation textAnnotation = item as TextAnnotation;
128                 if (textAnnotation != null && string.IsNullOrEmpty(textAnnotation.Text) && Chart != null && Chart.IsDesignMode())
129                 {
130                     textAnnotation.Text = item.Name;
131                 }
132 
133                 //If the collection belongs to annotation group we need to pass a ref to this group to all the child annotations
134                 if (this.AnnotationGroup != null)
135                 {
136                     item.annotationGroup = this.AnnotationGroup;
137                 }
138 
139                 item.ResetCurrentRelativePosition();
140             }
141             base.Initialize(item);
142         }
143 
144         /// <summary>
145         /// Deinitializes the specified item.
146         /// </summary>
147         /// <param name="item">The item.</param>
Deinitialize(Annotation item)148         internal override void Deinitialize(Annotation item)
149         {
150             if (item != null)
151             {
152                 item.annotationGroup = null;
153                 item.ResetCurrentRelativePosition();
154             }
155             base.Deinitialize(item);
156         }
157 
158 
159         /// <summary>
160 		/// Finds an annotation in the collection by name.
161 		/// </summary>
162 		/// <param name="name">
163 		/// Name of the annotation to find.
164 		/// </param>
165 		/// <returns>
166 		/// <see cref="Annotation"/> object, or null (or nothing) if it does not exist.
167 		/// </returns>
FindByName(string name)168 		public override Annotation FindByName(string name)
169 		{
170 			foreach(Annotation annotation in this)
171 			{
172 				// Compare annotation name
173 				if(annotation.Name == name)
174 				{
175 					return annotation;
176 				}
177 
178 				// Check if annotation is a group
179 				AnnotationGroup annotationGroup = annotation as AnnotationGroup;
180 				if(annotationGroup != null)
181 				{
182 					Annotation result = annotationGroup.Annotations.FindByName(name);
183 					if(result != null)
184 					{
185 						return result;
186 					}
187 				}
188 			}
189 
190 			return null;
191 		}
192 
193         #endregion
194 
195         #region Painting
196 
197         /// <summary>
198 		/// Paints all annotation objects in the collection.
199 		/// </summary>
200 		/// <param name="chartGraph">Chart graphics used for painting.</param>
201 		/// <param name="drawAnnotationOnly">Indicates that only annotation objects are redrawn.</param>
202         [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification="This parameter is used when compiling for the Microsoft version of Chart")]
Paint(ChartGraphics chartGraph, bool drawAnnotationOnly)203 		internal void Paint(ChartGraphics chartGraph, bool drawAnnotationOnly)
204 		{
205 #if Microsoft_CONTROL
206             ChartPicture chartPicture = this.Chart.chartPicture;
207 
208 			// Restore previous background using double buffered bitmap
209 			if(!chartPicture.isSelectionMode &&
210 				this.Count > 0 /*&&
211 				!this.Chart.chartPicture.isPrinting*/)
212 			{
213 				chartPicture.backgroundRestored = true;
214 				Rectangle chartPosition = new Rectangle(0, 0, chartPicture.Width, chartPicture.Height);
215 				if(chartPicture.nonTopLevelChartBuffer == null || !drawAnnotationOnly)
216 				{
217 					// Dispose previous bitmap
218 					if(chartPicture.nonTopLevelChartBuffer != null)
219 					{
220 						chartPicture.nonTopLevelChartBuffer.Dispose();
221 						chartPicture.nonTopLevelChartBuffer = null;
222 					}
223 
224 					// Copy chart area plotting rectangle from the chart's dubble buffer image into area dubble buffer image
225                     if (this.Chart.paintBufferBitmap != null &&
226                         this.Chart.paintBufferBitmap.Size.Width >= chartPosition.Size.Width &&
227                         this.Chart.paintBufferBitmap.Size.Height >= chartPosition.Size.Height)
228 					{
229                         chartPicture.nonTopLevelChartBuffer = this.Chart.paintBufferBitmap.Clone(
230                             chartPosition, this.Chart.paintBufferBitmap.PixelFormat);
231 					}
232 				}
233 				else if(drawAnnotationOnly && chartPicture.nonTopLevelChartBuffer != null)
234 				{
235 					// Restore previous background
236                     this.Chart.paintBufferBitmapGraphics.DrawImageUnscaled(
237 						chartPicture.nonTopLevelChartBuffer,
238 						chartPosition);
239 				}
240 			}
241 #endif // Microsoft_CONTROL
242 
243 			// Draw all annotation objects
244 			foreach(Annotation annotation in this)
245 			{
246 				// Reset calculated relative position
247 				annotation.ResetCurrentRelativePosition();
248 
249 				if(annotation.IsVisible())
250 				{
251 					bool	resetClip = false;
252 
253 					// Check if anchor point ----osiated with plot area is inside the scaleView
254 					if(annotation.IsAnchorVisible())
255 					{
256 						// Set annotation object clipping
257 						if(annotation.ClipToChartArea.Length > 0 &&
258                             annotation.ClipToChartArea != Constants.NotSetValue &&
259 							Chart != null)
260 						{
261                             int areaIndex = Chart.ChartAreas.IndexOf(annotation.ClipToChartArea);
262 							if( areaIndex >= 0 )
263 							{
264 								// Get chart area object
265                                 ChartArea chartArea = Chart.ChartAreas[areaIndex];
266 								chartGraph.SetClip(chartArea.PlotAreaPosition.ToRectangleF());
267 								resetClip = true;
268 							}
269 						}
270 
271 						// Start Svg Selection mode
272 						string url = String.Empty;
273 #if !Microsoft_CONTROL
274 						url = annotation.Url;
275 #endif // !Microsoft_CONTROL
276 						chartGraph.StartHotRegion(
277 							annotation.ReplaceKeywords(url),
278 							annotation.ReplaceKeywords(annotation.ToolTip) );
279 
280 						// Draw annotation object
281 						annotation.Paint(Chart, chartGraph);
282 
283 
284 						// End Svg Selection mode
285 						chartGraph.EndHotRegion( );
286 
287 						// Reset clipping region
288 						if(resetClip)
289 						{
290 							chartGraph.ResetClip();
291 						}
292 					}
293 				}
294 			}
295 		}
296 
297 		#endregion
298 
299         #region Mouse Events Handlers
300 
301 #if Microsoft_CONTROL
302 
303         /// <summary>
304 		/// Mouse was double clicked.
305 		/// </summary>
OnDoubleClick()306 		internal void OnDoubleClick()
307 		{
308 			if(lastClickedAnnotation != null &&
309 				lastClickedAnnotation.AllowTextEditing)
310 			{
311                 TextAnnotation textAnnotation = lastClickedAnnotation as TextAnnotation;
312 
313 				if(textAnnotation == null)
314 				{
315                     AnnotationGroup group = lastClickedAnnotation as AnnotationGroup;
316 
317                     if (group != null)
318                     {
319                         // Try to edit text annotation in the group
320                         foreach (Annotation annot in group.Annotations)
321                         {
322                             TextAnnotation groupAnnot = annot as TextAnnotation;
323                             if (groupAnnot != null &&
324                                 groupAnnot.AllowTextEditing)
325                             {
326                                 // Get annotation position in relative coordinates
327                                 PointF firstPoint = PointF.Empty;
328                                 PointF anchorPoint = PointF.Empty;
329                                 SizeF size = SizeF.Empty;
330                                 groupAnnot.GetRelativePosition(out firstPoint, out size, out anchorPoint);
331                                 RectangleF textPosition = new RectangleF(firstPoint, size);
332 
333                                 // Check if last clicked coordinate is inside this text annotation
334                                 if (groupAnnot.GetGraphics() != null &&
335                                     textPosition.Contains(groupAnnot.GetGraphics().GetRelativePoint(this._movingResizingStartPoint)))
336                                 {
337                                     textAnnotation = groupAnnot;
338                                     lastClickedAnnotation = textAnnotation;
339                                     break;
340                                 }
341                             }
342                         }
343                     }
344 				}
345 
346 				if(textAnnotation != null)
347 				{
348 					// Start annotation text editing
349 					textAnnotation.BeginTextEditing();
350 				}
351 			}
352 		}
353 
354 		/// <summary>
355 		/// Checks if specified point is contained by any of the selection handles.
356 		/// </summary>
357 		/// <param name="point">Point which is tested in pixel coordinates.</param>
358 		/// <param name="resizingMode">Handle containing the point or None.</param>
359 		/// <returns>Annotation that contains the point or Null.</returns>
HitTestSelectionHandles(PointF point, ref ResizingMode resizingMode)360 		internal Annotation HitTestSelectionHandles(PointF point, ref ResizingMode resizingMode)
361 		{
362             Annotation annotation = null;
363 
364 			if( Common != null &&
365 				Common.graph != null)
366 			{
367 				PointF pointRel = Common.graph.GetRelativePoint(point);
368 				foreach(Annotation annot in this)
369 				{
370 					// Reset selcted path point
371 					annot.currentPathPointIndex = -1;
372 
373 					// Check if annotation is selected
374 					if(annot.IsSelected)
375 					{
376 						if(annot.selectionRects != null)
377 						{
378 							for(int index = 0; index < annot.selectionRects.Length; index++)
379 							{
380 								if(!annot.selectionRects[index].IsEmpty &&
381 									annot.selectionRects[index].Contains(pointRel))
382 								{
383 									annotation = annot;
384 									if(index > (int)ResizingMode.AnchorHandle)
385 									{
386 										resizingMode = ResizingMode.MovingPathPoints;
387 										annot.currentPathPointIndex = index - 9;
388 									}
389 									else
390 									{
391 										resizingMode = (ResizingMode)index;
392 									}
393 								}
394 							}
395 						}
396 					}
397 				}
398 			}
399 			return annotation;
400 		}
401 
402 		/// <summary>
403 		/// Mouse button pressed in the control.
404 		/// </summary>
405 		/// <param name="e">Event arguments.</param>
406 		/// <param name="isHandled">Returns true if event is handled and no further processing required.</param>
OnMouseDown(MouseEventArgs e, ref bool isHandled)407 		internal void OnMouseDown(MouseEventArgs e, ref bool isHandled)
408 		{
409             // Reset last clicked annotation object and stop text editing
410 			if(lastClickedAnnotation != null)
411 			{
412 				TextAnnotation textAnnotation = lastClickedAnnotation as TextAnnotation;
413 				if(textAnnotation != null)
414 				{
415 					// Stop annotation text editing
416 					textAnnotation.StopTextEditing();
417 				}
418 				lastClickedAnnotation = null;
419 			}
420 
421 			// Check if in annotation placement mode
422 			if( this.placingAnnotation != null)
423 			{
424 				// Process mouse down
425 				this.placingAnnotation.PlacementMouseDown(new PointF(e.X, e.Y), e.Button);
426 
427 				// Set handled flag
428 				isHandled = true;
429 				return;
430 			}
431 
432 			// Process only left mouse buttons
433 			if(e.Button == MouseButtons.Left)
434 			{
435 				bool	updateRequired = false;
436 				this._resizingMode = ResizingMode.None;
437 
438 				// Check if mouse buton was pressed in any selection handles areas
439 				Annotation annotation =
440 					HitTestSelectionHandles(new PointF(e.X, e.Y), ref this._resizingMode);
441 
442 				// Check if mouse button was pressed over one of the annotation objects
443 				if(annotation == null && this.Count > 0)
444 				{
445 					HitTestResult result = this.Chart.HitTest(e.X, e.Y, ChartElementType.Annotation);
446 					if(result != null && result.ChartElementType == ChartElementType.Annotation)
447 					{
448 						annotation = (Annotation)result.Object;
449 					}
450 				}
451 
452 				// Unselect all annotations if mouse clicked outside any annotations
453 				if(annotation == null || !annotation.IsSelected)
454 				{
455 					if((Control.ModifierKeys & Keys.Control) != Keys.Control &&
456 						(Control.ModifierKeys & Keys.Shift) != Keys.Shift)
457 					{
458                         foreach (Annotation annot in this.Chart.Annotations)
459 						{
460 							if(annot != annotation && annot.IsSelected)
461 							{
462 								annot.IsSelected = false;
463 								updateRequired = true;
464 
465 								// Call selection changed notification
466                                 if (this.Chart != null)
467 								{
468                                     this.Chart.OnAnnotationSelectionChanged(annot);
469 								}
470 							}
471 						}
472 					}
473 				}
474 
475 				// Process mouse action in the annotation object
476 				if(annotation != null)
477 				{
478 					// Mouse down event handled
479 					isHandled = true;
480 
481 					// Select/Unselect annotation
482 					Annotation selectableAnnotation = annotation;
483 					if(annotation.AnnotationGroup != null)
484 					{
485 						// Select annotation group when click on any child annotations
486 						selectableAnnotation = annotation.AnnotationGroup;
487 					}
488 					if(!selectableAnnotation.IsSelected && selectableAnnotation.AllowSelecting)
489 					{
490 						selectableAnnotation.IsSelected = true;
491 						updateRequired = true;
492 
493 						// Call selection changed notification
494                         if (this.Chart != null)
495 						{
496                             this.Chart.OnAnnotationSelectionChanged(selectableAnnotation);
497 						}
498 					}
499 					else if((Control.ModifierKeys & Keys.Control) == Keys.Control ||
500 						(Control.ModifierKeys & Keys.Shift) == Keys.Shift)
501 					{
502 						selectableAnnotation.IsSelected = false;
503 						updateRequired = true;
504 
505 						// Call selection changed notification
506                         if (this.Chart != null)
507 						{
508                             this.Chart.OnAnnotationSelectionChanged(selectableAnnotation);
509 						}
510 					}
511 
512 					// Remember last clicked and selected annotation
513 					lastClickedAnnotation = annotation;
514 
515 					// Rember mouse position
516 					this._movingResizingStartPoint = new PointF(e.X, e.Y);
517 
518 					// Start moving, repositioning or resizing of annotation
519 					if(annotation.IsSelected)
520 					{
521 						// Check if one of selection handles was clicked on
522 						this._resizingMode = annotation.GetSelectionHandle(this._movingResizingStartPoint);
523 						if(!annotation.AllowResizing &&
524 							this._resizingMode >= ResizingMode.TopLeftHandle &&
525 							this._resizingMode <= ResizingMode.LeftHandle)
526 						{
527 							this._resizingMode = ResizingMode.None;
528 						}
529 						if(!annotation.AllowAnchorMoving &&
530 							this._resizingMode == ResizingMode.AnchorHandle)
531 						{
532 							this._resizingMode = ResizingMode.None;
533 						}
534 						if(this._resizingMode == ResizingMode.None && annotation.AllowMoving)
535 						{
536 							// Annotation moving mode
537 							this._resizingMode = ResizingMode.Moving;
538 						}
539 					}
540 					else
541 					{
542 						if(this._resizingMode == ResizingMode.None && annotation.AllowMoving)
543 						{
544                             // Do not allow moving child annotations inside the group.
545                             // Only the whole group can be selected, resized or repositioned.
546                             if (annotation.AnnotationGroup != null)
547                             {
548                                 // Move the group instead
549                                 lastClickedAnnotation = annotation.AnnotationGroup;
550                             }
551 
552                             // Annotation moving mode
553                             this._resizingMode = ResizingMode.Moving;
554 						}
555 					}
556 				}
557 
558 				// Update chart
559 				if(updateRequired)
560 				{
561 					// Invalidate and update the chart
562                     this.Chart.Invalidate(true);
563                     this.Chart.UpdateAnnotations();
564 				}
565 			}
566 		}
567 
568 		/// <summary>
569 		/// Mouse button released in the control.
570 		/// </summary>
571 		/// <param name="e">Event arguments.</param>
OnMouseUp(MouseEventArgs e)572 		internal void OnMouseUp(MouseEventArgs e)
573 		{
574 			// Check if in annotation placement mode
575 			if( this.placingAnnotation != null)
576 			{
577 				if(!this.placingAnnotation.PlacementMouseUp(new PointF(e.X, e.Y), e.Button))
578 				{
579 					return;
580 				}
581 			}
582 
583 			if(e.Button == MouseButtons.Left)
584 			{
585 				// Reset moving sizing start point
586 				this._movingResizingStartPoint = PointF.Empty;
587 				this._resizingMode = ResizingMode.None;
588 			}
589 
590 			// Loop through all annotation objects
591 			for(int index = 0; index < this.Count; index++)
592 			{
593 				Annotation	annotation = this[index];
594 
595 				// NOTE: Automatic deleting feature was disabled. -AG.
596 				/*
597 				// Delete all annotation objects moved outside clipping region
598 				if( annotation.outsideClipRegion )
599 				{
600 					this.List.RemoveAt(index);
601 					--index;
602 				}
603 				*/
604 
605 				// Reset start position/location fields
606 				annotation.startMovePositionRel = RectangleF.Empty;
607 				annotation.startMoveAnchorLocationRel = PointF.Empty;
608 				if(annotation.startMovePathRel != null)
609 				{
610 					annotation.startMovePathRel.Dispose();
611 					annotation.startMovePathRel = null;
612 				}
613 
614 				// Fire position changed event
615 				if( annotation.positionChanged )
616 				{
617 					annotation.positionChanged = false;
618                     if (this.Chart != null)
619 					{
620                         this.Chart.OnAnnotationPositionChanged(annotation);
621 					}
622 				}
623 			}
624 		}
625 
626 		/// <summary>
627 		/// Mouse moved in the control.
628 		/// </summary>
629 		/// <param name="e">Event arguments.</param>
OnMouseMove(MouseEventArgs e)630 		internal void OnMouseMove(MouseEventArgs e)
631 		{
632 			// Check if in annotation placement mode
633 			if(this.placingAnnotation != null)
634 			{
635                 System.Windows.Forms.Cursor newCursor = this.Chart.Cursor;
636 				if(this.placingAnnotation.IsValidPlacementPosition(e.X, e.Y))
637 				{
638 					newCursor = Cursors.Cross;
639 				}
640 				else
641 				{
642                     newCursor = this.Chart.defaultCursor;
643 				}
644 
645 				// Set current chart cursor
646                 if (newCursor != this.Chart.Cursor)
647 				{
648                     System.Windows.Forms.Cursor tmpCursor = this.Chart.defaultCursor;
649                     this.Chart.Cursor = newCursor;
650                     this.Chart.defaultCursor = tmpCursor;
651 				}
652 
653 				this.placingAnnotation.PlacementMouseMove(new PointF(e.X, e.Y));
654 
655 				return;
656 			}
657 
658 			// Check if currently resizing/moving annotation
659 			if(!this._movingResizingStartPoint.IsEmpty &&
660 				this._resizingMode != ResizingMode.None)
661 			{
662 				// Calculate how far the mouse was moved
663 				SizeF	moveDistance = new SizeF(
664 					this._movingResizingStartPoint.X - e.X,
665 					this._movingResizingStartPoint.Y - e.Y );
666 
667 				// Update location of all selected annotation objects
668 				foreach(Annotation annot in this)
669 				{
670 					if(annot.IsSelected &&
671 						( (this._resizingMode == ResizingMode.MovingPathPoints && annot.AllowPathEditing) ||
672 						(this._resizingMode == ResizingMode.Moving && annot.AllowMoving) ||
673 						(this._resizingMode == ResizingMode.AnchorHandle && annot.AllowAnchorMoving) ||
674 						(this._resizingMode >= ResizingMode.TopLeftHandle && this._resizingMode <= ResizingMode.LeftHandle && annot.AllowResizing) ) )
675 					{
676 						annot.AdjustLocationSize(moveDistance, this._resizingMode, true, true);
677 					}
678 				}
679 
680 				// Move last clicked non-selected annotation
681 				if(lastClickedAnnotation != null &&
682 					!lastClickedAnnotation.IsSelected)
683 				{
684 					if(this._resizingMode == ResizingMode.Moving &&
685 						lastClickedAnnotation.AllowMoving)
686 					{
687 						lastClickedAnnotation.AdjustLocationSize(moveDistance, this._resizingMode, true, true);
688 					}
689 				}
690 
691 				// Invalidate and update the chart
692                 this.Chart.Invalidate(true);
693                 this.Chart.UpdateAnnotations();
694 			}
695 			else if(this.Count > 0)
696 			{
697 				// Check if currently placing annotation from the UserInterface
698 				bool	process = true;
699 
700 				if(process)
701 				{
702 					// Check if mouse pointer is over the annotation selection handle
703 					ResizingMode currentResizingMode = ResizingMode.None;
704 					Annotation annotation =
705 						HitTestSelectionHandles(new PointF(e.X, e.Y), ref currentResizingMode);
706 
707 					// Check if mouse pointer over the annotation object movable area
708 					if(annotation == null)
709 					{
710                         HitTestResult result = this.Chart.HitTest(e.X, e.Y, ChartElementType.Annotation);
711 						if(result != null && result.ChartElementType == ChartElementType.Annotation)
712 						{
713 							annotation = (Annotation)result.Object;
714 							if(annotation != null)
715 							{
716 								// Check if annotation is in the collection
717 								if(this.Contains(annotation))
718 								{
719 									currentResizingMode = ResizingMode.Moving;
720 									if(annotation.AllowMoving == false)
721 									{
722 										// Movement is not allowed
723 										annotation = null;
724 										currentResizingMode = ResizingMode.None;
725 									}
726 								}
727 							}
728 						}
729 					}
730 					// Set mouse cursor
731 					SetResizingCursor(annotation, currentResizingMode);
732 				}
733 			}
734 		}
735 
736 		/// <summary>
737 		/// Sets mouse cursor shape.
738 		/// </summary>
739 		/// <param name="annotation">Annotation object.</param>
740 		/// <param name="currentResizingMode">Resizing mode.</param>
SetResizingCursor(Annotation annotation, ResizingMode currentResizingMode)741 		private void SetResizingCursor(Annotation annotation, ResizingMode currentResizingMode)
742 		{
743 			// Change current cursor
744 			if(this.Chart != null)
745 			{
746                 System.Windows.Forms.Cursor newCursor = this.Chart.Cursor;
747 				if(annotation != null)
748 				{
749 					if(currentResizingMode == ResizingMode.MovingPathPoints &&
750 						annotation.AllowPathEditing)
751 					{
752 						newCursor = Cursors.Cross;
753 					}
754 
755 					if(currentResizingMode == ResizingMode.Moving &&
756 						annotation.AllowMoving)
757 					{
758 						newCursor = Cursors.SizeAll;
759 					}
760 
761 					if(currentResizingMode == ResizingMode.AnchorHandle &&
762 						annotation.AllowAnchorMoving)
763 					{
764 						newCursor = Cursors.Cross;
765 					}
766 
767 					if(currentResizingMode != ResizingMode.Moving &&
768 						annotation.AllowResizing)
769 					{
770 						if(annotation.SelectionPointsStyle == SelectionPointsStyle.TwoPoints)
771 						{
772 							if(currentResizingMode == ResizingMode.TopLeftHandle ||
773 								currentResizingMode == ResizingMode.BottomRightHandle)
774 							{
775 								newCursor = Cursors.Cross;
776 							}
777 						}
778 						else
779 						{
780 							if(currentResizingMode == ResizingMode.TopLeftHandle ||
781 								currentResizingMode == ResizingMode.BottomRightHandle)
782 							{
783 								newCursor = Cursors.SizeNWSE;
784 							}
785 							else if(currentResizingMode == ResizingMode.TopRightHandle ||
786 								currentResizingMode == ResizingMode.BottomLeftHandle)
787 							{
788 								newCursor = Cursors.SizeNESW;
789 							}
790 							else if(currentResizingMode == ResizingMode.TopHandle ||
791 								currentResizingMode == ResizingMode.BottomHandle)
792 							{
793 								newCursor = Cursors.SizeNS;
794 							}
795 							else if(currentResizingMode == ResizingMode.LeftHandle ||
796 								currentResizingMode == ResizingMode.RightHandle)
797 							{
798 								newCursor = Cursors.SizeWE;
799 							}
800 						}
801 					}
802 				}
803 				else
804 				{
805                     newCursor = this.Chart.defaultCursor;
806 				}
807 
808 				// Set current chart cursor
809                 if (newCursor != this.Chart.Cursor)
810 				{
811                     System.Windows.Forms.Cursor tmpCursor = this.Chart.defaultCursor;
812                     this.Chart.Cursor = newCursor;
813                     this.Chart.defaultCursor = tmpCursor;
814 				}
815 			}
816 		}
817 
818 #endif // Microsoft_CONTROL
819 
820 		#endregion
821 
822         #region Event handlers
ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e)823         internal void ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e)
824         {
825             // If all the chart areas are removed and then a new one is inserted - Annotations don't get bound to it by default
826             if (e.OldElement == null)
827                 return;
828 
829             foreach (Annotation annotation in this)
830             {
831                 if (annotation.ClipToChartArea == e.OldName)
832                     annotation.ClipToChartArea = e.NewName;
833 
834                 AnnotationGroup group = annotation as AnnotationGroup;
835                 if (group != null)
836                 {
837                     group.Annotations.ChartAreaNameReferenceChanged(sender, e);
838                 }
839             }
840         }
841         #endregion
842 
843     }
844 }
845