Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Web.DataVisualization / Common / General / AxisScrollBar.cs
1 //-------------------------------------------------------------
2 // <copyright company=\92Microsoft Corporation\92>
3 //   Copyright © Microsoft Corporation. All Rights Reserved.
4 // </copyright>
5 //-------------------------------------------------------------
6 // @owner=alexgor, deliant
7 //=================================================================
8 //  File:               AxisScrollBar.cs
9 //
10 //  Namespace:  System.Web.UI.WebControls[Windows.Forms].Charting
11 //
12 //      Classes:        AxisScrollBar, ScrollBarEventArgs
13 //
14 //  Purpose:    AxisScrollBar class represent axis scroolbar. There 
15 //              is a big difference how this UI  functionality 
16 //              implemented for Windows Forms and ASP.NET. For 
17 //              Windows Forms a custom drawn scrollbar control is
18 //              drawn in the chart which reacts to the mouse input and 
19 //              changes current axis data scaleView.
20 //
21 //              ASP.NET version uses client-side scripting and partial
22 //              loading of data segment by segment. Due to the fact
23 //              that scrollbar operates on the client side not all
24 //              functionality of WindowsForms scrollbar is supported.
25 //              
26 //      Reviewed:       AG - March 16, 2007
27 //
28 //===================================================================
29
30 #if WINFORMS_CONTROL
31
32 #region Used namespaces
33
34 using System;
35 using System.ComponentModel;
36 using System.Drawing;
37 using System.Drawing.Design;
38 using System.Drawing.Drawing2D;
39 using System.Windows.Forms;
40 using System.Windows.Forms.DataVisualization.Charting;
41 using System.Windows.Forms.DataVisualization.Charting.Data;
42 using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
43 using System.Windows.Forms.DataVisualization.Charting.Utilities;
44 using System.Windows.Forms.DataVisualization.Charting.Borders3D;
45 using System.Diagnostics.CodeAnalysis;
46
47 #endregion
48
49 namespace System.Windows.Forms.DataVisualization.Charting
50 {
51         #region Scroll bar enumerations
52
53         /// <summary>
54         /// An enumeration of scrollbar button types.
55         /// </summary>
56     public enum ScrollBarButtonType
57         {
58                 /// <summary>
59                 /// Thumb tracker button.
60                 /// </summary>
61                 ThumbTracker,
62
63                 /// <summary>
64                 /// Scroll by substracting small distance.
65                 /// </summary>
66                 SmallDecrement,
67
68                 /// <summary>
69                 /// Scroll by adding small distance.
70                 /// </summary>
71                 SmallIncrement,
72
73                 /// <summary>
74                 /// Scroll by substracting large distance.
75                 /// </summary>
76                 LargeDecrement,
77
78                 /// <summary>
79                 /// Scroll by adding large distance.
80                 /// </summary>
81                 LargeIncrement,
82
83                 /// <summary>
84                 /// Zoom reset button.
85                 /// </summary>
86                 ZoomReset
87         }
88
89         /// <summary>
90         /// An enumeration of scrollbar button style flags.
91         /// </summary>
92         [Flags]
93     public enum ScrollBarButtonStyles
94         {
95                 /// <summary>
96                 /// No buttons are shown.
97                 /// </summary>
98                 None = 0,
99
100                 /// <summary>
101                 /// Small increment or decrement buttons are shown.
102                 /// </summary>
103                 SmallScroll = 1,
104
105                 /// <summary>
106                 /// Reset zoom buttons are shown.
107                 /// </summary>
108                 ResetZoom = 2,
109
110                 /// <summary>
111                 /// All buttons are shown. 
112                 /// </summary>
113                 All = SmallScroll | ResetZoom
114         }
115
116         #endregion
117
118         /// <summary>
119     /// AxisScrollBar class represents the axis scrollbar. It is exposed as the
120     /// ScrollBar property of the Axis class. It contains scrollbar appearance
121     /// properties and drawing methods.
122         /// </summary>
123     public class AxisScrollBar : IDisposable
124         {
125         #region Scroll bar fields
126
127         // Reference to the axis data scaleView class
128                 internal Axis                                   axis = null;
129
130                 // Indicates that scollbra will be drawn
131                 private bool                                    _enabled = true;
132
133         // Axis data scaleView scroll bar style
134                 private ScrollBarButtonStyles   _scrollBarButtonStyle = ScrollBarButtonStyles.All;
135
136                 // Axis data scaleView scroll bar size
137                 private double                                  _scrollBarSize = 14.0;
138
139                 // Index of the pressed butoon in the scroll bar
140                 private int                                             _pressedButtonType = int.MaxValue;
141
142                 // Axis data scaleView scroll bar buttons color
143                 private Color                                   _buttonColor = Color.Empty;
144
145                 // Axis data scaleView scroll bar back color
146                 private Color                                   _backColor = Color.Empty;
147
148                 // Axis data scaleView scroll bar lines color
149                 private Color                                   _lineColor = Color.Empty;
150
151                 // Current scroll bar drawing colors
152                 private Color                                   _buttonCurrentColor = Color.Empty;
153                 private Color                                   _backCurrentColor = Color.Empty;
154                 private Color                                   _lineCurrentColor = Color.Empty;
155
156                 // Last mouse click mouse and scaleView position
157                 private PointF                                  _lastClickMousePosition = PointF.Empty;
158                 private double                                  _lastClickViewPosition = double.NaN;
159
160                 // Timer used to scroll the data while selecting
161                 private System.Windows.Forms.Timer      _scrollTimer = new System.Windows.Forms.Timer();
162
163                 // Scroll size and direction when AutoScroll is set
164                 private MouseEventArgs                  _mouseArguments = null;
165
166                 // Position of the scrollbar (true - edge of PlotArea, false - edge of chart area)
167                 private bool                                    _isPositionedInside = true;
168
169                 #endregion
170
171                 #region Scroll bar constructors and initialization
172
173                 /// <summary>
174                 /// AxisScrollBar constructor.
175                 /// </summary>
176                 public AxisScrollBar()
177                 {
178                 }
179
180                 /// <summary>
181                 /// Axis scroll bar constructor.
182                 /// </summary>
183                 /// <param name="axis">Reference to the axis class.</param>
184         internal AxisScrollBar(Axis axis)
185                 {
186                         // Save reference to the axis data scaleView
187                         this.axis = axis;
188                 }
189
190                 /// <summary>
191                 /// Initialize axis scroll bar class.
192                 /// </summary>
193                 internal void Initialize()
194                 {
195                 }
196
197         #endregion
198
199 #region Scroll bar properties
200         
201         /// <summary>
202                 /// Gets or sets a flag which indicates whether scroll bar is positioned inside or outside of chart area.
203                 /// </summary>
204                 [
205         SRCategory("CategoryAttributeAxisView"),
206                 Bindable(true),
207                 DefaultValue(true),
208                 SRDescription("DescriptionAttributeAxisScrollBar_PositionInside")
209                 ]
210                 public bool IsPositionedInside
211                 {
212                         get
213                         {
214                                 return _isPositionedInside;
215                         }
216                         set
217                         {
218                                 if(_isPositionedInside != value)
219                                 {
220                                         _isPositionedInside = value;
221                                         if(axis != null)
222                                         {
223                                                 axis.ChartArea.Invalidate();
224                                         }
225                                 }
226                         }
227                 }
228
229
230                 /// <summary>
231                 /// Gets or sets a flag which indicates whether the scroll bar is enabled.
232                 /// </summary>
233                 [
234                 SRCategory("CategoryAttributeAxisView"),
235                 Bindable(true),
236                 DefaultValue(true),
237                 SRDescription("DescriptionAttributeAxisScrollBar_Enabled")
238                 ]
239                 public bool Enabled
240                 {
241                         get
242                         {
243                                 return _enabled;
244                         }
245                         set
246                         {
247                                 if(_enabled != value)
248                                 {
249                                         _enabled = value;
250                                         if(axis != null)
251                                         {
252                                                 axis.ChartArea.Invalidate();
253                                         }
254                                 }
255                         }
256                 }
257
258                 /// <summary>
259                 /// Gets the ChartArea that contains this scrollbar.
260                 /// </summary>
261                 [
262                 Browsable(false),
263                 Bindable(false),
264                 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
265                 SerializationVisibilityAttribute(SerializationVisibility.Hidden)
266                 ]
267                 public ChartArea ChartArea
268                 {
269                         get
270                         {
271                                 return this.axis.ChartArea;
272                         }
273                 }
274
275                 /// <summary>
276                 /// Gets the Axis that contains this scrollbar.
277                 /// </summary>
278                 [
279                 Browsable(false),
280                 Bindable(false),
281                 DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden),
282                 SerializationVisibilityAttribute(SerializationVisibility.Hidden)
283                 ]
284                 public Axis Axis
285                 {
286                         get
287                         {
288                                 return this.axis;
289                         }
290                 }
291
292                 /// <summary>
293                 /// Gets or sets the style of the scrollbar button.
294                 /// </summary>
295                 [
296                 SRCategory("CategoryAttributeAxisView"),
297                 Bindable(true),
298 #if WEB_OLAP
299         DefaultValue(ScrollBarButtonStyle.SmallScroll),
300 #else
301                 DefaultValue(ScrollBarButtonStyles.All),
302 #endif
303                 SRDescription("DescriptionAttributeAxisScrollBar_Buttons"),
304         Editor(Editors.FlagsEnumUITypeEditor.Editor, Editors.FlagsEnumUITypeEditor.Base)
305                 ]
306                 public ScrollBarButtonStyles ButtonStyle
307                 {
308                         get
309                         {
310                                 return _scrollBarButtonStyle;
311                         }
312                         set
313                         {
314                                 if(_scrollBarButtonStyle != value)
315                                 {
316                                         _scrollBarButtonStyle = value;
317                                         if(axis != null)
318                                         {
319                                                 axis.ChartArea.Invalidate();
320                                         }
321                                 }
322                         }
323                 }
324
325                 /// <summary>
326                 /// Gets or sets the size of the scrollbar.
327                 /// </summary>
328                 [
329                 SRCategory("CategoryAttributeAxisView"),
330                 Bindable(true),
331                 DefaultValue(14.0),
332                 SRDescription("DescriptionAttributeAxisScrollBar_Size"),
333                 ]
334                 public double Size
335                 {
336                         get
337                         {
338                                 return _scrollBarSize;
339                         }
340                         set
341                         {
342                                 if(_scrollBarSize != value)
343                                 {
344                                         // Check values range
345                                         if(value < 5.0 || value > 20.0)
346                                         {
347                         throw (new ArgumentOutOfRangeException("value", SR.ExceptionScrollBarSizeInvalid));
348                                         }
349                                         _scrollBarSize = value;
350                                         if(axis != null)
351                                         {
352                                                 axis.ChartArea.Invalidate();
353                                         }
354                                 }
355                         }
356                 }
357
358                 /// <summary>
359                 /// Gets or sets the button color of the scrollbar.
360                 /// </summary>
361                 [
362                 SRCategory("CategoryAttributeAxisView"),
363                 Bindable(true),
364                 DefaultValue(typeof(Color), ""),
365                 SRDescription("DescriptionAttributeAxisScrollBar_ButtonColor"),
366         TypeConverter(typeof(ColorConverter)),
367         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
368                 ]
369                 public Color ButtonColor
370                 {
371                         get
372                         {
373                                 return _buttonColor;
374                         }
375                         set
376                         {
377                                 if(_buttonColor != value)
378                                 {
379                                         _buttonColor = value;
380                                         if(axis != null)
381                                         {
382                                                 axis.ChartArea.Invalidate();
383                                         }
384                                 }
385                         }
386                 }
387
388                 /// <summary>
389                 /// Gets or sets the line color of the scrollbar.
390                 /// </summary>
391                 [
392                 SRCategory("CategoryAttributeAxisView"),
393                 Bindable(true),
394                 DefaultValue(typeof(Color), ""),
395         SRDescription("DescriptionAttributeLineColor"),
396         TypeConverter(typeof(ColorConverter)),
397         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
398                 ]
399                 public Color LineColor
400                 {
401                         get
402                         {
403                                 return _lineColor;
404                         }
405                         set
406                         {
407                                 if(_lineColor != value)
408                                 {
409                                         _lineColor = value;
410                                         if(axis != null)
411                                         {
412                                                 axis.ChartArea.Invalidate();
413                                         }
414                                 }
415                         }
416                 }
417
418                 /// <summary>
419                 /// Gets or sets the background color of the scrollbar.
420                 /// </summary>
421                 [
422                 SRCategory("CategoryAttributeAxisView"),
423                 Bindable(true),
424                 DefaultValue(typeof(Color), ""),
425         SRDescription("DescriptionAttributeBackColor"),
426         TypeConverter(typeof(ColorConverter)),
427         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base)
428                 ]
429                 public Color BackColor
430                 {
431                         get
432                         {
433                                 return _backColor;
434                         }
435                         set
436                         {
437                                 if(_backColor != value)
438                                 {
439                                         _backColor = value;
440                                         if(axis != null)
441                                         {
442                                                 axis.ChartArea.Invalidate();
443                                         }
444                                 }
445                         }
446                 }
447
448 #endregion
449
450 #region Scroll bar public methods
451
452                 /// <summary>
453                 /// This method returns true if the scrollbar is visible.
454                 /// </summary>
455         [Browsable(false)]
456         [Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)]
457                 public bool IsVisible
458                 {
459             get
460             {
461                 // Check scroll bar enabled flag
462                 if (!this.Enabled)
463                 {
464                     return false;
465                 }
466
467                 // Do not show scroll bars while printing
468                 if (this.axis == null ||
469                     this.axis.ChartArea == null ||
470                     this.axis.ChartArea.Common == null ||
471                     this.axis.ChartArea.Common.ChartPicture == null ||
472                     this.axis.ChartArea.Common.ChartPicture.isPrinting)
473                 {
474                     return false;
475                 }
476
477 #if SUBAXES
478                         // Scrollbar is not supported on the sub axis
479                         if(this.axis.IsSubAxis)
480                         {
481                                 return false;
482                         }
483 #endif // SUBAXES
484
485                 // Check if data scaleView size in percentage is less than 100%
486                 return (GetDataViewPercentage() < 100.0) ? true : false;
487             }
488                 }
489
490 #endregion
491
492 #region Scroll bar painting methods
493
494                 /// <summary>
495                 /// Draws axis scroll bar.
496                 /// </summary>
497                 /// <param name="graph">Reference to the Chart Graphics object.</param>
498                 internal void Paint( ChartGraphics graph )
499                 {
500                         // Scroll bar border width
501                         int     borderWidth = 1;
502
503                         // Scroll bar should not be visible
504                         if(!this.IsVisible)
505                         {
506                                 return;
507             }
508
509 #if SUBAXES
510                         // Scrollbar not supported on sub axis
511                         if( this.axis != null &&  this.axis.IsSubAxis)
512                         {
513                                 return;
514                         }
515 #endif //SUBAXES
516
517             // Set current scroll bar colors
518                         _buttonCurrentColor = this._buttonColor;
519                         _backCurrentColor = this._backColor;
520                         _lineCurrentColor = this._lineColor;
521
522                         // Make sure the current colors are not empty
523                         if(_buttonCurrentColor == Color.Empty)
524                         {
525                                 _buttonCurrentColor = this.axis.ChartArea.BackColor;
526                                 if(_buttonCurrentColor == Color.Empty)
527                                 {
528                                         _buttonCurrentColor = Color.DarkGray;
529                                 }
530                         }
531                         if(_backCurrentColor == Color.Empty)
532                         {
533                                 _backCurrentColor = this.axis.ChartArea.BackColor;
534                                 if(_backCurrentColor == Color.Empty)
535                                 {
536                                         _backCurrentColor = Color.LightGray;
537                                 }
538                         }
539                         if(_lineCurrentColor == Color.Empty)
540                         {
541                                 _lineCurrentColor = this.axis.LineColor;
542                                 if(_lineCurrentColor == Color.Empty)
543                                 {
544                                         _lineCurrentColor = Color.Black;
545                                 }
546                         }
547
548                         // Get scroll bar rectangle
549                         RectangleF      scrollBarRect = this.GetScrollBarRect();
550
551                         // Fill scroll bar background
552                         graph.FillRectangleRel( 
553                                 scrollBarRect, 
554                                 _backCurrentColor, 
555                                 ChartHatchStyle.None, 
556                                 "", 
557                                 ChartImageWrapMode.Tile,                                
558                                 Color.Empty,
559                                 ChartImageAlignmentStyle.Center,
560                                 GradientStyle.None, 
561                                 Color.Empty, 
562                                 _lineCurrentColor,
563                                 borderWidth, 
564                                 ChartDashStyle.Solid, 
565                                 Color.Empty, 
566                                 0, 
567                                 PenAlignment.Outset );
568
569                         // Fill rectangle between to neighbour scroll bars
570                         PaintScrollBarConnectionRect(graph, scrollBarRect, borderWidth);
571
572                         // Get scroll bar client rectangle
573                         SizeF   borderRelativeSize = new SizeF(borderWidth, borderWidth);
574                         borderRelativeSize = graph.GetRelativeSize(borderRelativeSize);
575                         RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
576                         scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
577
578                         // Draw all button types
579             foreach (ScrollBarButtonType buttonType in Enum.GetValues(typeof(ScrollBarButtonType)))
580                         {
581                 // Get button rectangle
582                                 RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)buttonType);
583
584                                 // Paint button
585                                 if(!buttonRect.IsEmpty)
586                                 {
587                                         PaintScrollBar3DButton(
588                                                 graph, 
589                                                 buttonRect, 
590                                                 ((ScrollBarButtonType)this._pressedButtonType) == (ScrollBarButtonType)buttonType, 
591                                                 (ScrollBarButtonType)buttonType);
592                                 }
593                         }
594
595             if( this.ChartArea.Common.ProcessModeRegions )
596                         {
597                                 SetHotRegionElement( this.ChartArea.Common );
598                         }
599                 }
600                 
601                 /// <summary>
602                 /// Fills a connection rectangle between two scoll bars.
603                 /// </summary>
604                 /// <param name="graph">Chart graphics.</param>
605                 /// <param name="scrollBarRect">Scroll bar position.</param>
606                 /// <param name="borderWidth">Border width.</param>
607                 private void PaintScrollBarConnectionRect( 
608                         ChartGraphics graph, 
609                         RectangleF scrollBarRect,
610                         int borderWidth)
611                 {
612                         // Do not draw anything if scroll bar is vertical
613                         if(this.axis.AxisPosition == AxisPosition.Left || 
614                                 this.axis.AxisPosition == AxisPosition.Right)
615                         {
616                                 return;
617                         }
618
619                         // Check if scoll bar is shown on the left/right sides of 
620                         // the plotting area and get their sizes in relative coordinates
621                         float   leftSize = 0f;
622                         float   rightSize = 0f;
623
624                         foreach(Axis a in this.axis.ChartArea.Axes)
625                         {
626                                 if(a.AxisPosition == AxisPosition.Left && a.ScrollBar.IsVisible && a.ScrollBar.IsPositionedInside == this.axis.ScrollBar.IsPositionedInside)
627                                 {
628                                         leftSize = (float)a.ScrollBar.GetScrollBarRelativeSize();
629                                 }
630                                 if(a.AxisPosition == AxisPosition.Right && a.ScrollBar.IsVisible && a.ScrollBar.IsPositionedInside == this.axis.ScrollBar.IsPositionedInside)
631                                 {
632                                         rightSize = (float)a.ScrollBar.GetScrollBarRelativeSize();
633                                 }
634                         }
635
636                         // Prepare generic rectangle coordinates
637                         RectangleF      connectorRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
638
639                         // Prepare coordinates and fill area to the left
640                         if(leftSize > 0f)
641                         {
642                                 connectorRect.X = scrollBarRect.X - leftSize;
643                                 connectorRect.Width = leftSize;
644
645                                 // Fill background
646                                 graph.FillRectangleRel( 
647                                         connectorRect, 
648                                         _backCurrentColor, 
649                                         ChartHatchStyle.None, 
650                                         "", 
651                                         ChartImageWrapMode.Tile,                                
652                                         Color.Empty,
653                                         ChartImageAlignmentStyle.Center,
654                                         GradientStyle.None, 
655                                         Color.Empty, 
656                                         _lineCurrentColor,
657                                         borderWidth, 
658                                         ChartDashStyle.Solid, 
659                                         Color.Empty, 
660                                         0, 
661                                         PenAlignment.Outset );
662                         }
663
664                         // Prepare coordinates and fill area to the right
665                         if(rightSize > 0f)
666                         {
667                                 connectorRect.X = scrollBarRect.Right;
668                                 connectorRect.Width = rightSize;
669
670                                 // Fill background
671                                 graph.FillRectangleRel( 
672                                         connectorRect, 
673                                         _backCurrentColor, 
674                                         ChartHatchStyle.None, 
675                                         "", 
676                                         ChartImageWrapMode.Tile,                                
677                                         Color.Empty,
678                                         ChartImageAlignmentStyle.Center,
679                                         GradientStyle.None, 
680                                         Color.Empty, 
681                                         _lineCurrentColor,
682                                         borderWidth, 
683                                         ChartDashStyle.Solid, 
684                                         Color.Empty, 
685                                         0, 
686                                         PenAlignment.Outset );
687                         }
688
689                 }
690
691                 /// <summary>
692                 /// Draws 3D button in the scroll bar
693                 /// </summary>
694                 /// <param name="graph">Chart graphics.</param>
695                 /// <param name="buttonRect">Button position.</param>
696                 /// <param name="pressedState">Indicates that button is pressed.</param>
697                 /// <param name="buttonType">Button type to draw.</param>
698                 internal void PaintScrollBar3DButton( 
699                         ChartGraphics graph, 
700                         RectangleF buttonRect, 
701                         bool pressedState, 
702                         ScrollBarButtonType buttonType)
703                 {
704                         // Page Up/Down buttons do not require drawing
705                         if(buttonType == ScrollBarButtonType.LargeIncrement || buttonType == ScrollBarButtonType.LargeDecrement)
706                         {
707                                 return;
708                         }
709
710                         // Get 3 levels of colors for button drawing
711                         Color   darkerColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.Black, 0.5);
712                         Color   darkestColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.Black, 0.8);
713                         Color   lighterColor = ChartGraphics.GetGradientColor(_buttonCurrentColor, Color.White, 0.5);
714
715                         // Fill button rectangle background
716                         graph.FillRectangleRel( 
717                                 buttonRect, 
718                                 _buttonCurrentColor, 
719                                 ChartHatchStyle.None, 
720                                 "", 
721                                 ChartImageWrapMode.Tile,                                
722                                 Color.Empty,
723                                 ChartImageAlignmentStyle.Center,
724                                 GradientStyle.None, 
725                                 Color.Empty, 
726                                 darkerColor,
727                                 (pressedState) ? 1 : 0, 
728                                 ChartDashStyle.Solid, 
729                                 Color.Empty, 
730                                 0, 
731                                 PenAlignment.Outset );
732
733                         // Check if 2 or 1 pixel border will be drawn (if size too small)
734                         bool    singlePixelBorder = this.Size <= 12;
735
736                         // Draw 3D effect around the button when not pressed
737                         if(!pressedState)
738                         {
739                                 // Get relative size of 1 pixel
740                                 SizeF   pixelRelativeSize = new SizeF(1, 1);
741                                 pixelRelativeSize = graph.GetRelativeSize(pixelRelativeSize);
742
743                                 // Draw top/left border with button color
744                                 graph.DrawLineRel(
745                                         (singlePixelBorder) ? lighterColor : _buttonCurrentColor, 1, ChartDashStyle.Solid,
746                                         new PointF(buttonRect.X, buttonRect.Bottom),
747                                         new PointF(buttonRect.X, buttonRect.Top));
748                                 graph.DrawLineRel(
749                                         (singlePixelBorder) ? lighterColor : _buttonCurrentColor, 1, ChartDashStyle.Solid,
750                                         new PointF(buttonRect.Left, buttonRect.Y),
751                                         new PointF(buttonRect.Right, buttonRect.Y));
752
753                                 // Draw right/bottom border with the darkest color
754                                 graph.DrawLineRel(
755                                         (singlePixelBorder) ? darkerColor : darkestColor, 1, ChartDashStyle.Solid,
756                                         new PointF(buttonRect.Right, buttonRect.Bottom),
757                                         new PointF(buttonRect.Right, buttonRect.Top));
758                                 graph.DrawLineRel(
759                                         (singlePixelBorder) ? darkerColor : darkestColor, 1, ChartDashStyle.Solid,
760                                         new PointF(buttonRect.Left, buttonRect.Bottom),
761                                         new PointF(buttonRect.Right, buttonRect.Bottom));
762
763                                 if(!singlePixelBorder)
764                                 {
765                                         // Draw right/bottom border (offset 1) with the dark color
766                                         graph.DrawLineRel(
767                                                 darkerColor, 1, ChartDashStyle.Solid,
768                                                 new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height),
769                                                 new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Top+pixelRelativeSize.Height));
770                                         graph.DrawLineRel(
771                                                 darkerColor, 1, ChartDashStyle.Solid,
772                                                 new PointF(buttonRect.Left+pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height),
773                                                 new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height));
774
775                                         // Draw top/left border (offset 1) with lighter color
776                                         graph.DrawLineRel(
777                                                 lighterColor, 1, ChartDashStyle.Solid,
778                                                 new PointF(buttonRect.X+pixelRelativeSize.Width, buttonRect.Bottom-pixelRelativeSize.Height),
779                                                 new PointF(buttonRect.X+pixelRelativeSize.Width, buttonRect.Top+pixelRelativeSize.Height));
780                                         graph.DrawLineRel(
781                                                 lighterColor, 1, ChartDashStyle.Solid,
782                                                 new PointF(buttonRect.Left+pixelRelativeSize.Width, buttonRect.Y+pixelRelativeSize.Height),
783                                                 new PointF(buttonRect.Right-pixelRelativeSize.Width, buttonRect.Y+pixelRelativeSize.Height));
784                                 }
785                         }
786
787                         // Check axis orientation
788                         bool    verticalAxis = (this.axis.AxisPosition == AxisPosition.Left || 
789                                 this.axis.AxisPosition == AxisPosition.Right) ? true : false;
790
791                         // Set graphics transformation for button pressed mode
792                         float pressedShifting = (singlePixelBorder) ? 0.5f : 1f;
793                         if(pressedState)
794                         {
795                                 graph.TranslateTransform(pressedShifting, pressedShifting);
796                         }
797
798                         // Draw button image
799                         RectangleF      buttonAbsRect = graph.GetAbsoluteRectangle(buttonRect);
800                         float           imageOffset = (singlePixelBorder) ? 2 : 3;
801                         switch(buttonType)
802                         {
803                                 case(ScrollBarButtonType.SmallDecrement):
804                                 {
805                                         // Calculate triangal points position
806                                         PointF[] points = new PointF[3];
807                                         if(verticalAxis)
808                                         {
809                                                 points[0].X = buttonAbsRect.X + imageOffset;
810                                                 points[0].Y = buttonAbsRect.Y + (imageOffset + 1f);
811                                                 points[1].X = buttonAbsRect.X  + buttonAbsRect.Width/2f;
812                                                 points[1].Y = buttonAbsRect.Bottom - imageOffset;
813                                                 points[2].X = buttonAbsRect.Right - imageOffset;
814                                                 points[2].Y = buttonAbsRect.Y + (imageOffset + 1f);
815                                         }
816                                         else
817                                         {
818                                                 points[0].X = buttonAbsRect.X + imageOffset;
819                                                 points[0].Y = buttonAbsRect.Y + buttonAbsRect.Height/2f;
820                                                 points[1].X = buttonAbsRect.Right - (imageOffset + 1f);
821                                                 points[1].Y = buttonAbsRect.Y + imageOffset;
822                                                 points[2].X = buttonAbsRect.Right - (imageOffset + 1f);
823                                                 points[2].Y = buttonAbsRect.Bottom - imageOffset;
824                                         }
825
826                     using (Brush brush = new SolidBrush(this._lineCurrentColor))
827                     {
828                         graph.FillPolygon(brush, points);
829                     }
830                                         break;
831                                 }
832                                 case(ScrollBarButtonType.SmallIncrement):
833                                 {
834                                         // Calculate triangal points position
835                                         PointF[] points = new PointF[3];
836                                         if(verticalAxis)
837                                         {
838                                                 points[0].X = buttonAbsRect.X + imageOffset;
839                                                 points[0].Y = buttonAbsRect.Bottom - (imageOffset + 1f);
840                                                 points[1].X = buttonAbsRect.X  + buttonAbsRect.Width/2f;
841                                                 points[1].Y = buttonAbsRect.Y + imageOffset;
842                                                 points[2].X = buttonAbsRect.Right - imageOffset;
843                                                 points[2].Y = buttonAbsRect.Bottom - (imageOffset + 1f);
844                                         }
845                                         else
846                                         {
847                                                 points[0].X = buttonAbsRect.Right - imageOffset;
848                                                 points[0].Y = buttonAbsRect.Y + buttonAbsRect.Height/2f;
849                                                 points[1].X = buttonAbsRect.X + (imageOffset + 1f);
850                                                 points[1].Y = buttonAbsRect.Y + imageOffset;
851                                                 points[2].X = buttonAbsRect.X + (imageOffset + 1f);
852                                                 points[2].Y = buttonAbsRect.Bottom - imageOffset;
853                                         }
854
855                     using (Brush brush = new SolidBrush(this._lineCurrentColor))
856                     {
857                         graph.FillPolygon(brush, points);
858                     }
859                                         break;
860                                 }
861                                 case(ScrollBarButtonType.ZoomReset):
862                                 {                                               
863                                         // Draw circule with a minus sign
864                     using (Pen pen = new Pen(this._lineCurrentColor, 1))
865                     {
866                         graph.DrawEllipse(pen, buttonAbsRect.X + imageOffset - 0.5f, buttonAbsRect.Y + imageOffset - 0.5f, buttonAbsRect.Width - 2f * imageOffset, buttonAbsRect.Height - 2f * imageOffset);
867                         graph.DrawLine(pen, buttonAbsRect.X + imageOffset + 1.5f, buttonAbsRect.Y + buttonAbsRect.Height / 2f - 0.5f, buttonAbsRect.Right - imageOffset - 2.5f, buttonAbsRect.Y + buttonAbsRect.Height / 2f - 0.5f);
868                     }
869                                         break;
870                                 }
871                         }
872
873                         // Reset graphics transformation for button pressed mode
874                         if(pressedState)
875                         {
876                                 graph.TranslateTransform(-pressedShifting, -pressedShifting);
877                         }
878                 }
879
880 #endregion
881
882 #region Mouse events handling for the Scroll Bar
883
884                 /// <summary>
885                 /// Mouse down event handler.
886                 /// </summary>
887                 internal void ScrollBar_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
888                 {
889                         // Process left mouse button
890                         if(e.Button == MouseButtons.Left && this.IsVisible)
891                         {
892                                 // Remember position where mouse was clicked
893                                 _lastClickMousePosition = new PointF(e.X, e.Y);
894                                 _lastClickViewPosition = this.axis.ScaleView.Position;
895
896                                 // Check if button was pressed inside the scroll bar
897                                 ScrollBarButtonType     buttonType;
898                                 if(GetElementByPixelPosition(e.X, e.Y, out buttonType))
899                                 {
900                                         this.ButtonClicked(buttonType, e.X, e.Y);
901                                 }
902                         }
903                 }
904
905                 /// <summary>
906                 /// Mouse up event handler.
907                 /// </summary>
908                 internal void ScrollBar_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
909                 {
910                         // If scroll bar button was pressed
911                         if(this._pressedButtonType != int.MaxValue)
912                         {
913                                 // Check if button was unpressed inside the reset zoom button
914                                 ScrollBarButtonType     buttonType;
915                                 if(GetElementByPixelPosition(e.X, e.Y, out buttonType))
916                                 {
917                                         if(buttonType == ScrollBarButtonType.ZoomReset)
918                                         {
919                                                 this.ButtonClicked(buttonType, e.X, e.Y);
920                                         }
921                                 }
922
923                                 // Stop scrolling timer
924                                 _scrollTimer.Stop();
925                                 _mouseArguments = null;
926
927                                 // Clear pressed button state
928                                 this._pressedButtonType = int.MaxValue;
929
930                                 // Invalidate chart
931                                 this.axis.Invalidate();
932                         }
933                 }
934
935                 /// <summary>
936                 /// Mouse move event handler.
937                 /// </summary>
938                 internal void ScrollBar_MouseMove(System.Windows.Forms.MouseEventArgs e, ref bool handled)
939                 {
940                         // If scroll bar button was pressed
941                         if(this._pressedButtonType != int.MaxValue)
942                         {
943                                 // Mouse move event should not be handled by any other chart elements
944                                 handled = true;
945
946                                 // Check if tracking buton was pressed
947                                 if((ScrollBarButtonType)this._pressedButtonType == ScrollBarButtonType.ThumbTracker)
948                                 {
949                                         // Proceed if last clicked position is known
950                                         if(!_lastClickMousePosition.IsEmpty)
951                                         {
952                                                 this.ButtonClicked(ScrollBarButtonType.ThumbTracker, e.X, e.Y);
953                                         }
954                                 }
955
956                                 // Non tracking scroll bar button
957                                 else
958                                 {
959                                         // Check if mouse cursor is still in the pressed button's rectangle
960                                         bool inPressedButton = false;
961                                         ScrollBarButtonType     buttonType;
962                                         if(GetElementByPixelPosition(e.X, e.Y, out buttonType))
963                                         {
964                                                 if(buttonType == (ScrollBarButtonType)this._pressedButtonType)
965                                                 {
966                                                         inPressedButton = true;
967                                                 }
968                                         }
969
970                                         // Clear pressed button state
971                                         if(!inPressedButton)
972                                         {
973                                                 // Stop scrolling timer
974                                                 _scrollTimer.Stop();
975                                                 _mouseArguments = null;
976
977                                                 // Clear pressed button state
978                                                 this._pressedButtonType = int.MaxValue;
979
980                                                 // Invalidate chart
981                                                 this.axis.Invalidate();
982                                         }
983                                 }
984                         }
985                 }
986
987                 /// <summary>
988                 /// Scroll bar button was clicked by the user.
989                 /// </summary>
990                 /// <param name="buttonType">Button type.</param>
991                 /// <param name="x">X click position in pixels.</param>
992                 /// <param name="y">Y click position in pixels.</param>
993         [SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Justification = "The timer is used for simulating scrolling behavior")]
994                 private void ButtonClicked(ScrollBarButtonType buttonType, int x, int y)
995                 {
996                         // Call zoom reset on the second pass when button is released
997                         if(buttonType != ScrollBarButtonType.ZoomReset ||
998                                 (ScrollBarButtonType)this._pressedButtonType == buttonType)
999                         {
1000
1001                                 //**************************************************
1002                                 //** Fire scroll bar button clicked event
1003                                 //**************************************************
1004                                 ScrollBarEventArgs      eventArg = new ScrollBarEventArgs(this.axis, x, y, buttonType);
1005                                 this.axis.ScaleView.GetChartObject().OnAxisScrollBarClicked(eventArg);
1006
1007                                 // Check if event was handled by user
1008                                 if(eventArg.IsHandled)
1009                                 {
1010                                         // Save type of the button pressed
1011                                         this._pressedButtonType = (int)buttonType;
1012
1013                                         return;
1014                                 }
1015
1016                                 //**************************************************
1017                                 //** Scroll data scaleView
1018                                 //**************************************************
1019                                 switch(buttonType)
1020                                 {
1021                                         case(ScrollBarButtonType.SmallIncrement):
1022                                                 this.axis.ScaleView.Scroll(ScrollType.SmallIncrement, true);
1023                                                 break;
1024                                         case(ScrollBarButtonType.SmallDecrement):
1025                                                 this.axis.ScaleView.Scroll(ScrollType.SmallDecrement, true);
1026                                                 break;
1027                                         case(ScrollBarButtonType.LargeIncrement):
1028                                                 this.axis.ScaleView.Scroll(ScrollType.LargeIncrement, true);
1029                                                 break;
1030                                         case(ScrollBarButtonType.LargeDecrement):
1031                                                 this.axis.ScaleView.Scroll(ScrollType.LargeDecrement, true);
1032                                                 break;
1033                                         case(ScrollBarButtonType.ZoomReset):
1034                                                 this.axis.ScaleView.ZoomReset(1, true);
1035                                                 break;
1036                                         case(ScrollBarButtonType.ThumbTracker):
1037                                         {
1038                                                 if(!_lastClickMousePosition.IsEmpty && 
1039                                                         !double.IsNaN(this._lastClickViewPosition) &&
1040                                                         (_lastClickMousePosition.X != x || _lastClickMousePosition.Y != y))
1041                                                 {
1042                                                         // Get scroll bar client rectangle
1043                                                         RectangleF      scrollBarRect = this.GetScrollBarRect();
1044                                                         SizeF   borderRelativeSize = new SizeF(1, 1);
1045                                                         borderRelativeSize = this.GetRelativeSize(borderRelativeSize);
1046                                                         RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
1047                                                         scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
1048
1049                                                         // Check axis orientation
1050                                                         bool    verticalAxis = (this.axis.AxisPosition == AxisPosition.Left || 
1051                                                                 this.axis.AxisPosition == AxisPosition.Right) ? true : false;
1052
1053                                                         // Get button relative size
1054                                                         SizeF   buttonSize = new SizeF(scrollBarClientRect.Width, scrollBarClientRect.Height);
1055                                                         buttonSize = this.GetAbsoluteSize(buttonSize);
1056                                                         if(verticalAxis)
1057                                                         {
1058                                                                 buttonSize.Height = buttonSize.Width;
1059                                                         }
1060                                                         else
1061                                                         {
1062                                                                 buttonSize.Width = buttonSize.Height;
1063                                                         }
1064                                                         buttonSize = this.GetRelativeSize(buttonSize);
1065
1066                                                         // Calculate the distance in percentages the mouse was moved 
1067                                                         // from it's original (clicked) position.
1068                                                         float distance = 0f;
1069                                                         double trackingAreaSize = 0f;
1070                                                         if(verticalAxis)
1071                                                         {
1072                                                                 // Calculate max tracking size
1073                                                                 trackingAreaSize = scrollBarClientRect.Height - this.GetButtonsNumberAll() * buttonSize.Height;
1074                                                                 distance = _lastClickMousePosition.Y - y;
1075
1076                                                                 // Convert to relative coordinates
1077                                                                 distance = distance * 100F / ((float)(this.axis.Common.Height - 1));
1078                                                         }
1079                                                         else
1080                                                         {
1081                                                                 trackingAreaSize = scrollBarClientRect.Width - this.GetButtonsNumberAll() * buttonSize.Width;
1082                                                                 distance = x - _lastClickMousePosition.X;
1083
1084                                                                 // Convert to relative coordinates
1085                                                                 distance = distance * 100F / ((float)(this.axis.Common.Width - 1)); 
1086                                                         }
1087
1088                                                         // Convert to percentages from total tracking area
1089                                                         distance = (float)(distance / (trackingAreaSize / 100f));
1090
1091                                                         // Get axis scale size without margins
1092                                                         double  axisScaleSize = Math.Abs(
1093                                                                 (this.axis.maximum - this.axis.marginView) -
1094                                                                 (this.axis.minimum + this.axis.marginView));
1095
1096                                                         // Calculate the same percentage using axis scale
1097                                                         distance = (float)(distance * (axisScaleSize/100f));
1098
1099                                                         // Round the distance to the minimum scroll line size
1100                                                         if(!double.IsNaN(axis.ScaleView.SmallScrollMinSize) && axis.ScaleView.SmallScrollMinSize != 0.0)
1101                                                         {
1102                                 double minSize = ChartHelper.GetIntervalSize(0, axis.ScaleView.SmallScrollMinSize, axis.ScaleView.SmallScrollMinSizeType);
1103
1104                                                                 double rounder = (Math.Round(distance / minSize));
1105                                                                 distance = (float)(rounder * minSize);
1106                                                         }
1107
1108                                                         // Scroll scaleView into the new position
1109                                                         this.axis.ScaleView.Scroll(this._lastClickViewPosition + ((this.axis.IsReversed) ? -1 : 1) * distance, true);
1110                                                 }
1111                                                 break;
1112                                         }
1113                                 }
1114
1115                                 //************************************************************
1116                                 //** Initialize timer for repeating scroll (if mouse is hold)
1117                                 //************************************************************
1118
1119                                 // Reset mouse arguments
1120                                 _mouseArguments = null;
1121
1122                                 if(buttonType != ScrollBarButtonType.ThumbTracker && buttonType != ScrollBarButtonType.ZoomReset)
1123                                 {
1124                                         // Remember last mouse position
1125                                         _mouseArguments = new MouseEventArgs(MouseButtons.Left, 1, x, y, 0);
1126
1127                                         // Enable timer
1128                                         if(!_scrollTimer.Enabled)
1129                                         {
1130                                                 _scrollTimer.Tick += new EventHandler(ScrollingTimerEventProcessor);
1131                                                 _scrollTimer.Interval = 400;
1132                                                 _scrollTimer.Start();
1133                                         }
1134                                 }
1135                         }
1136
1137                         //************************************************************
1138                         //** Invalidate chart
1139                         //************************************************************
1140                         
1141                         // Save type of the button pressed
1142                         this._pressedButtonType = (int)buttonType;
1143
1144                         // Invalidate
1145                         this.axis.Invalidate();
1146                 }
1147
1148                 /// <summary>
1149                 /// This is the method to run when the timer is raised.
1150                 /// Used to repetedly scroll data scaleView while mouse button is pressed.
1151                 /// </summary>
1152                 /// <param name="myObject">Object.</param>
1153                 /// <param name="myEventArgs">Event arguments.</param>
1154         [SuppressMessage("Microsoft.Mobility", "CA1601:DoNotUseTimersThatPreventPowerStateChanges", Justification = "The timer is used for simulating scrolling behavior")]
1155                 private void ScrollingTimerEventProcessor(Object myObject, EventArgs myEventArgs) 
1156                 {
1157                         // Simulate mouse move events
1158                         if(_mouseArguments != null)
1159                         {
1160                                 _scrollTimer.Interval = 200;
1161                                 this.ScrollBar_MouseDown(null, _mouseArguments);
1162                         }
1163                 }
1164
1165                 /// <summary>
1166                 /// This method fills hot region collection with scroll bar elements.
1167                 /// Possible elements are all scroll bar buttons and scroll bar background
1168                 /// which performs PgUp/PgDn action.
1169                 /// </summary>
1170                 /// <param name="common">Common Elements</param>
1171                 private void SetHotRegionElement( CommonElements common )
1172                 {
1173                         // Check if mouse button was clicked in the scroll bar
1174                         RectangleF      scrollBarRect = this.GetScrollBarRect();
1175
1176                         // Get scroll bar client rectangle
1177                         SizeF   borderRelativeSize = new SizeF(1, 1);
1178                         borderRelativeSize = this.GetRelativeSize(borderRelativeSize);
1179                         RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
1180                         scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
1181                         
1182                         ChartElementType buttonType = ChartElementType.Nothing;
1183
1184                         // Fill collection with scroll buttons rectangles.
1185                         foreach(object type in Enum.GetValues(typeof(ScrollBarButtonType)))
1186                         {
1187
1188                                 // Convert Scroll Bar Button type enum to Chart Element AxisName enum.
1189                                 switch( (ScrollBarButtonType)type )
1190                                 {
1191                                         case ScrollBarButtonType.SmallIncrement:
1192                                                 buttonType = ChartElementType.ScrollBarSmallIncrement;
1193                                                 break;
1194                                         case ScrollBarButtonType.LargeIncrement:
1195                                                 buttonType = ChartElementType.ScrollBarLargeIncrement;
1196                                                 break;
1197                                         case ScrollBarButtonType.LargeDecrement:
1198                                                 buttonType = ChartElementType.ScrollBarLargeDecrement;
1199                                                 break;
1200                                         case ScrollBarButtonType.ThumbTracker:
1201                                                 buttonType = ChartElementType.ScrollBarThumbTracker;
1202                                                 break;
1203                                         case ScrollBarButtonType.SmallDecrement:
1204                                                 buttonType = ChartElementType.ScrollBarSmallDecrement;
1205                                                 break;
1206                                         case ScrollBarButtonType.ZoomReset:
1207                                                 buttonType = ChartElementType.ScrollBarZoomReset;
1208                                                 break;
1209                                 }
1210
1211                                 // Get button rectangle
1212                                 RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)type);
1213
1214                                 common.HotRegionsList.AddHotRegion( buttonRect, this, buttonType, true );
1215                                 
1216                         }
1217                 }
1218
1219                 /// <summary>
1220                 /// Detects the scroll bar elements by pixel position.
1221                 /// Possible elements are all scroll bar buttons and scroll bar background
1222                 /// which performs PgUp/PgDn action.
1223                 /// </summary>
1224                 /// <param name="x">X coordinate in pixels.</param>
1225                 /// <param name="y">Y coordinate in pixels.</param>
1226                 /// <param name="buttonType">Return button type.</param>
1227                 /// <returns>True if position is in the scroll bar.</returns>
1228                 private bool GetElementByPixelPosition(float x, float y, out ScrollBarButtonType buttonType)
1229                 {
1230                         // Set initial values 
1231                         buttonType = ScrollBarButtonType.ThumbTracker;
1232
1233                         // Convert mouse click coordinates to relative
1234                         PointF  position = new PointF(x, y);
1235                         position.X = x * 100F / ((float)(this.axis.Common.Width - 1)); 
1236                         position.Y = y * 100F / ((float)(this.axis.Common.Height - 1)); 
1237
1238                         // Check if mouse button was clicked in the scroll bar
1239                         RectangleF      scrollBarRect = this.GetScrollBarRect();
1240                         if(scrollBarRect.Contains(position))
1241                         {
1242                                 // Get scroll bar client rectangle
1243                                 SizeF   borderRelativeSize = new SizeF(1, 1);
1244                                 borderRelativeSize = this.GetRelativeSize(borderRelativeSize);
1245                                 RectangleF scrollBarClientRect = new RectangleF(scrollBarRect.Location, scrollBarRect.Size);
1246                                 scrollBarClientRect.Inflate(-borderRelativeSize.Width, -borderRelativeSize.Height);
1247
1248                                 //******************************************************************
1249                                 //** Check if scroll bar button was clicked
1250                                 //******************************************************************
1251                                 foreach(object type in Enum.GetValues(typeof(ScrollBarButtonType)))
1252                                 {
1253                                         // Get button rectangle
1254                                         RectangleF buttonRect = this.GetScrollBarButtonRect(scrollBarClientRect, (ScrollBarButtonType)type);
1255
1256                                         // Check if position is inside the button
1257                                         if(buttonRect.Contains(position))
1258                                         {
1259                                                 buttonType = (ScrollBarButtonType)type;
1260                                                 return true;
1261                                         }
1262                                 }
1263                         }
1264
1265                         // Pixel position is outside scroll bar area
1266                         return false;
1267                 }
1268
1269 #endregion
1270
1271 #region Scroll bar helper methods
1272
1273                 /// <summary>
1274                 /// Returns scroll bar button rectangle position in relative coordinates.
1275                 /// </summary>
1276                 /// <param name="scrollBarClientRect">Scroll bar client rectangle.</param>
1277                 /// <param name="buttonType">Scroll bar button type.</param>
1278                 /// <returns>Scroll bar position.</returns>
1279                 internal RectangleF GetScrollBarButtonRect(RectangleF scrollBarClientRect, ScrollBarButtonType buttonType)
1280                 {
1281                         // Initialize button rectangle
1282                         RectangleF      buttonRect = new RectangleF(scrollBarClientRect.Location, scrollBarClientRect.Size);
1283
1284                         // Check axis orientation
1285                         bool    verticalAxis = (this.axis.AxisPosition == AxisPosition.Left || 
1286                                 this.axis.AxisPosition == AxisPosition.Right) ? true : false;
1287
1288                         // Get relative size of 1 pixel
1289                         SizeF   pixelRelativeSize = new SizeF(1, 1);
1290                         pixelRelativeSize = this.GetRelativeSize(pixelRelativeSize);
1291
1292                         // Get button relative size
1293                         SizeF   buttonSize = new SizeF(scrollBarClientRect.Width, scrollBarClientRect.Height);
1294                         buttonSize = this.GetAbsoluteSize(buttonSize);
1295                         if(verticalAxis)
1296                         {
1297                                 buttonSize.Height = buttonSize.Width;
1298                         }
1299                         else
1300                         {
1301                                 buttonSize.Width = buttonSize.Height;
1302                         }
1303                         buttonSize = this.GetRelativeSize(buttonSize);
1304
1305                         // Set common position sizes
1306                         buttonRect.Width = buttonSize.Width;
1307                         buttonRect.Height = buttonSize.Height;
1308                         if(verticalAxis)
1309                         {
1310                                 buttonRect.X = scrollBarClientRect.X;
1311                         }
1312                         else
1313                         {
1314                                 buttonRect.Y = scrollBarClientRect.Y;
1315                         }
1316
1317                         // Calculate scroll bar buttons position
1318                         switch(buttonType)
1319                         {
1320                                 case(ScrollBarButtonType.LargeDecrement):
1321                                 case(ScrollBarButtonType.LargeIncrement):
1322                                 case(ScrollBarButtonType.ThumbTracker):
1323                                 {
1324                                         // Get tracker button position and size first
1325                                         if(verticalAxis)
1326                                         {
1327                                                 // Calculate tracker size
1328                                                 double trackingAreaSize = scrollBarClientRect.Height - this.GetButtonsNumberAll() * buttonSize.Height;
1329                                                 buttonRect.Height = (float)(this.GetDataViewPercentage() * (trackingAreaSize / 100f));
1330
1331                                                 // Check if tracker size is too small
1332                                                 if(buttonRect.Height < pixelRelativeSize.Height * 6f)
1333                                                 {
1334                                                         buttonRect.Height = pixelRelativeSize.Height * 6f;
1335                                                 }
1336
1337                                                 // Calculate tracker position
1338                                                 if(!this.axis.IsReversed)
1339                                                 {
1340                                                         buttonRect.Y = scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - buttonRect.Height;
1341                                                         buttonRect.Y -=  (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
1342                                                         if(buttonRect.Y < scrollBarClientRect.Y + this.GetButtonsNumberTop()*buttonSize.Height + ((this.GetButtonsNumberTop() == 0) ? 0 : pixelRelativeSize.Height))
1343                                                         {
1344                                                                 buttonRect.Y = scrollBarClientRect.Y + this.GetButtonsNumberTop()*buttonSize.Height + ((this.GetButtonsNumberTop() == 0) ? 0 : pixelRelativeSize.Height);
1345                                                         }
1346                                                 }
1347                                                 else
1348                                                 {
1349                                                         buttonRect.Y = scrollBarClientRect.Top + this.GetButtonsNumberTop()*buttonSize.Height;
1350                                                         buttonRect.Y +=  (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
1351                                                         if((buttonRect.Y + buttonRect.Height) > scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Height))
1352                                                         {
1353                                                                 buttonRect.Y = (scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height) - buttonRect.Height - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Height);
1354                                                         }
1355                                                 }
1356                                         }
1357                                         else
1358                                         {
1359                                                 // Calculate tracker size
1360                                                 double trackingAreaSize = scrollBarClientRect.Width - this.GetButtonsNumberAll() * buttonSize.Width;
1361                                                 buttonRect.Width = (float)(this.GetDataViewPercentage() * (trackingAreaSize / 100f));
1362
1363                                                 // Check if tracker size is too small
1364                                                 if(buttonRect.Width < pixelRelativeSize.Width * 6f)
1365                                                 {
1366                                                         buttonRect.Width = pixelRelativeSize.Width * 6f;
1367                                                 }
1368
1369                                                 // Calculate tracker position
1370                                                 if(!this.axis.IsReversed)
1371                                                 {
1372                                                         buttonRect.X = scrollBarClientRect.X + this.GetButtonsNumberTop() * buttonSize.Width;
1373                                                         buttonRect.X +=  (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
1374                                                         if((buttonRect.X + buttonRect.Width) > scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width))
1375                                                         {
1376                                                                 buttonRect.X = (scrollBarClientRect.Right - buttonRect.Width) - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width);
1377                                                         }
1378                                                 }
1379                                                 else
1380                                                 {
1381                                                         buttonRect.X = scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - ((this.GetButtonsNumberBottom() == 0) ? 0 : pixelRelativeSize.Width) - buttonRect.Width;
1382                                                         buttonRect.X -=  (float)(this.GetDataViewPositionPercentage() * (trackingAreaSize / 100f));
1383                                                         if(buttonRect.X < scrollBarClientRect.X + this.GetButtonsNumberTop()*buttonSize.Width)
1384                                                         {
1385                                                                 buttonRect.X = scrollBarClientRect.X + this.GetButtonsNumberTop()*buttonSize.Width;
1386                                                         }
1387                                                 }
1388
1389                                         }
1390
1391                                         // Get page up region rectangle depending on the tracker position
1392                                         if(buttonType == ScrollBarButtonType.LargeDecrement)
1393                                         {
1394                                                 if(verticalAxis)
1395                                                 {
1396                                                         buttonRect.Y = buttonRect.Bottom + pixelRelativeSize.Height;
1397                                                         buttonRect.Height = (scrollBarClientRect.Bottom - this.GetButtonsNumberBottom()*buttonSize.Height - pixelRelativeSize.Height) - buttonRect.Y;
1398                                                 }
1399                                                 else
1400                                                 {
1401                                                         float x = scrollBarClientRect.X + 
1402                                                                 this.GetButtonsNumberTop() * buttonSize.Width + 
1403                                                                 pixelRelativeSize.Width;
1404
1405                                                         buttonRect.Width = buttonRect.X - x;
1406                                                         buttonRect.X = x;
1407                                                 }
1408                                         }
1409
1410                                         // Get page down region rectangle depending on the tracker position
1411                                         else if(buttonType == ScrollBarButtonType.LargeIncrement)
1412                                         {
1413                                                 if(verticalAxis)
1414                                                 {
1415                                                         float y = scrollBarClientRect.Y + 
1416                                                                 this.GetButtonsNumberTop() * buttonSize.Height + 
1417                                                                 pixelRelativeSize.Height;
1418
1419                                                         buttonRect.Height = buttonRect.Y - y;
1420                                                         buttonRect.Y = y;
1421                                                 }
1422                                                 else
1423                                                 {
1424                                                         buttonRect.X = buttonRect.Right + pixelRelativeSize.Width;
1425                                                         buttonRect.Width = (scrollBarClientRect.Right - this.GetButtonsNumberBottom()*buttonSize.Width - pixelRelativeSize.Height) - buttonRect.X;
1426                                                 }
1427                                         }
1428
1429                                         break;
1430                                 }
1431
1432                                 case(ScrollBarButtonType.SmallDecrement):
1433                                         if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All ||
1434                                                 this._scrollBarButtonStyle == ScrollBarButtonStyles.SmallScroll)
1435                                         {
1436                                                 if(verticalAxis)
1437                                                 {
1438                                                         buttonRect.Y = scrollBarClientRect.Bottom - buttonRect.Height;
1439                                                 }
1440                                                 else
1441                                                 {
1442                                                         buttonRect.X = scrollBarClientRect.X + (this.GetButtonsNumberTop()-1f)*buttonSize.Width;
1443                                                         buttonRect.X += (this.GetButtonsNumberTop() == 1) ? 0 : pixelRelativeSize.Width;
1444                                                 }
1445                                         }
1446                                         else
1447                                         {
1448                                                 buttonRect = RectangleF.Empty;
1449                                         }
1450                                         break;
1451
1452                                 case(ScrollBarButtonType.SmallIncrement):
1453                                         if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All ||
1454                                                 this._scrollBarButtonStyle == ScrollBarButtonStyles.SmallScroll)
1455                                         {
1456                                                 if(verticalAxis)
1457                                                 {
1458                                                         buttonRect.Y = scrollBarClientRect.Y + (this.GetButtonsNumberTop()-1f) * buttonSize.Height;
1459                                                         buttonRect.Y += (this.GetButtonsNumberTop() == 1) ? 0 : pixelRelativeSize.Height;
1460                                                 }
1461                                                 else
1462                                                 {
1463                                                         buttonRect.X = scrollBarClientRect.Right - buttonRect.Width;
1464                                                 }
1465                                         }
1466                                         else
1467                                         {
1468                                                 buttonRect = RectangleF.Empty;
1469                                         }
1470                                         break;
1471
1472                                 case(ScrollBarButtonType.ZoomReset):
1473                                         if(this._scrollBarButtonStyle == ScrollBarButtonStyles.All ||
1474                                                 this._scrollBarButtonStyle == ScrollBarButtonStyles.ResetZoom)
1475                                         {
1476                                                 if(verticalAxis)
1477                                                 {
1478                                                         buttonRect.Y = scrollBarClientRect.Y;
1479                                                 }
1480                                                 else
1481                                                 {
1482                                                         buttonRect.X = scrollBarClientRect.X;
1483                                                 }
1484                                         }
1485                                         else
1486                                         {
1487                                                 buttonRect = RectangleF.Empty;
1488                                         }
1489                                         break;
1490                         }
1491
1492                         return buttonRect;
1493                 }
1494
1495                 /// <summary>
1496                 /// Returns scroll bar rectangle position in relative coordinates.
1497                 /// </summary>
1498                 /// <returns>Scroll bar position.</returns>
1499                 internal RectangleF GetScrollBarRect()
1500                 {
1501                         // Get scroll bar relative size
1502                         float   scrollBarSize = (float)this.GetScrollBarRelativeSize();
1503
1504                         // Get relative size of the axis line (Note: Code removed for now. -- AG)
1505                         //SizeF axisLineSize = new SizeF(axis.LineWidth, axis.LineWidth);
1506                         //axisLineSize.Width =  axisLineSize.Width * 100F / ((float)(this.axis.Common.Width - 1)); 
1507                         //axisLineSize.Height = axisLineSize.Height * 100F / ((float)(this.axis.Common.Height - 1)); 
1508
1509                         // Check if scroll bar is positioned next to PlotArea or ChartArea
1510                         RectangleF      areaPosition = axis.PlotAreaPosition.ToRectangleF();
1511                         if(!this.IsPositionedInside)
1512                         {
1513                                 areaPosition = axis.ChartArea.Position.ToRectangleF();
1514
1515                                 // Reduce rectangle size by scroll bar size
1516                                 foreach(Axis a in this.ChartArea.Axes)
1517                                 {
1518                                         if(a.ScrollBar.IsVisible && !a.ScrollBar.IsPositionedInside)
1519                                         {
1520                                                 float   size = (float)a.ScrollBar.GetScrollBarRelativeSize();
1521                                                 switch( a.AxisPosition )
1522                                                 {
1523                                                         case AxisPosition.Left:
1524                                                                 areaPosition.X += size;
1525                                                                 areaPosition.Width -= size;
1526                                                                 break;
1527                                                         case AxisPosition.Right:
1528                                                                 areaPosition.Width -= size;
1529                                                                 break;
1530                                                         case AxisPosition.Bottom:
1531                                                                 areaPosition.Height -= size;
1532                                                                 break;
1533                                                         case AxisPosition.Top:
1534                                                                 areaPosition.Y += size;
1535                                                                 areaPosition.Height -= size;
1536                                                                 break;
1537                                                 }
1538                                         }
1539                                 }
1540                         }
1541
1542                         // Get bar position depending on the axis type
1543                         RectangleF      barPosition = RectangleF.Empty;
1544                         if(this.axis.PlotAreaPosition != null)
1545                         {
1546                                 switch( axis.AxisPosition )
1547                                 {
1548                                         case AxisPosition.Left:
1549                                                 barPosition.Y = areaPosition.Y;
1550                                                 barPosition.Height = areaPosition.Height;
1551                                                 barPosition.X = 
1552                                                         ( (this.IsPositionedInside) ? (float)(axis.GetAxisPosition(true)) : areaPosition.X) - scrollBarSize;// - axisLineSize.Width / 2f;
1553                                                 barPosition.Width = scrollBarSize;
1554                                                 break;
1555                                         case AxisPosition.Right:
1556                                                 barPosition.Y = areaPosition.Y;
1557                                                 barPosition.Height = areaPosition.Height;
1558                                                 barPosition.X = 
1559                                                         (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Right;// + axisLineSize.Width / 2f;
1560                                                 barPosition.Width = scrollBarSize;
1561                                                 break;
1562                                         case AxisPosition.Bottom:
1563                                                 barPosition.X = areaPosition.X;
1564                                                 barPosition.Width = areaPosition.Width;
1565                                                 barPosition.Y = 
1566                                                         (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Bottom;// + axisLineSize.Height / 2f;
1567                                                 barPosition.Height = scrollBarSize;
1568                                                 break;
1569                                         case AxisPosition.Top:
1570                                                 barPosition.X = areaPosition.X;
1571                                                 barPosition.Width = areaPosition.Width;
1572                                                 barPosition.Y = 
1573                                                         ( (this.IsPositionedInside) ? (float)axis.GetAxisPosition(true) : areaPosition.Y) - scrollBarSize;// - axisLineSize.Height / 2f;
1574                                                 barPosition.Height = scrollBarSize;
1575                                                 break;
1576                                 }
1577                         }
1578                 
1579                         return barPosition;
1580                 }
1581
1582                 /// <summary>
1583                 /// Internal helper method which returns the relative scroll bar size.
1584                 /// </summary>
1585                 /// <returns>Relative scroll bar size.</returns>
1586                 internal double GetScrollBarRelativeSize()
1587                 {
1588                         // Scroll bar is not shown in 3D
1589                         if(this.axis.ChartArea.Area3DStyle.Enable3D || this.axis.ChartArea.chartAreaIsCurcular)
1590                         {
1591                                 return 0.0;
1592             }
1593
1594 #if SUBAXES
1595                         // Scrollbar not supported on sub axis
1596                         if( this.axis != null &&  this.axis.IsSubAxis)
1597                         {
1598                                 return 0.0;
1599                         }
1600 #endif //SUBAXES
1601
1602
1603             // Get scroll bar relative size depending on the axis location
1604                         if(this.axis.AxisPosition == AxisPosition.Left || this.axis.AxisPosition == AxisPosition.Right)
1605                         {
1606                                 return this._scrollBarSize * 100F / ((float)(this.axis.Common.Width - 1)); 
1607                         }
1608                         else
1609                         {
1610                                 return this._scrollBarSize * 100F / ((float)(this.axis.Common.Height - 1)); 
1611                         }
1612                 }
1613
1614                 /// <summary>
1615                 /// Returns the percentage size (0-100%) of the data scaleView comparing to 
1616                 /// the axis scale minimum and maximum values.
1617                 /// </summary>
1618                 /// <returns>Size of the data scaleView in percentage.</returns>
1619                 private double GetDataViewPercentage()
1620                 {
1621                         double  viewPercentage = 100.0;
1622
1623                         // Check if axis data scaleView properties are set
1624                         if(this.axis != null &&
1625                                 !double.IsNaN(this.axis.ScaleView.Position) &&
1626                                 !double.IsNaN(this.axis.ScaleView.Size))
1627                         {
1628                                 // Get data scaleView size 
1629                 double dataViewSize = ChartHelper.GetIntervalSize(
1630                                         this.axis.ScaleView.Position,
1631                                         this.axis.ScaleView.Size,
1632                                         this.axis.ScaleView.SizeType);
1633
1634                                 // Get axis scale size without margins
1635                                 double  minimum = this.axis.minimum + this.axis.marginView;
1636                                 double  maximum = this.axis.maximum - this.axis.marginView;
1637                                 if(this.axis.ScaleView.Position < minimum)
1638                                 {
1639                                         minimum = this.axis.ScaleView.Position;
1640                                 }
1641                                 if((this.axis.ScaleView.Position + dataViewSize) > maximum)
1642                                 {
1643                                         maximum = this.axis.ScaleView.Position + dataViewSize;
1644                                 }
1645                                 double  axisScaleSize = Math.Abs(minimum - maximum);
1646
1647                                 // Check if data scaleView is smaller than axis scale and if it is find the pecentage
1648                                 if(dataViewSize < axisScaleSize)
1649                                 {
1650                                         viewPercentage = dataViewSize / (axisScaleSize / 100.0);
1651                                 }
1652                         }
1653
1654                         return viewPercentage;
1655                 }
1656
1657                 /// <summary>
1658                 /// Returns the the data scaleView position in percentage (0-100%) using 
1659                 /// the axis scale minimum and maximum values.
1660                 /// </summary>
1661                 /// <returns>Data scaleView position in percentage.</returns>
1662                 private double GetDataViewPositionPercentage()
1663                 {
1664                         double  viewPosition = 0.0;
1665
1666                         // Check if axis data scaleView properties are set
1667                         if(this.axis != null &&
1668                                 !double.IsNaN(this.axis.ScaleView.Position) &&
1669                                 !double.IsNaN(this.axis.ScaleView.Size))
1670                         {
1671                                 // Get data scaleView size 
1672                 double dataViewSize = ChartHelper.GetIntervalSize(
1673                                         this.axis.ScaleView.Position,
1674                                         this.axis.ScaleView.Size,
1675                                         this.axis.ScaleView.SizeType);
1676
1677                                 // Get axis scale size without margins
1678                                 double  minimum = this.axis.minimum + this.axis.marginView;
1679                                 double  maximum = this.axis.maximum - this.axis.marginView;
1680                                 if(this.axis.ScaleView.Position < minimum)
1681                                 {
1682                                         minimum = this.axis.ScaleView.Position;
1683                                 }
1684                                 if((this.axis.ScaleView.Position + dataViewSize) > maximum)
1685                                 {
1686                                         maximum = this.axis.ScaleView.Position + dataViewSize;
1687                                 }
1688                                 double  axisScaleSize = Math.Abs(minimum - maximum);
1689
1690                                 // Calculate data scaleView position in percentage
1691                                 viewPosition = (this.axis.ScaleView.Position - (minimum)) / (axisScaleSize / 100.0);
1692                         }
1693
1694                         return viewPosition;
1695                 }
1696
1697                 /// <summary>
1698                 /// Get total number of buttons in the scroll bar (except tracker).
1699                 /// </summary>
1700                 /// <returns>Number of buttons.</returns>
1701                 private int GetButtonsNumberAll()
1702                 {
1703                         int buttonNumber = 0;
1704                         if((this._scrollBarButtonStyle & ScrollBarButtonStyles.ResetZoom) == ScrollBarButtonStyles.ResetZoom)
1705                         {
1706                                 buttonNumber += 1;
1707                         }
1708                         if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll)
1709                         {
1710                                 buttonNumber += 2;
1711                         }
1712
1713                         return buttonNumber;
1714                 }
1715
1716                 /// <summary>
1717                 /// Get number of buttons in the top (left) part of the scroll bar.
1718                 /// </summary>
1719                 /// <returns>Number of buttons.</returns>
1720                 private int GetButtonsNumberTop()
1721                 {
1722                         int buttonNumber = 0;
1723                         if((this._scrollBarButtonStyle & ScrollBarButtonStyles.ResetZoom) == ScrollBarButtonStyles.ResetZoom)
1724                         {
1725                                 buttonNumber += 1;
1726                         }
1727                         if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll)
1728                         {
1729                                 buttonNumber += 1;
1730                         }
1731
1732                         return buttonNumber;
1733                 }
1734
1735                 /// <summary>
1736                 /// Get number of buttons in the bottom (right) part of the scroll bar.
1737                 /// </summary>
1738                 /// <returns>Number of buttons.</returns>
1739                 private int GetButtonsNumberBottom()
1740                 {
1741                         int buttonNumber = 0;
1742                         if((this._scrollBarButtonStyle & ScrollBarButtonStyles.SmallScroll) == ScrollBarButtonStyles.SmallScroll)
1743                         {
1744                                 buttonNumber += 1;
1745                         }
1746
1747                         return buttonNumber;
1748                 }
1749
1750 #endregion
1751
1752 #region Coordinate convertion methods
1753
1754                 /// <summary>
1755                 /// Converts Relative size to Absolute size
1756                 /// </summary>
1757                 /// <param name="relative">Relative size in %</param>
1758                 /// <returns>Absolute size</returns>
1759                 internal SizeF GetAbsoluteSize( SizeF relative )
1760                 {
1761                         SizeF absolute = SizeF.Empty;
1762
1763                         // Convert relative coordinates to absolute coordinates
1764                         absolute.Width = relative.Width * (this.axis.Common.Width - 1) / 100F; 
1765                         absolute.Height = relative.Height * (this.axis.Common.Height - 1) / 100F; 
1766                         
1767                         // Return Absolute coordinates
1768                         return absolute;
1769                 }
1770
1771                 /// <summary>
1772                 /// Converts Absolute size to Relative size
1773                 /// </summary>
1774                 /// <param name="size">Absolute size</param>
1775                 /// <returns>Relative size</returns>
1776                 internal SizeF GetRelativeSize( SizeF size )
1777                 {
1778                         SizeF relative = SizeF.Empty;
1779
1780                         // Convert absolute coordinates to relative coordinates
1781                         relative.Width = size.Width * 100F / ((float)(this.axis.Common.Width - 1)); 
1782                         relative.Height = size.Height * 100F / ((float)(this.axis.Common.Height - 1)); 
1783                         
1784                         // Return relative coordinates
1785                         return relative;
1786                 }
1787
1788 #endregion
1789
1790 #region IDisposable Members
1791
1792         /// <summary>
1793         /// Releases unmanaged and - optionally - managed resources
1794         /// </summary>
1795         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
1796         protected virtual void Dispose(bool disposing)
1797         {
1798             if (disposing)
1799             {
1800                 // Dispose managed resources
1801                 if (this._scrollTimer != null)
1802                 {
1803                     this._scrollTimer.Dispose();
1804                     this._scrollTimer = null;
1805                 }
1806             }
1807         }
1808
1809         /// <summary>
1810         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
1811         /// </summary>
1812         public void Dispose()
1813         {
1814             Dispose(true);
1815             GC.SuppressFinalize(this);
1816         }
1817
1818         #endregion
1819     }
1820
1821         /// <summary>
1822         /// The arguments for a scrollbar event.
1823         /// </summary>
1824     public class ScrollBarEventArgs : EventArgs
1825         {
1826 #region Private fields
1827
1828                 // Private fields for properties values storage
1829                 private         Axis                                    _axis = null;
1830                 private         bool                                    _isHandled = false;
1831                 private         int                                             _mousePositionX = 0;
1832                 private         int                                             _mousePositionY = 0;
1833                 private         ScrollBarButtonType             _buttonType = ScrollBarButtonType.ThumbTracker;
1834
1835 #endregion
1836
1837 #region Constructors
1838
1839                 /// <summary>
1840                 /// ScrollBarEventArgs constructor.
1841                 /// </summary>
1842                 /// <param name="axis">Axis containing the scrollbar.</param>
1843                 /// <param name="x">X position of mouse cursor.</param>
1844                 /// <param name="y">Y position of mouse cursor.</param>
1845                 /// <param name="buttonType">Button type of the button clicked.</param>
1846         [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
1847             Justification = "X and Y are cartesian coordinates and well understood")]
1848                 public ScrollBarEventArgs(Axis axis, int x, int y, ScrollBarButtonType buttonType)
1849                 {
1850                         this._axis = axis;
1851                         this._mousePositionX = x;
1852                         this._mousePositionY = y;
1853                         this._buttonType = buttonType;
1854                 }
1855
1856 #endregion
1857
1858 #region Properties
1859
1860                 /// <summary>
1861                 /// Axis containing the scrollbar of the event.
1862                 /// </summary>
1863                 [
1864                 SRDescription("DescriptionAttributeAxis"),
1865                 ]
1866                 public Axis Axis
1867                 {
1868                         get
1869                         {
1870                                 return _axis;
1871                         }
1872                 }
1873
1874                 /// <summary>
1875                 /// ChartArea containing the scrollbar of the event.
1876                 /// </summary>
1877                 [
1878                 SRDescription("DescriptionAttributeChartArea"),
1879                 ]
1880                 public ChartArea ChartArea
1881                 {
1882                         get
1883                         {
1884                                 return _axis.ChartArea;
1885                         }
1886                 }
1887
1888                 /// <summary>
1889                 /// Button type of the scrollbar button clicked.
1890                 /// </summary>
1891                 [
1892                 SRDescription("DescriptionAttributeScrollBarEventArgs_ButtonType"),
1893                 ]
1894         public ScrollBarButtonType ButtonType
1895                 {
1896                         get
1897                         {
1898                                 return _buttonType;
1899                         }
1900                 }
1901                 
1902                 /// <summary>
1903                 /// Indicates if the event is handled by the user and no further processing is required.
1904                 /// </summary>
1905                 [
1906                 SRDescription("DescriptionAttributeScrollBarEventArgs_Handled"),
1907                 ]
1908                 public bool IsHandled
1909                 {
1910                         get
1911                         {
1912                                 return _isHandled;
1913                         }
1914                         set
1915                         {
1916                                 _isHandled = value;
1917                         }
1918                 }
1919
1920                 /// <summary>
1921                 /// X position of mouse cursor.
1922                 /// </summary>
1923                 [
1924                 SRDescription("DescriptionAttributeScrollBarEventArgs_MousePositionX"),
1925                 ]
1926                 public int MousePositionX
1927                 {
1928                         get
1929                         {
1930                                 return _mousePositionX;
1931                         }
1932                 }
1933
1934                 /// <summary>
1935                 /// Y position of mouse cursor.
1936                 /// </summary>
1937                 [
1938                 SRDescription("DescriptionAttributeScrollBarEventArgs_MousePositionY"),
1939                 ]
1940                 public int MousePositionY
1941                 {
1942                         get
1943                         {
1944                                 return _mousePositionY;
1945                         }
1946                 }
1947
1948 #endregion
1949         }
1950 }
1951
1952 #endif  // #if WINFORMS_CONTROL