Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Web.DataVisualization / Common / General / Title.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:               Title.cs
9 //
10 //  Namespace:  DataVisualization.Charting
11 //
12 //      Classes:        TitleCollection, Title, Docking
13 //
14 //  Purpose:    Titles can be added to the chart by simply including 
15 //              those titles into the Titles collection, which is 
16 //              found in the root Chart object. The Title object 
17 //              incorporates several properties that can be used to 
18 //              position, dock, and control the appearance of any 
19 //              Title. Title positioning can be explicitly set, or 
20 //              you can specify that your title be docked. The 
21 //              charting control gives you full control over all of 
22 //              the appearance properties of your Titles, so you have 
23 //              the ability to set specific properties for such things 
24 //              as fonts, or colors, and even text effects. 
25 //
26 // NOTE: In early versions of the Chart control only 1 title was 
27 // exposed through the Title, TitleFont and TitleFontColor properties 
28 // in the root chart object. Due to the customer requests, support for 
29 // unlimited number of titles was added through the TitleCollection 
30 // exposed as a Titles property of the root chart object. Old 
31 // properties were deprecated and marked as non-browsable. 
32 //
33 //      Reviewed:       AG - Microsoft 13, 2007
34 //
35 //===================================================================
36
37 #region Used namespaces
38
39 using System;
40 using System.Collections;
41 using System.Collections.Specialized;
42 using System.ComponentModel;
43 using System.ComponentModel.Design;
44 using System.Data;
45 using System.Drawing;
46 using System.Drawing.Design;
47 using System.Drawing.Drawing2D;
48 using System.Diagnostics.CodeAnalysis;
49 using System.Globalization;
50
51 #if Microsoft_CONTROL
52         using System.Windows.Forms.DataVisualization.Charting;
53         using System.Windows.Forms.DataVisualization.Charting.Data;
54         using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
55         using System.Windows.Forms.DataVisualization.Charting.Utilities;
56         using System.Windows.Forms.DataVisualization.Charting.Borders3D;
57         using System.ComponentModel.Design.Serialization;
58         using System.Reflection;
59         using System.Windows.Forms.Design;
60 #else
61 using System.Web;
62 using System.Web.UI;
63 using System.Web.UI.DataVisualization.Charting;
64 using System.Web.UI.DataVisualization.Charting.Data;
65 using System.Web.UI.DataVisualization.Charting.Utilities;
66 #endif
67
68
69 #endregion
70
71 #if Microsoft_CONTROL
72         namespace System.Windows.Forms.DataVisualization.Charting
73 #else
74 namespace System.Web.UI.DataVisualization.Charting
75
76 #endif
77 {
78         #region Title enumerations
79
80                 /// <summary>
81                 /// An enumeration of chart element docking styles.
82                 /// </summary>
83                 public enum Docking
84                 {
85                         /// <summary>
86                         /// Docked to the top.
87                         /// </summary>
88                         Top, 
89
90                         /// <summary>
91                         /// Docked to the right.
92                         /// </summary>
93                         Right,
94
95             /// <summary>
96             /// Docked to the bottom.
97             /// </summary>
98                         Bottom, 
99
100                         /// <summary>
101                         /// Docked to the left.
102                         /// </summary>
103                         Left,
104                 };
105
106         /// <summary>
107         /// Text drawing styles.
108         /// </summary>
109         public enum TextStyle
110         {
111             /// <summary>
112             /// Default text drawing style.
113             /// </summary>
114             Default,
115
116             /// <summary>
117             /// Shadow text.
118             /// </summary>
119             Shadow,
120
121             /// <summary>
122             /// Emboss text.
123             /// </summary>
124             Emboss,
125
126             /// <summary>
127             /// Embed text.
128             /// </summary>
129             Embed,
130
131             /// <summary>
132             /// Frame text.
133             /// </summary>
134             Frame
135         }
136
137
138         /// <summary>
139         /// An enumeration of chart text orientation.
140         /// </summary>
141         public enum TextOrientation
142         {
143             /// <summary>
144             /// Orientation is automatically determined based on the type of the 
145             /// chart element it is used in.
146             /// </summary>
147             Auto,
148
149             /// <summary>
150             /// Horizontal text.
151             /// </summary>
152             Horizontal,
153
154             /// <summary>
155             /// Text rotated 90 degrees and oriented from top to bottom.
156             /// </summary>
157             Rotated90,
158
159             /// <summary>
160             /// Text rotated 270 degrees and oriented from bottom to top.
161             /// </summary>
162             Rotated270,
163
164             /// <summary>
165             /// Text characters are not rotated and position one below the other.
166             /// </summary>
167             Stacked
168         }
169
170         #endregion
171
172         /// <summary>
173     /// The Title class provides properties which define content, visual 
174     /// appearance and position of the single chart title. It also 
175     /// contains methods responsible for calculating title position, 
176     /// drawing and hit testing.
177         /// </summary>
178         [
179         SRDescription("DescriptionAttributeTitle5"),
180         ]
181 #if Microsoft_CONTROL
182         public class Title : ChartNamedElement, IDisposable
183 #else
184 #if ASPPERM_35
185         [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
186     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
187 #endif
188     public class Title : ChartNamedElement, IDisposable, IChartMapArea
189 #endif
190     {
191                 #region Fields
192
193                 // Spacing between title text and the border in pixels
194                 internal int                                            titleBorderSpacing = 4;
195
196
197         //***********************************************************
198                 //** Private data members, which store properties values
199                 //***********************************************************
200
201                 // Title text
202                 private string                                  _text = String.Empty;
203
204         // Title drawing style
205         private TextStyle               _style = TextStyle.Default;
206
207                 // Title position
208                 private ElementPosition                 _position = null;
209
210                 // Background properties
211                 private bool                                    _visible = true;
212                 private Color                                   _backColor = Color.Empty;
213                 private ChartHatchStyle                 _backHatchStyle = ChartHatchStyle.None;
214                 private string                                  _backImage = "";
215                 private ChartImageWrapMode              _backImageWrapMode = ChartImageWrapMode.Tile;
216                 private Color                                   _backImageTransparentColor = Color.Empty;
217                 private ChartImageAlignmentStyle                        _backImageAlignment = ChartImageAlignmentStyle.TopLeft;
218                 private GradientStyle                   _backGradientStyle = GradientStyle.None;
219                 private Color                                   _backSecondaryColor = Color.Empty;
220                 private int                                             _shadowOffset = 0;
221                 private Color                                   _shadowColor = Color.FromArgb(128, 0, 0, 0);
222
223                 // Border properties
224                 private Color                                   _borderColor = Color.Empty;
225                 private int                                             _borderWidth = 1;
226                 private ChartDashStyle                  _borderDashStyle = ChartDashStyle.Solid;
227
228                 // Font properties
229         private FontCache               _fontCache = new FontCache();
230                 private Font                                    _font;
231                 private Color                                   _foreColor = Color.Black;
232
233                 // Docking and Alignment properties
234                 private ContentAlignment                _alignment = ContentAlignment.MiddleCenter;
235                 private Docking                                 _docking = Docking.Top;
236         private string                  _dockedToChartArea = Constants.NotSetValue;
237                 private bool                                    _isDockedInsideChartArea = true;
238                 private int                                             _dockingOffset = 0;
239
240                 // Interactive properties
241                 private string                                  _toolTip = String.Empty;
242
243 #if !Microsoft_CONTROL
244         private string                  _url = String.Empty;
245                 private string                                  _mapAreaAttributes = String.Empty;
246         private string                  _postbackValue = String.Empty;
247 #endif
248
249         // Default text orientation
250         private TextOrientation         _textOrientation = TextOrientation.Auto;
251
252                 #endregion 
253
254                 #region Constructors and Initialization
255
256                 /// <summary>
257         /// Title constructor.
258                 /// </summary>
259                 public Title()
260                 {
261                         Initialize(string.Empty, Docking.Top, null, Color.Black);
262                 }
263
264                 /// <summary>
265                 /// Public constructor.
266                 /// </summary>
267                 /// <param name="text">Title text.</param>
268                 public Title(string text)
269                 {
270                         Initialize(text, Docking.Top, null, Color.Black);
271                 }
272
273                 /// <summary>
274         /// Title constructor.
275                 /// </summary>
276                 /// <param name="text">Title text.</param>
277                 /// <param name="docking">Title docking.</param>
278                 public Title(string text, Docking docking)
279                 {
280                         Initialize(text, docking, null, Color.Black);
281                 }
282
283                 /// <summary>
284         /// Title constructor.
285                 /// </summary>
286                 /// <param name="text">Title text.</param>
287                 /// <param name="docking">Title docking.</param>
288                 /// <param name="font">Title font.</param>
289                 /// <param name="color">Title color.</param>
290                 public Title(string text, Docking docking, Font font, Color color)
291                 {
292                         Initialize(text, docking, font, color);
293                 }
294
295                 /// <summary>
296                 /// Initialize title object.
297                 /// </summary>
298                 /// <param name="text">Title text.</param>
299                 /// <param name="docking">Title docking.</param>
300                 /// <param name="font">Title font.</param>
301                 /// <param name="color">Title color.</param>
302                 private void Initialize(string text, Docking docking, Font font, Color color)
303                 {
304                         // Initialize fields
305             this._position = new ElementPosition(this);
306             this._font = _fontCache.DefaultFont;
307                         this._text = text;
308                         this._docking = docking;
309                         this._foreColor = color;
310                         if(font != null)
311                         {
312                                 this._font = font;
313                         }
314                 }
315
316                 #endregion 
317
318                 #region Properties
319
320         /// <summary>
321         /// Gets or sets the unique name of a ChartArea object.
322         /// </summary>
323         [
324
325         SRCategory("CategoryAttributeMisc"),
326         Bindable(true),
327         SRDescription("DescriptionAttributeTitle_Name"),
328         NotifyParentPropertyAttribute(true),
329         #if !Microsoft_CONTROL
330          PersistenceMode(PersistenceMode.Attribute)
331         #endif
332         ]
333         public override string Name
334         {
335             get
336             {
337                 return base.Name;
338             }
339             set
340             {
341                 base.Name = value;
342             }
343         }
344
345         /// <summary>
346         /// Gets or sets the text orientation.
347         /// </summary>
348         [
349         SRCategory("CategoryAttributeAppearance"),
350         Bindable(true),
351         DefaultValue(TextOrientation.Auto),
352         SRDescription("DescriptionAttribute_TextOrientation"),
353         NotifyParentPropertyAttribute(true),
354 #if !Microsoft_CONTROL
355                 PersistenceMode(PersistenceMode.Attribute)
356 #endif
357 ]
358         public TextOrientation TextOrientation
359         {
360             get
361             {
362                 return this._textOrientation;
363             }
364             set
365             {
366                 this._textOrientation = value;
367                 this.Invalidate(true);
368             }
369         }
370
371                 /// <summary>
372                 /// Gets or sets a flag that specifies whether the title is visible.
373                 /// </summary>
374                 /// <value>
375                 /// <b>True</b> if the title is visible; <b>false</b> otherwise.
376                 /// </value>
377                 [
378                 SRCategory("CategoryAttributeAppearance"),
379                 DefaultValue(true),
380                 SRDescription("DescriptionAttributeTitle_Visible"),
381                 ParenthesizePropertyNameAttribute(true),
382                 ]
383                 virtual public bool Visible
384                 {
385                         get
386                         {
387                                 return _visible;
388                         }
389                         set
390                         {
391                                 _visible = value;
392                                 this.Invalidate(false);
393                         }
394                 }
395
396                 /// <summary>
397                 /// Gets or sets the chart area name which the title is docked to inside or outside.
398                 /// </summary>
399                 [
400                 SRCategory("CategoryAttributeDocking"),
401                 Bindable(true),
402         DefaultValue(Constants.NotSetValue),
403                 SRDescription("DescriptionAttributeTitle_DockToChartArea"),
404         TypeConverter(typeof(LegendAreaNameConverter)),
405                 NotifyParentPropertyAttribute(true),
406                 #if !Microsoft_CONTROL
407                 PersistenceMode(PersistenceMode.Attribute),
408                 #endif
409                 ]
410                 public string DockedToChartArea
411                 {
412                         get
413                         {
414                                 return _dockedToChartArea;
415                         }
416                         set
417                         {
418                                 if(value != _dockedToChartArea)
419                                 {
420                                         if(value.Length == 0)
421                                         {
422                         _dockedToChartArea = Constants.NotSetValue;
423                                         }
424                                         else
425                                         {
426                         if (Chart != null && Chart.ChartAreas != null)
427                         {
428                             Chart.ChartAreas.VerifyNameReference(value);
429                         }
430                                                 _dockedToChartArea = value;
431                                         }
432                                         this.Invalidate(false);
433                                 }
434                         }
435                 }
436
437                 /// <summary>
438                 /// Gets or sets a property which indicates whether the title is docked inside chart area. 
439         /// DockedToChartArea property must be set first.
440                 /// </summary>
441                 [
442         SRCategory("CategoryAttributeDocking"),
443                 Bindable(true),
444                 DefaultValue(true),
445                 SRDescription("DescriptionAttributeTitle_DockInsideChartArea"),
446                 NotifyParentPropertyAttribute(true),
447                 #if !Microsoft_CONTROL
448                 PersistenceMode(PersistenceMode.Attribute),
449                 #endif
450                 ]
451                 public bool IsDockedInsideChartArea
452                 {
453                         get
454                         {
455                                 return _isDockedInsideChartArea;
456                         }
457                         set
458                         {
459                                 if(value != _isDockedInsideChartArea)
460                                 {
461                                         _isDockedInsideChartArea = value;
462                                         this.Invalidate(false);
463                                 }
464                         }
465                 }
466
467                 /// <summary>
468                 /// Gets or sets the positive or negative offset of the docked title position.
469                 /// </summary>
470                 [
471                 SRCategory("CategoryAttributeDocking"),
472                 Bindable(true),
473                 DefaultValue(0),
474                 SRDescription("DescriptionAttributeTitle_DockOffset"),
475                 NotifyParentPropertyAttribute(true),
476                 #if !Microsoft_CONTROL
477                 PersistenceMode(PersistenceMode.Attribute),
478                 #endif
479                 ]
480                 public int DockingOffset
481                 {
482                         get
483                         {
484                                 return _dockingOffset;
485                         }
486                         set
487                         {
488                                 if(value != _dockingOffset)
489                                 {
490                     if (value < -100 || value > 100)
491                     {
492                         throw (new ArgumentOutOfRangeException("value", SR.ExceptionValueMustBeInRange("DockingOffset", (-100).ToString(CultureInfo.CurrentCulture), (100).ToString(CultureInfo.CurrentCulture))));
493                     }
494                                         _dockingOffset = value;
495                                         this.Invalidate(false);
496                                 }
497                         }
498                 }
499
500
501                 /// <summary>
502                 /// Gets or sets the position of the title.
503                 /// </summary>
504                 [
505                 SRCategory("CategoryAttributeAppearance"),
506                 Bindable(true),
507                 SRDescription("DescriptionAttributeTitle_Position"),
508 #if Microsoft_CONTROL
509                 DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
510 #else
511                 PersistenceMode(PersistenceMode.InnerProperty),
512 #endif
513                 NotifyParentPropertyAttribute(true),
514         TypeConverter(typeof(ElementPositionConverter)),
515                 SerializationVisibilityAttribute(SerializationVisibility.Element)
516                 ]
517                 public ElementPosition Position
518                 {
519                         get
520                         {       
521                                 // Serialize only position values if Auto set to false
522                 if (Chart != null && Chart.serializationStatus == SerializationStatus.Saving)
523                                 {
524                                         if(_position.Auto)
525                                         {
526                                                 return new ElementPosition();   
527                                         }
528                                         else
529                                         {
530                                                 ElementPosition newPosition = new ElementPosition();
531 #if Microsoft_CONTROL
532                                                 newPosition.Auto = false;
533 #else
534                                                 newPosition.Auto = true;
535 #endif
536                                                 newPosition.SetPositionNoAuto(_position.X, _position.Y, _position.Width, _position.Height);
537                                                 return newPosition;
538                                         }
539                                 }
540                                 return _position;
541                         }
542                         set
543                         {
544                                 _position = value;
545                 _position.Parent = this;
546                                 this.Invalidate(false);
547                         }
548                 }
549
550         /// <summary>
551         /// Determoines if this position should be serialized.
552         /// </summary>
553         /// <returns></returns>
554         internal bool ShouldSerializePosition()
555         {
556             return !this.Position.Auto;
557         }
558
559
560                 /// <summary>
561                 /// Gets or sets the text of the title.
562                 /// </summary>
563                 [
564                 SRCategory("CategoryAttributeAppearance"),
565                 Bindable(true),
566                 DefaultValue(""),
567                 SRDescription("DescriptionAttributeTitle_Text"),
568                 NotifyParentPropertyAttribute(true),
569                 ParenthesizePropertyNameAttribute(true),
570                 #if !Microsoft_CONTROL
571                 PersistenceMode(PersistenceMode.Attribute)
572                 #endif
573                 ]
574                 public string Text
575                 {
576                         get
577                         {
578                                 return _text;
579                         }
580                         set
581                         {
582                                 _text = (value == null) ? string.Empty : value;
583                                 this.Invalidate(false);
584                         }
585                 }
586
587
588         /// <summary>
589         /// Title drawing style.
590         /// </summary>
591         [
592         SRCategory("CategoryAttributeAppearance"),
593         Bindable(true),
594         DefaultValue(TextStyle.Default),
595         SRDescription("DescriptionAttributeTextStyle"),
596         NotifyParentPropertyAttribute(true),
597         #if !Microsoft_CONTROL
598         PersistenceMode(PersistenceMode.Attribute)
599         #endif
600         ]
601         public TextStyle TextStyle
602         {
603             get
604             {
605                 return _style;
606             }
607             set
608             {
609                 _style = value;
610                 this.Invalidate(true);
611             }
612         }
613
614
615                 /// <summary>
616                 /// Gets or sets the background color of the title.
617                 /// </summary>
618                 [
619                 SRCategory("CategoryAttributeAppearance"),
620                 Bindable(true),
621                 DefaultValue(typeof(Color), ""),
622         SRDescription("DescriptionAttributeBackColor"),
623                 NotifyParentPropertyAttribute(true),
624         TypeConverter(typeof(ColorConverter)),
625         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
626                 #if !Microsoft_CONTROL
627                 PersistenceMode(PersistenceMode.Attribute)
628                 #endif
629                 ]
630                 public Color BackColor
631                 {
632                         get
633                         {
634                                 return _backColor;
635                         }
636                         set
637                         {
638                                 _backColor = value;
639                                 this.Invalidate(true);
640                         }
641                 }
642
643                 /// <summary>
644                 /// Gets or sets the border color of the title.
645                 /// </summary>
646                 [
647         SRCategory("CategoryAttributeAppearance"),
648                 Bindable(true),
649                 DefaultValue(typeof(Color), ""),
650         SRDescription("DescriptionAttributeBorderColor"),
651                 NotifyParentPropertyAttribute(true),
652         TypeConverter(typeof(ColorConverter)),
653         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
654                 #if !Microsoft_CONTROL
655                 PersistenceMode(PersistenceMode.Attribute)
656                 #endif
657                 ]
658                 public Color BorderColor
659                 {
660                         get
661                         {
662                                 return _borderColor;
663                         }
664                         set
665                         {
666                                 _borderColor = value;
667                                 this.Invalidate(true);
668                         }
669                 }
670
671                 /// <summary>
672                 /// Gets or sets the border style of the title.
673                 /// </summary>
674                 [
675                 SRCategory("CategoryAttributeAppearance"),
676                 Bindable(true),
677                 DefaultValue(ChartDashStyle.Solid),
678         SRDescription("DescriptionAttributeBorderDashStyle"),
679                 NotifyParentPropertyAttribute(true),
680                 #if !Microsoft_CONTROL
681                 PersistenceMode(PersistenceMode.Attribute)
682                 #endif
683                 ]
684                 public ChartDashStyle BorderDashStyle
685                 {
686                         get
687                         {
688                                 return _borderDashStyle;
689                         }
690                         set
691                         {
692                                 _borderDashStyle = value;
693                                 this.Invalidate(true);
694                         }
695                 }
696
697                 /// <summary>
698                 /// Gets or sets the border width of the title.
699                 /// </summary>
700                 [
701         SRCategory("CategoryAttributeAppearance"),
702                 Bindable(true),
703                 DefaultValue(1),
704         SRDescription("DescriptionAttributeBorderWidth"),
705                 NotifyParentPropertyAttribute(true),
706                 #if !Microsoft_CONTROL
707                 PersistenceMode(PersistenceMode.Attribute)
708                 #endif
709                 ]
710                 public int BorderWidth
711                 {
712                         get
713                         {
714                                 return _borderWidth;
715                         }
716                         set
717                         {
718                                 if(value < 0)
719                                 {
720                     throw (new ArgumentOutOfRangeException("value", SR.ExceptionTitleBorderWidthIsNegative));
721                                 }
722                                 _borderWidth = value;
723                                 this.Invalidate(false);
724                         }
725                 }
726                 
727                 /// <summary>
728                 /// Gets or sets the background image.
729                 /// </summary>
730                 [
731                 SRCategory("CategoryAttributeAppearance"),
732                 Bindable(true),
733                 DefaultValue(""),
734         SRDescription("DescriptionAttributeBackImage"),
735         Editor(Editors.ImageValueEditor.Editor, Editors.ImageValueEditor.Base),
736                 #if !Microsoft_CONTROL
737                 PersistenceMode(PersistenceMode.Attribute),
738                 #endif
739                 NotifyParentPropertyAttribute(true),
740                 ]
741                 public string BackImage
742                 {
743                         get
744                         {
745                                 return _backImage;
746                         }
747                         set
748                         {
749                                 _backImage = value;
750                                 this.Invalidate(true);
751                         }
752                 }
753
754         /// <summary>
755         /// Gets or sets the background image drawing mode.
756         /// </summary>
757                 [
758                 SRCategory("CategoryAttributeAppearance"),
759                 Bindable(true),
760                 DefaultValue(ChartImageWrapMode.Tile),
761                 NotifyParentPropertyAttribute(true),
762         SRDescription("DescriptionAttributeImageWrapMode"),
763                 #if !Microsoft_CONTROL
764                 PersistenceMode(PersistenceMode.Attribute)
765                 #endif
766                 ]
767                 public ChartImageWrapMode BackImageWrapMode
768                 {
769                         get
770                         {
771                                 return _backImageWrapMode;
772                         }
773                         set
774                         {
775                                 _backImageWrapMode = value;
776                                 this.Invalidate(true);
777                         }
778                 }
779
780         /// <summary>
781         /// Gets or sets a color which will be replaced with a transparent color while drawing the background image.
782         /// </summary>
783                 [
784         SRCategory("CategoryAttributeAppearance"),
785                 Bindable(true),
786                 DefaultValue(typeof(Color), ""),
787                 NotifyParentPropertyAttribute(true),
788         SRDescription("DescriptionAttributeImageTransparentColor"),
789         TypeConverter(typeof(ColorConverter)),
790         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
791                 #if !Microsoft_CONTROL
792                 PersistenceMode(PersistenceMode.Attribute)
793                 #endif
794                 ]
795                 public Color BackImageTransparentColor
796                 {
797                         get
798                         {
799                                 return _backImageTransparentColor;
800                         }
801                         set
802                         {
803                                 _backImageTransparentColor = value;
804                                 this.Invalidate(true);
805                         }
806                 }
807
808         /// <summary>
809         /// Gets or sets the background image alignment used by unscale drawing mode.
810         /// </summary>
811                 [
812                 SRCategory("CategoryAttributeAppearance"),
813                 Bindable(true),
814                 DefaultValue(ChartImageAlignmentStyle.TopLeft),
815                 NotifyParentPropertyAttribute(true),
816         SRDescription("DescriptionAttributeBackImageAlign"),
817                 #if !Microsoft_CONTROL
818                 PersistenceMode(PersistenceMode.Attribute)
819                 #endif
820                 ]
821                 public ChartImageAlignmentStyle BackImageAlignment
822                 {
823                         get
824                         {
825                                 return _backImageAlignment;
826                         }
827                         set
828                         {
829                                 _backImageAlignment = value;
830                                 this.Invalidate(true);
831                         }
832                 }
833
834         /// <summary>
835         /// Gets or sets the background gradient style.
836         /// <seealso cref="BackSecondaryColor"/>
837         /// <seealso cref="BackColor"/>
838         /// <seealso cref="BackHatchStyle"/>
839         /// </summary>
840         /// <value>
841         /// A <see cref="GradientStyle"/> value used for the background.
842         /// </value>
843         /// <remarks>
844         /// Two colors are used to draw the gradient, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
845         /// </remarks>
846                 [
847         SRCategory("CategoryAttributeAppearance"),
848                 Bindable(true),
849                 DefaultValue(GradientStyle.None),
850                 NotifyParentPropertyAttribute(true),
851         SRDescription("DescriptionAttributeBackGradientStyle"),
852                 #if !Microsoft_CONTROL
853                 PersistenceMode(PersistenceMode.Attribute),
854                 #endif
855         Editor(Editors.GradientEditor.Editor, Editors.GradientEditor.Base)
856                 ]
857                 public GradientStyle BackGradientStyle
858                 {
859                         get
860                         {
861                                 return _backGradientStyle;
862                         }
863                         set
864                         {
865                                 _backGradientStyle = value;
866                                 this.Invalidate(true);
867                         }
868                 }
869
870         /// <summary>
871         /// Gets or sets the secondary background color.
872         /// <seealso cref="BackColor"/>
873         /// <seealso cref="BackHatchStyle"/>
874         /// <seealso cref="BackGradientStyle"/>
875         /// </summary>
876         /// <value>
877         /// A <see cref="Color"/> value used for the secondary color of a background with 
878         /// hatching or gradient fill.
879         /// </value>
880         /// <remarks>
881         /// This color is used with <see cref="BackColor"/> when <see cref="BackHatchStyle"/> or
882         /// <see cref="BackGradientStyle"/> are used.
883         /// </remarks>
884                 [
885         SRCategory("CategoryAttributeAppearance"),
886                 Bindable(true),
887                 DefaultValue(typeof(Color), ""),
888                 NotifyParentPropertyAttribute(true),
889         SRDescription("DescriptionAttributeBackSecondaryColor"),
890         TypeConverter(typeof(ColorConverter)),
891         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
892                 #if !Microsoft_CONTROL
893                 PersistenceMode(PersistenceMode.Attribute)
894                 #endif
895                 ]
896                 public Color BackSecondaryColor
897                 {
898                         get
899                         {
900                                 return _backSecondaryColor;
901                         }
902                         set
903                         {
904                                 _backSecondaryColor = value;
905                                 this.Invalidate(true);
906                         }
907                 }
908
909         /// <summary>
910         /// Gets or sets the background hatch style.
911         /// <seealso cref="BackSecondaryColor"/>
912         /// <seealso cref="BackColor"/>
913         /// <seealso cref="BackGradientStyle"/>
914         /// </summary>
915         /// <value>
916         /// A <see cref="ChartHatchStyle"/> value used for the background.
917         /// </value>
918         /// <remarks>
919         /// Two colors are used to draw the hatching, <see cref="BackColor"/> and <see cref="BackSecondaryColor"/>.
920         /// </remarks>
921                 [
922                 SRCategory("CategoryAttributeAppearance"),
923                 Bindable(true),
924                 DefaultValue(ChartHatchStyle.None),
925                 NotifyParentPropertyAttribute(true),
926         SRDescription("DescriptionAttributeBackHatchStyle"),
927                 #if !Microsoft_CONTROL
928                 PersistenceMode(PersistenceMode.Attribute),
929                 #endif
930         Editor(Editors.HatchStyleEditor.Editor, Editors.HatchStyleEditor.Base)
931                 ]
932                 public ChartHatchStyle BackHatchStyle
933                 {
934                         get
935                         {
936                                 return _backHatchStyle;
937                         }
938                         set
939                         {
940                                 _backHatchStyle = value;
941                                 this.Invalidate(true);
942                         }
943                 }
944
945                 /// <summary>
946                 /// Gets or sets the title font.
947                 /// </summary>
948                 [
949                 SRCategory("CategoryAttributeAppearance"),
950                 Bindable(true),
951                 DefaultValue(typeof(Font), "Microsoft Sans Serif, 8pt"),
952                 SRDescription("DescriptionAttributeTitle_Font"),
953                 NotifyParentPropertyAttribute(true),
954                 #if !Microsoft_CONTROL
955                 PersistenceMode(PersistenceMode.Attribute)
956                 #endif
957                 ]
958                 public Font Font
959                 {
960                         get
961                         {
962                                 return _font;
963                         }
964                         set
965                         {
966                                 _font = value;
967                                 this.Invalidate(false);
968                         }
969                 }
970
971                 /// <summary>
972                 /// Gets or sets the title fore color.
973                 /// </summary>
974                 [
975                 SRCategory("CategoryAttributeAppearance"),
976                 Bindable(true),
977                 DefaultValue(typeof(Color), "Black"),
978                 SRDescription("DescriptionAttributeTitle_Color"),
979                 NotifyParentPropertyAttribute(true),
980         TypeConverter(typeof(ColorConverter)),
981         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
982                 #if !Microsoft_CONTROL
983                 PersistenceMode(PersistenceMode.Attribute)
984                 #endif
985                 ]
986                 public Color ForeColor
987                 {
988                         get
989                         {
990                                 return _foreColor;
991                         }
992                         set
993                         {
994                                 _foreColor = value;
995                                 this.Invalidate(true);
996                         }
997                 }
998
999                 /// <summary>
1000                 /// Gets or sets title alignment.
1001                 /// </summary>
1002                 [
1003                 SRCategory("CategoryAttributeDocking"),
1004                 Bindable(true),
1005                 DefaultValue(ContentAlignment.MiddleCenter),
1006                 SRDescription("DescriptionAttributeTitle_Alignment"),
1007                 NotifyParentPropertyAttribute(true),
1008                 #if !Microsoft_CONTROL
1009                 PersistenceMode(PersistenceMode.Attribute)
1010                 #endif
1011                 ]
1012                 public ContentAlignment Alignment
1013                 {
1014                         get
1015                         {
1016                                 return _alignment;
1017                         }
1018                         set
1019                         {
1020                                 _alignment = value;
1021                                 this.Invalidate(false);
1022                         }
1023                 }
1024                 
1025                 /// <summary>
1026                 /// Gets or sets the title docking style.
1027                 /// </summary>
1028                 [
1029         SRCategory("CategoryAttributeDocking"),
1030                 Bindable(true),
1031                 DefaultValue(Docking.Top),
1032                 SRDescription("DescriptionAttributeTitle_Docking"),
1033                 NotifyParentPropertyAttribute(true),
1034                 #if !Microsoft_CONTROL
1035                 PersistenceMode(PersistenceMode.Attribute)
1036                 #endif
1037                 ]
1038                 public Docking Docking
1039                 {
1040                         get
1041                         {
1042                                 return _docking;
1043                         }
1044                         set
1045                         {
1046                                 _docking = value;
1047                                 this.Invalidate(false);
1048                         }
1049                 }
1050
1051                 /// <summary>
1052                 /// Gets or sets the title shadow offset.
1053                 /// </summary>
1054                 [
1055                 SRCategory("CategoryAttributeAppearance"),
1056                 Bindable(true),
1057                 DefaultValue(0),
1058         SRDescription("DescriptionAttributeShadowOffset"),
1059                 NotifyParentPropertyAttribute(true),
1060                 #if !Microsoft_CONTROL
1061                 PersistenceMode(PersistenceMode.Attribute)
1062                 #endif
1063                 ]
1064                 public int ShadowOffset
1065                 {
1066                         get
1067                         {
1068                                 return _shadowOffset;
1069                         }
1070                         set
1071                         {
1072                                 _shadowOffset = value;
1073                                 this.Invalidate(false);
1074                         }
1075                 }
1076
1077                 /// <summary>
1078                 /// Gets or sets the title shadow color.
1079                 /// </summary>
1080                 [
1081                 SRCategory("CategoryAttributeAppearance"),
1082                 Bindable(true),
1083                 DefaultValue(typeof(Color), "128, 0, 0, 0"),
1084         SRDescription("DescriptionAttributeShadowColor"),
1085                 NotifyParentPropertyAttribute(true),
1086         TypeConverter(typeof(ColorConverter)),
1087         Editor(Editors.ChartColorEditor.Editor, Editors.ChartColorEditor.Base),
1088                 #if !Microsoft_CONTROL
1089                 PersistenceMode(PersistenceMode.Attribute)
1090                 #endif
1091                 ]
1092                 public Color ShadowColor
1093                 {
1094                         get
1095                         {
1096                                 return _shadowColor;
1097                         }
1098                         set
1099                         {
1100                                 _shadowColor = value;
1101                                 this.Invalidate(false);
1102                         }
1103                 }
1104
1105                 /// <summary>
1106                 /// Gets or sets the tooltip.
1107                 /// </summary>
1108                 [
1109 #if !Microsoft_CONTROL
1110                 SRCategory("CategoryAttributeMapArea"),
1111 #else
1112                 SRCategory("CategoryAttributeToolTip"),
1113 #endif
1114                 Bindable(true),
1115         SRDescription("DescriptionAttributeToolTip"),
1116                 DefaultValue(""),
1117                 #if !Microsoft_CONTROL
1118                 PersistenceMode(PersistenceMode.Attribute)
1119                 #endif
1120                 ]
1121                 public string ToolTip
1122                 {
1123                         set
1124                         {
1125                                 _toolTip = value;
1126                         }
1127                         get
1128                         {
1129                                 return _toolTip;
1130                         }
1131                 }
1132
1133
1134 #if !Microsoft_CONTROL
1135
1136                 /// <summary>
1137                 /// Gets or sets the URL target of the title.
1138                 /// </summary>
1139                 [
1140                 SRCategory("CategoryAttributeMapArea"),
1141                 Bindable(true),
1142                 SRDescription("DescriptionAttributeUrl"),
1143                 DefaultValue(""),
1144 #if !Microsoft_CONTROL
1145                 PersistenceMode(PersistenceMode.Attribute),
1146         Editor(Editors.UrlValueEditor.Editor, Editors.UrlValueEditor.Base)
1147 #endif
1148                 ]
1149                 public string Url
1150                 {
1151                         set
1152                         {
1153                                 _url = value;
1154                         }
1155                         get
1156                         {
1157                                 return _url;
1158                         }
1159                 }
1160                 /// <summary>
1161                 /// Gets or sets the other attributes of the title map area.
1162                 /// </summary>
1163                 [
1164                 SRCategory("CategoryAttributeMapArea"),
1165                 Bindable(true),
1166                 SRDescription("DescriptionAttributeMapAreaAttributes"),
1167                 DefaultValue(""),
1168                 PersistenceMode(PersistenceMode.Attribute)
1169                 ]
1170                 public string MapAreaAttributes
1171                 {
1172                         set
1173                         {
1174                                 _mapAreaAttributes = value;
1175                         }
1176                         get
1177                         {
1178                                 return _mapAreaAttributes;
1179                         }
1180         }
1181
1182         /// <summary>
1183         /// Gets or sets the postback value which can be processed on a click event.
1184         /// </summary>
1185         /// <value>The value which is passed to a click event as an argument.</value>
1186         [DefaultValue("")]
1187         [SRCategory(SR.Keys.CategoryAttributeMapArea)]
1188         [SRDescription(SR.Keys.DescriptionAttributePostBackValue)]
1189         public string PostBackValue 
1190         {
1191             get
1192             {
1193                 return this._postbackValue;
1194             }
1195             set
1196             {
1197                 this._postbackValue = value;
1198             } 
1199         }
1200
1201
1202 #endif
1203
1204         /// <summary>
1205                 /// True if title background or border is visible
1206                 /// </summary>
1207                 internal bool BackGroundIsVisible
1208                 {
1209                         get
1210                         {
1211                                 if(!this.BackColor.IsEmpty ||
1212                                         this.BackImage.Length > 0 ||
1213                                         (!this.BorderColor.IsEmpty && this.BorderDashStyle != ChartDashStyle.NotSet) )
1214                                 {
1215                                         return true;
1216                                 }
1217
1218                                 return false;
1219                         }
1220                 }
1221
1222                 #endregion
1223
1224                 #region Helper Methods
1225
1226         /// <summary>
1227         /// Checks if chart title is drawn vertically.
1228         /// Note: From the drawing perspective stacked text orientation is not vertical.
1229         /// </summary>
1230         /// <returns>True if text is vertical.</returns>
1231         private bool IsTextVertical
1232         {
1233             get
1234             {
1235                 TextOrientation currentTextOrientation = this.GetTextOrientation();
1236                 return currentTextOrientation == TextOrientation.Rotated90 || currentTextOrientation == TextOrientation.Rotated270;
1237             }
1238         }
1239
1240         /// <summary>
1241         /// Returns title text orientation. If set to Auto automatically determines the
1242         /// orientation based on title docking.
1243         /// </summary>
1244         /// <returns>Current text orientation.</returns>
1245         private TextOrientation GetTextOrientation()
1246         {
1247             if (this.TextOrientation == TextOrientation.Auto)
1248             {
1249                 // When chart title is docked to the left or right we automatically 
1250                 // set vertical text with different rotation angles.
1251                 if (this.Position.Auto)
1252                 {
1253                     if (this.Docking == Docking.Left)
1254                     {
1255                         return TextOrientation.Rotated270;
1256                     }
1257                     else if (this.Docking == Docking.Right)
1258                     {
1259                         return TextOrientation.Rotated90;
1260                     }
1261                 }
1262                 return TextOrientation.Horizontal;
1263             }
1264             return this.TextOrientation;
1265         }
1266
1267                 /// <summary>
1268                 /// Helper method that checks if title is visible.
1269                 /// </summary>
1270                 /// <returns>True if title is visible.</returns>
1271                 internal bool IsVisible()
1272                 {
1273                         if(this.Visible)
1274                         {
1275
1276                                 // Check if title is docked to the chart area
1277                                 if(this.DockedToChartArea.Length > 0 &&
1278                                         this.Chart != null)
1279                                 {
1280                                         if(this.Chart.ChartAreas.IndexOf(this.DockedToChartArea) >= 0)
1281                                         {
1282                                                 // Do not show title when it is docked to invisible chart area
1283                                                 ChartArea area = this.Chart.ChartAreas[this.DockedToChartArea];
1284                                                 if(!area.Visible)
1285                                                 {
1286                                                         return false;
1287                                                 }
1288                                         }
1289                                 }
1290                                         
1291
1292                                 return true;
1293                         }
1294                         return false;
1295                 }
1296
1297                 /// <summary>
1298                 /// Invalidate chart title when one of the properties is changed.
1299                 /// </summary>
1300                 /// <param name="invalidateTitleOnly">Indicates that only title area should be invalidated.</param>
1301         [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", Justification = "This parameter is used when compiling for the Microsoft version of Chart")]
1302                 internal void Invalidate(bool invalidateTitleOnly)
1303                 {
1304 #if Microsoft_CONTROL
1305                         if(Chart != null)
1306                         {
1307                                 // Set dirty flag
1308                                 Chart.dirtyFlag = true;
1309
1310                                 // Invalidate chart
1311                                 if(invalidateTitleOnly)
1312                                 {
1313                                         // Calculate the position of the title
1314                                         Rectangle       invalRect = Chart.ClientRectangle;
1315                                         if(this.Position.Width != 0 && this.Position.Height != 0 )
1316                                         {
1317                                                 // Convert relative coordinates to absolute coordinates
1318                         invalRect.X = (int)(this.Position.X * (Common.ChartPicture.Width - 1) / 100F);
1319                         invalRect.Y = (int)(this.Position.Y * (Common.ChartPicture.Height - 1) / 100F);
1320                         invalRect.Width = (int)(this.Position.Width * (Common.ChartPicture.Width - 1) / 100F);
1321                         invalRect.Height = (int)(this.Position.Height * (Common.ChartPicture.Height - 1) / 100F); 
1322
1323                                                 // Inflate rectangle size using border size and shadow size
1324                                                 invalRect.Inflate(this.BorderWidth + this.ShadowOffset + 1, this.BorderWidth + this.ShadowOffset + 1);
1325                                         }
1326
1327                                         // Invalidate title rectangle only
1328                                         Chart.Invalidate(invalRect);
1329                                 }
1330                                 else
1331                                 {
1332                                         Invalidate();
1333                                 }
1334                         }
1335 #endif // #if Microsoft_CONTROL
1336                 }
1337
1338                 #endregion 
1339
1340                 #region Painting and Selection Methods
1341
1342                 /// <summary>
1343                 /// Paints title using chart graphics object.
1344                 /// </summary>
1345                 /// <param name="chartGraph">The graph provides drawing object to the display device. A Graphics object is associated with a specific device context.</param>
1346         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
1347         internal void Paint(ChartGraphics chartGraph )
1348                 {
1349                         // check if title is visible
1350                         if(!this.IsVisible())
1351                         {
1352                                 return;
1353                         }
1354
1355                         // Title text
1356                         string  titleText = this.Text;
1357                         
1358                         //***************************************************************
1359                         //** Calculate title relative position
1360                         //***************************************************************
1361                         RectangleF      titlePosition = this.Position.ToRectangleF();
1362                         
1363                         // Auto set the title position if width or height is not set for custom position
1364                         if(!this.Position.Auto && Common != null && Common.ChartPicture != null)
1365                         {
1366                                 if(titlePosition.Width == 0 || titlePosition.Height == 0)
1367                                 {
1368                                         // Calculate text layout area
1369                                         SizeF layoutArea = new SizeF(
1370                         (titlePosition.Width == 0) ? Common.ChartPicture.Width : titlePosition.Width,
1371                         (titlePosition.Height == 0) ? Common.ChartPicture.Height : titlePosition.Height);
1372                     if (this.IsTextVertical)
1373                     {
1374                         float tempValue = layoutArea.Width;
1375                         layoutArea.Width = layoutArea.Height;
1376                         layoutArea.Height = tempValue;
1377                     }
1378
1379                                         // Measure text size
1380                                         layoutArea = chartGraph.GetAbsoluteSize(layoutArea);
1381                                         SizeF titleSize = chartGraph.MeasureString(
1382                                                 "W" + titleText.Replace("\\n", "\n"), 
1383                                                 this.Font, 
1384                                                 layoutArea, 
1385                                                 StringFormat.GenericDefault,
1386                         this.GetTextOrientation());
1387
1388                     // Increase text size by 4 pixels
1389                                         if(this.BackGroundIsVisible)
1390                                         {
1391                                                 titleSize.Width += titleBorderSpacing;
1392                                                 titleSize.Height += titleBorderSpacing;
1393                                         }
1394
1395                                         // Switch width and height for vertical text
1396                     if (this.IsTextVertical)
1397                     {
1398                         float tempValue = titleSize.Width;
1399                         titleSize.Width = titleSize.Height;
1400                         titleSize.Height = tempValue;
1401                     }
1402
1403                                         // Convert text size to relative coordinates
1404                                         titleSize = chartGraph.GetRelativeSize(titleSize);
1405
1406                                         // Update custom position
1407                                         if(titlePosition.Width == 0)
1408                                         {
1409                                                 titlePosition.Width = titleSize.Width;
1410                                                 if(this.Alignment == ContentAlignment.BottomRight ||
1411                                                         this.Alignment == ContentAlignment.MiddleRight ||
1412                                                         this.Alignment == ContentAlignment.TopRight)
1413                                                 {
1414                                                         titlePosition.X = titlePosition.X - titlePosition.Width;
1415                                                 }
1416                                                 else if(this.Alignment == ContentAlignment.BottomCenter ||
1417                                                         this.Alignment == ContentAlignment.MiddleCenter ||
1418                                                         this.Alignment == ContentAlignment.TopCenter)
1419                                                 {
1420                                                         titlePosition.X = titlePosition.X - titlePosition.Width/2f;
1421                                                 }
1422                                         }
1423                                         if(titlePosition.Height == 0)
1424                                         {
1425                                                 titlePosition.Height = titleSize.Height;
1426                                                 if(this.Alignment == ContentAlignment.BottomRight ||
1427                                                         this.Alignment == ContentAlignment.BottomCenter ||
1428                                                         this.Alignment == ContentAlignment.BottomLeft)
1429                                                 {
1430                                                         titlePosition.Y = titlePosition.Y - titlePosition.Height;
1431                                                 }
1432                                                 else if(this.Alignment == ContentAlignment.MiddleCenter ||
1433                                                         this.Alignment == ContentAlignment.MiddleLeft ||
1434                                                         this.Alignment == ContentAlignment.MiddleRight)
1435                                                 {
1436                                                         titlePosition.Y = titlePosition.Y - titlePosition.Height/2f;
1437                                                 }
1438                                         }
1439
1440                                 }
1441                         }
1442
1443                         //***************************************************************
1444                         //** Convert title position to absolute coordinates
1445                         //***************************************************************
1446                         RectangleF      absPosition = new RectangleF(titlePosition.Location, titlePosition.Size);
1447                         absPosition = chartGraph.GetAbsoluteRectangle(absPosition);
1448
1449                         //***************************************************************
1450                         //** Draw title background, border and shadow
1451                         //***************************************************************
1452                         if(this.BackGroundIsVisible && Common.ProcessModePaint )
1453                         {
1454                                 chartGraph.FillRectangleRel( titlePosition, 
1455                                         BackColor, 
1456                                         BackHatchStyle, 
1457                                         BackImage, 
1458                                         BackImageWrapMode, 
1459                                         BackImageTransparentColor,
1460                                         BackImageAlignment,
1461                                         BackGradientStyle, 
1462                                         BackSecondaryColor,
1463                                         BorderColor, 
1464                                         BorderWidth, 
1465                                         BorderDashStyle, 
1466                                         ShadowColor, 
1467                                         ShadowOffset,
1468                                         PenAlignment.Inset);
1469                         }
1470                         else 
1471                         {
1472                                 // Adjust text position to be only around the text itself
1473                                 SizeF titleArea = chartGraph.GetAbsoluteSize(titlePosition.Size);
1474                                 SizeF titleSize = chartGraph.MeasureString(
1475                     "W" + titleText.Replace("\\n", "\n"), 
1476                                         this.Font, 
1477                                         titleArea,
1478                     StringFormat.GenericDefault,
1479                     this.GetTextOrientation());
1480
1481                                 // Convert text size to relative coordinates
1482                                 titleSize = chartGraph.GetRelativeSize(titleSize);
1483
1484                                 // Adjust position depending on alignment
1485                                 RectangleF exactTitleRect = new RectangleF(
1486                                         titlePosition.X, 
1487                                         titlePosition.Y, 
1488                                         titleSize.Width,
1489                                         titleSize.Height);
1490                                 if(this.Alignment == ContentAlignment.BottomCenter ||
1491                                         this.Alignment == ContentAlignment.BottomLeft ||
1492                                         this.Alignment == ContentAlignment.BottomRight )
1493                                 {
1494                                         exactTitleRect.Y = titlePosition.Bottom - exactTitleRect.Height;
1495                                 }
1496                                 else if(this.Alignment == ContentAlignment.MiddleCenter ||
1497                                         this.Alignment == ContentAlignment.MiddleLeft ||
1498                                         this.Alignment == ContentAlignment.MiddleRight )
1499                                 {
1500                                         exactTitleRect.Y = titlePosition.Y + 
1501                                                 titlePosition.Height / 2f - 
1502                                                 exactTitleRect.Height / 2f;
1503                                 }
1504                                 
1505                                 if(this.Alignment == ContentAlignment.BottomRight ||
1506                                         this.Alignment == ContentAlignment.MiddleRight ||
1507                                         this.Alignment == ContentAlignment.TopRight )
1508                                 {
1509                                         exactTitleRect.X = titlePosition.Right - exactTitleRect.Width;
1510                                 }
1511                                 else if(this.Alignment == ContentAlignment.BottomCenter ||
1512                                         this.Alignment == ContentAlignment.MiddleCenter ||
1513                                         this.Alignment == ContentAlignment.TopCenter )
1514                                 {
1515                                         exactTitleRect.X = titlePosition.X + 
1516                                                 titlePosition.Width / 2f - 
1517                                                 exactTitleRect.Width / 2f;
1518                                 }
1519
1520                                 // NOTE: This approach for text selection can not be used with
1521                                 // Flash animations because of the bug in Flash viewer. When the 
1522                                 // button shape is placed in the last frame the Alpha value of the
1523                                 // color is ignored.
1524
1525                                 // NOTE: Feature tested again with Flash Player 7 and it seems to be 
1526                                 // working fine. Code below is commented to enable selection in flash
1527                                 // through transparent rectangle.
1528                                 // Fixes issue #4172.
1529
1530                                 bool drawRect = true;
1531
1532                                 // Draw transparent rectangle in the text position
1533                                 if(drawRect)
1534                                 {
1535                                         chartGraph.FillRectangleRel( 
1536                                                 exactTitleRect, 
1537                                                 Color.FromArgb(0, Color.White),
1538                                                 ChartHatchStyle.None,
1539                                                 String.Empty, 
1540                                                 ChartImageWrapMode.Tile, 
1541                                                 BackImageTransparentColor,
1542                                                 BackImageAlignment,
1543                                                 GradientStyle.None, 
1544                                                 BackSecondaryColor,
1545                                                 Color.Transparent, 
1546                                                 0, 
1547                                                 BorderDashStyle, 
1548                                                 Color.Transparent, 
1549                                                 0,
1550                                                 PenAlignment.Inset);
1551                                 }
1552
1553                                 // End Selection mode
1554                                 chartGraph.EndHotRegion( );
1555                         }
1556
1557             if( Common.ProcessModePaint)
1558                 Common.Chart.CallOnPrePaint(new ChartPaintEventArgs(this, chartGraph, Common, Position));
1559
1560                         //***************************************************************
1561                         //** Add spacing between text and border
1562                         //***************************************************************
1563                         if(this.BackGroundIsVisible)
1564                         {
1565                                 absPosition.Width -= this.titleBorderSpacing;
1566                                 absPosition.Height -= this.titleBorderSpacing;
1567                                 absPosition.X += this.titleBorderSpacing / 2f;
1568                                 absPosition.Y += this.titleBorderSpacing / 2f;
1569                         }
1570
1571                         //***************************************************************
1572                         //** Create string format
1573                         //***************************************************************
1574             using (StringFormat format = new StringFormat())
1575             {
1576                 format.Alignment = StringAlignment.Center;
1577                 format.LineAlignment = StringAlignment.Center;
1578
1579                 if (this.Alignment == ContentAlignment.BottomCenter ||
1580                     this.Alignment == ContentAlignment.BottomLeft ||
1581                     this.Alignment == ContentAlignment.BottomRight)
1582                 {
1583                     format.LineAlignment = StringAlignment.Far;
1584                 }
1585                 else if (this.Alignment == ContentAlignment.TopCenter ||
1586                     this.Alignment == ContentAlignment.TopLeft ||
1587                     this.Alignment == ContentAlignment.TopRight)
1588                 {
1589                     format.LineAlignment = StringAlignment.Near;
1590                 }
1591
1592                 if (this.Alignment == ContentAlignment.BottomLeft ||
1593                     this.Alignment == ContentAlignment.MiddleLeft ||
1594                     this.Alignment == ContentAlignment.TopLeft)
1595                 {
1596                     format.Alignment = StringAlignment.Near;
1597                 }
1598                 else if (this.Alignment == ContentAlignment.BottomRight ||
1599                     this.Alignment == ContentAlignment.MiddleRight ||
1600                     this.Alignment == ContentAlignment.TopRight)
1601                 {
1602                     format.Alignment = StringAlignment.Far;
1603                 }
1604
1605                 //***************************************************************
1606                 //** Draw text shadow for the default style when background is not drawn anf ShadowOffset is not null
1607                 //***************************************************************
1608                 Color textShadowColor = ChartGraphics.GetGradientColor(this.ForeColor, Color.Black, 0.8);
1609                 int textShadowOffset = 1;
1610                 TextStyle textStyle = this.TextStyle;
1611                 if ((textStyle == TextStyle.Default || textStyle == TextStyle.Shadow) &&
1612                     !this.BackGroundIsVisible &&
1613                     ShadowOffset != 0)
1614                 {
1615                     // Draw shadowed text
1616                     textStyle = TextStyle.Shadow;
1617                     textShadowColor = ShadowColor;
1618                     textShadowOffset = ShadowOffset;
1619                 }
1620                 
1621                 if (textStyle == TextStyle.Shadow)
1622                 {
1623                     textShadowColor = (textShadowColor.A != 255) ? textShadowColor : Color.FromArgb(textShadowColor.A / 2, textShadowColor);
1624                 }
1625
1626                 //***************************************************************
1627                 //** Replace new line characters
1628                 //***************************************************************
1629                 titleText = titleText.Replace("\\n", "\n");
1630
1631                 //***************************************************************
1632                 //** Define text angle depending on the docking
1633                 //***************************************************************
1634                 Matrix oldTransform = null;
1635                 if (this.IsTextVertical)
1636                 {
1637                     if (this.GetTextOrientation() == TextOrientation.Rotated270)
1638                     {
1639                         // IMPORTANT !
1640                         // Right to Left flag has to be used because of bug with .net with multi line vertical text. As soon as .net bug is fixed this flag HAS TO be removed. Bug number 1870.
1641                         format.FormatFlags |= StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft;
1642
1643                         // Save old graphics transformation
1644                         oldTransform = chartGraph.Transform.Clone();
1645
1646                         // Rotate tile 180 degrees at center
1647                         PointF center = PointF.Empty;
1648
1649                         center.X = absPosition.X + absPosition.Width / 2F;
1650                         center.Y = absPosition.Y + absPosition.Height / 2F;
1651
1652                         // Create and set new transformation matrix
1653                         Matrix newMatrix = chartGraph.Transform.Clone();
1654                         newMatrix.RotateAt(180, center);
1655                         chartGraph.Transform = newMatrix;
1656                     }
1657                     else if (this.GetTextOrientation() == TextOrientation.Rotated90)
1658                     {
1659                         // IMPORTANT !
1660                         // Right to Left flag has to be used because of bug with .net with multi line vertical text. As soon as .net bug is fixed this flag HAS TO be removed. Bug number 1870.
1661                         format.FormatFlags |= StringFormatFlags.DirectionVertical | StringFormatFlags.DirectionRightToLeft;
1662                     }
1663                 }
1664                 try
1665                 {
1666                     chartGraph.IsTextClipped = !Position.Auto;
1667                     Title.DrawStringWithStyle(chartGraph, titleText, textStyle, this.Font, absPosition, this.ForeColor, textShadowColor, textShadowOffset, format, this.GetTextOrientation());
1668                 }
1669                 finally
1670                 {
1671                     chartGraph.IsTextClipped = false;
1672                 }
1673                 // Call Paint event
1674                 if (Common.ProcessModePaint)
1675                     Common.Chart.CallOnPostPaint(new ChartPaintEventArgs(this, chartGraph, Common, Position));
1676             
1677                             //***************************************************************
1678                             //** Restore old transformation
1679                             //***************************************************************
1680                             if(oldTransform != null)
1681                             {
1682                                     chartGraph.Transform = oldTransform;
1683                             }
1684
1685                             if( Common.ProcessModeRegions )
1686                             {
1687 #if !Microsoft_CONTROL
1688                                 Common.HotRegionsList.AddHotRegion( titlePosition, this.ToolTip, this.Url, this.MapAreaAttributes, this.PostBackValue, this, ChartElementType.Title, string.Empty );
1689 #else
1690                                 Common.HotRegionsList.AddHotRegion( titlePosition, this.ToolTip, null, null, null, this, ChartElementType.Title, null );
1691 #endif // !Microsoft_CONTROL
1692                             }
1693             }
1694         }
1695
1696         /// <summary>
1697         /// Draws the string with style.
1698         /// </summary>
1699         /// <param name="chartGraph">The chart graph.</param>
1700         /// <param name="titleText">The title text.</param>
1701         /// <param name="textStyle">The text style.</param>
1702         /// <param name="font">The font.</param>
1703         /// <param name="absPosition">The abs position.</param>
1704         /// <param name="foreColor">Color of the fore.</param>
1705         /// <param name="shadowColor">Color of the shadow.</param>
1706         /// <param name="shadowOffset">The shadow offset.</param>
1707         /// <param name="format">The format.</param>
1708         /// <param name="orientation">The orientation.</param>
1709         internal static void DrawStringWithStyle(
1710             ChartGraphics chartGraph,
1711             string titleText,
1712             TextStyle textStyle, 
1713             Font font,
1714             RectangleF absPosition,
1715             Color foreColor,
1716             Color shadowColor,
1717             int shadowOffset,
1718             StringFormat format,
1719             TextOrientation orientation
1720             )
1721         {
1722             //***************************************************************
1723             //** Draw title text
1724             //***************************************************************
1725             if (titleText.Length > 0)
1726             {
1727                 if (textStyle == TextStyle.Default)
1728                 {
1729                     using (SolidBrush brush = new SolidBrush(foreColor))
1730                     {
1731                         chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
1732                     }
1733                 }
1734                 else if (textStyle == TextStyle.Frame)
1735                 {
1736                     using (GraphicsPath graphicsPath = new GraphicsPath())
1737                     {
1738                         graphicsPath.AddString(
1739                             titleText,
1740                             font.FontFamily,
1741                             (int)font.Style,
1742                             font.Size * 1.3f,
1743                             absPosition,
1744                             format);
1745                         graphicsPath.CloseAllFigures();
1746
1747
1748                         using (Pen pen = new Pen(foreColor, 1))
1749                         {
1750                             chartGraph.DrawPath(pen, graphicsPath);
1751                         }
1752                     }
1753                 }
1754                 else if (textStyle == TextStyle.Embed)
1755                 {
1756                     // Draw shadow
1757                     RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size);
1758                     shadowPosition.X -= 1;
1759                     shadowPosition.Y -= 1;
1760                     using (SolidBrush brush = new SolidBrush(shadowColor))
1761                     {
1762                         chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
1763                     }
1764                     // Draw highlighting
1765                     shadowPosition.X += 2;
1766                     shadowPosition.Y += 2;
1767                     Color texthighlightColor = ChartGraphics.GetGradientColor(Color.White, foreColor, 0.3);
1768                     using (SolidBrush brush = new SolidBrush(texthighlightColor))
1769                     {
1770                         chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
1771                     }
1772                     using (SolidBrush brush = new SolidBrush(foreColor))
1773                     {
1774                         // Draw text
1775                         chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
1776                     }
1777                 }
1778                 else if (textStyle == TextStyle.Emboss)
1779                 {
1780                     // Draw shadow
1781                     RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size);
1782                     shadowPosition.X += 1;
1783                     shadowPosition.Y += 1;
1784                     using (SolidBrush brush = new SolidBrush(shadowColor))
1785                     {
1786                         chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
1787                     }
1788                     // Draw highlighting
1789                     shadowPosition.X -= 2;
1790                     shadowPosition.Y -= 2;
1791                     Color texthighlightColor = ChartGraphics.GetGradientColor(Color.White, foreColor, 0.3);
1792                     using (SolidBrush brush = new SolidBrush(texthighlightColor))
1793                     {
1794                         chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
1795                     }
1796                     // Draw text
1797                     using (SolidBrush brush = new SolidBrush(foreColor))
1798                     {
1799                         chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
1800                     }
1801
1802                 }
1803                 else if (textStyle == TextStyle.Shadow)
1804                 {
1805                     // Draw shadow
1806                     RectangleF shadowPosition = new RectangleF(absPosition.Location, absPosition.Size);
1807                     shadowPosition.X += shadowOffset;
1808                     shadowPosition.Y += shadowOffset;
1809                     using (SolidBrush brush = new SolidBrush(shadowColor))
1810                     {
1811                         chartGraph.DrawString(titleText, font, brush, shadowPosition, format, orientation);
1812                     }
1813                     // Draw text
1814                     using (SolidBrush brush = new SolidBrush(foreColor))
1815                     {
1816                         chartGraph.DrawString(titleText, font, brush, absPosition, format, orientation);
1817                     }
1818
1819                 }
1820             }
1821         }
1822
1823                 #endregion 
1824
1825                 #region Position Calculation Methods
1826
1827                 /// <summary>
1828                 /// Recalculates title position.
1829                 /// </summary>
1830                 /// <param name="chartGraph">Chart graphics used.</param>
1831                 /// <param name="chartAreasRectangle">Area where the title should be docked.</param>
1832                 /// <param name="frameTitlePosition">Position of the title in the frame.</param>
1833                 /// <param name="elementSpacing">Spacing size in percentage of the area.</param>
1834                 internal void CalcTitlePosition(
1835                         ChartGraphics chartGraph, 
1836                         ref RectangleF chartAreasRectangle, 
1837                         ref RectangleF frameTitlePosition,
1838                         float elementSpacing)
1839                 {
1840                         // Special case for the first title docked to the top when the title frame is used
1841                         if(!frameTitlePosition.IsEmpty && 
1842                                 this.Position.Auto &&
1843                                 this.Docking == Docking.Top &&
1844                 this.DockedToChartArea == Constants.NotSetValue)
1845                         {
1846                                 this.Position.SetPositionNoAuto(
1847                                         frameTitlePosition.X + elementSpacing, 
1848                                         frameTitlePosition.Y, 
1849                                         frameTitlePosition.Width - 2f * elementSpacing, 
1850                                         frameTitlePosition.Height);
1851                                 frameTitlePosition = RectangleF.Empty;
1852                                 return;
1853                         }
1854
1855                         // Get title size
1856                         RectangleF              titlePosition = new RectangleF();
1857                         SizeF                   layoutArea = new SizeF(chartAreasRectangle.Width, chartAreasRectangle.Height);
1858
1859                         // Switch width and height for vertical text
1860             if (this.IsTextVertical)
1861             {
1862                 float tempValue = layoutArea.Width;
1863                 layoutArea.Width = layoutArea.Height;
1864                 layoutArea.Height = tempValue;
1865             }
1866
1867                         // Meausure text size
1868                         layoutArea.Width -= 2f * elementSpacing;
1869                         layoutArea.Height -= 2f * elementSpacing;
1870                         layoutArea = chartGraph.GetAbsoluteSize(layoutArea);
1871                         SizeF titleSize = chartGraph.MeasureString(
1872                 "W" + this.Text.Replace("\\n", "\n"), 
1873                                 this.Font, 
1874                                 layoutArea, 
1875                                 StringFormat.GenericDefault,
1876                 this.GetTextOrientation());
1877
1878             // Increase text size by 4 pixels
1879                         if(this.BackGroundIsVisible)
1880                         {
1881                                 titleSize.Width += titleBorderSpacing;
1882                                 titleSize.Height += titleBorderSpacing;
1883                         }
1884
1885                         // Switch width and height for vertical text
1886             if (this.IsTextVertical)
1887             {
1888                 float tempValue = titleSize.Width;
1889                 titleSize.Width = titleSize.Height;
1890                 titleSize.Height = tempValue;
1891             }
1892
1893                         // Convert text size to relative coordinates
1894                         titleSize = chartGraph.GetRelativeSize(titleSize);
1895                         titlePosition.Height = titleSize.Height;
1896                         titlePosition.Width = titleSize.Width;
1897                         if(float.IsNaN(titleSize.Height) || float.IsNaN(titleSize.Width))
1898                         {
1899                                 return;
1900                         }
1901
1902                         // Calculate title position
1903                         if(this.Docking == Docking.Top)
1904                         {
1905                                 titlePosition.Y = chartAreasRectangle.Y + elementSpacing;
1906                                 titlePosition.X = chartAreasRectangle.X + elementSpacing;
1907                                 titlePosition.Width = chartAreasRectangle.Right - titlePosition.X - elementSpacing;
1908                                 if(titlePosition.Width < 0)
1909                                 {
1910                                         titlePosition.Width = 0;
1911                                 }
1912
1913                                 // Adjust position of the chart area(s)
1914                                 chartAreasRectangle.Height -= titlePosition.Height + elementSpacing;
1915                                 chartAreasRectangle.Y = titlePosition.Bottom;
1916                         }
1917                         else if(this.Docking == Docking.Bottom)
1918                         {
1919                                 titlePosition.Y = chartAreasRectangle.Bottom - titleSize.Height - elementSpacing;
1920                                 titlePosition.X = chartAreasRectangle.X + elementSpacing;
1921                                 titlePosition.Width = chartAreasRectangle.Right - titlePosition.X - elementSpacing;
1922                                 if(titlePosition.Width < 0)
1923                                 {
1924                                         titlePosition.Width = 0;
1925                                 }
1926
1927                                 // Adjust position of the chart area(s)
1928                                 chartAreasRectangle.Height -= titlePosition.Height + elementSpacing;
1929                         }
1930                         if(this.Docking == Docking.Left)
1931                         {
1932                                 titlePosition.X = chartAreasRectangle.X + elementSpacing;
1933                                 titlePosition.Y = chartAreasRectangle.Y + elementSpacing;
1934                                 titlePosition.Height = chartAreasRectangle.Bottom - titlePosition.Y - elementSpacing;
1935                                 if(titlePosition.Height < 0)
1936                                 {
1937                                         titlePosition.Height = 0;
1938                                 }
1939
1940                                 // Adjust position of the chart area(s)
1941                                 chartAreasRectangle.Width -= titlePosition.Width + elementSpacing;
1942                                 chartAreasRectangle.X = titlePosition.Right;
1943                         }
1944                         if(this.Docking == Docking.Right)
1945                         {
1946                                 titlePosition.X = chartAreasRectangle.Right - titleSize.Width - elementSpacing;
1947                                 titlePosition.Y = chartAreasRectangle.Y + elementSpacing;
1948                                 titlePosition.Height = chartAreasRectangle.Bottom - titlePosition.Y - elementSpacing;
1949                                 if(titlePosition.Height < 0)
1950                                 {
1951                                         titlePosition.Height = 0;
1952                                 }
1953
1954                                 // Adjust position of the chart area(s)
1955                                 chartAreasRectangle.Width -= titlePosition.Width + elementSpacing;
1956                         }
1957
1958
1959                         // Offset calculated docking position
1960                         if(this.DockingOffset != 0)
1961                         {
1962                                 if(this.Docking == Docking.Top || this.Docking == Docking.Bottom)
1963                                 {
1964                                         titlePosition.Y += this.DockingOffset;
1965                                 }
1966                                 else
1967                                 {
1968                                         titlePosition.X += this.DockingOffset;
1969                                 }
1970                         }
1971
1972                         this.Position.SetPositionNoAuto(titlePosition.X, titlePosition.Y, titlePosition.Width, titlePosition.Height);
1973                 }
1974
1975                 #endregion
1976
1977         #region IDisposable Members
1978
1979         /// <summary>
1980         /// Releases unmanaged and - optionally - managed resources
1981         /// </summary>
1982         /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
1983         protected override void Dispose(bool disposing)
1984         {
1985             if (disposing)
1986             {
1987                 if (_fontCache != null)
1988                 {
1989                     _fontCache.Dispose();
1990                     _fontCache = null;
1991                 }
1992                 if (_position != null)
1993                 {
1994                     _position.Dispose();
1995                     _position = null;
1996                 }
1997             }
1998         }
1999
2000
2001         #endregion
2002         }
2003
2004         /// <summary>
2005     /// The TitleCollection class is a strongly typed collection of Title classes.
2006     /// Indexer of this collection can take the title index (integer) or unique 
2007     /// title name (string) as a parameter.
2008         /// </summary>
2009         [
2010                 SRDescription("DescriptionAttributeTitles"),
2011         ]
2012 #if ASPPERM_35
2013         [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
2014     [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
2015 #endif
2016     public class TitleCollection : ChartNamedElementCollection<Title>
2017         {
2018
2019                 #region Constructors
2020
2021                 /// <summary>
2022         /// TitleCollection constructor.
2023                 /// </summary>
2024                 /// <param name="parent">Parent chart element.</param>
2025         internal TitleCollection(IChartElement parent)
2026             : base(parent)
2027         {
2028         }
2029
2030                 #endregion 
2031
2032                 #region Methods
2033
2034         /// <summary>
2035         /// Creates a new Title with the specified name and adds it to the collection.
2036         /// </summary>
2037         /// <param name="name">The new chart area name.</param>
2038         /// <returns>New title</returns>
2039         public Title Add(string name)
2040         {
2041             Title title = new Title(name);
2042             this.Add(title);
2043             return title;
2044         }
2045
2046
2047                 /// <summary>
2048                 /// Recalculates title position in the collection for titles docked outside of chart area.
2049                 /// </summary>
2050                 /// <param name="chartPicture">Chart picture object.</param>
2051                 /// <param name="chartGraph">Chart graphics used.</param>
2052                 /// <param name="area">Area the title is docked to.</param>
2053                 /// <param name="chartAreasRectangle">Area where the title should be positioned.</param>
2054                 /// <param name="elementSpacing">Spacing size in percentage of the area.</param>
2055                 internal static void CalcOutsideTitlePosition(
2056                         ChartPicture chartPicture,
2057                         ChartGraphics chartGraph, 
2058                         ChartArea area,
2059                         ref RectangleF chartAreasRectangle, 
2060                         float elementSpacing)
2061                 {
2062                         if(chartPicture != null)
2063                         {
2064                                 // Get elemets spacing
2065                                 float areaSpacing = Math.Min((chartAreasRectangle.Height/100F) * elementSpacing, (chartAreasRectangle.Width/100F) * elementSpacing);
2066
2067                                 // Loop through all titles
2068                                 foreach(Title title in chartPicture.Titles)
2069                                 {
2070                                         // Check if title visible
2071                                         if(!title.IsVisible())
2072                                         {
2073                                                 continue;
2074                                         }
2075
2076                                         // Check if all chart area names are valid
2077                     if (title.DockedToChartArea != Constants.NotSetValue && chartPicture.ChartAreas.IndexOf(title.DockedToChartArea)<0)
2078                     {
2079                         throw (new ArgumentException(SR.ExceptionChartTitleDockedChartAreaIsMissing((string)title.DockedToChartArea)));
2080                     }
2081
2082                                         // Process only titles docked to specified area
2083                                         if(title.IsDockedInsideChartArea == false &&
2084                                                 title.DockedToChartArea == area.Name && 
2085                                                 title.Position.Auto)
2086                                         {
2087                                                 // Calculate title position
2088                                                 RectangleF frameRect = RectangleF.Empty;
2089                         RectangleF prevChartAreasRectangle = chartAreasRectangle;
2090                                                 title.CalcTitlePosition(chartGraph, 
2091                                                         ref chartAreasRectangle,
2092                                                         ref frameRect,
2093                                                         areaSpacing);
2094
2095                                                 // Adjust title position
2096                                                 RectangleF titlePosition = title.Position.ToRectangleF();
2097                                                 if(title.Docking == Docking.Top)
2098                                                 {
2099                                                         titlePosition.Y -= areaSpacing;
2100                                                         if(!area.Position.Auto)
2101                                                         {
2102                                                                 titlePosition.Y -= titlePosition.Height;
2103                                 prevChartAreasRectangle.Y -= titlePosition.Height + areaSpacing;
2104                                 prevChartAreasRectangle.Height += titlePosition.Height + areaSpacing;
2105                                                         }
2106                                                 }
2107                                                 else if(title.Docking == Docking.Bottom)
2108                                                 {
2109                                                         titlePosition.Y += areaSpacing;
2110                                                         if(!area.Position.Auto)
2111                                                         {
2112                                 titlePosition.Y = prevChartAreasRectangle.Bottom + areaSpacing;
2113                                 prevChartAreasRectangle.Height += titlePosition.Height +areaSpacing;
2114                                                         }
2115                                                 }
2116                                                 if(title.Docking == Docking.Left)
2117                                                 {
2118                                                         titlePosition.X -= areaSpacing;
2119                                                         if(!area.Position.Auto)
2120                                                         {
2121                                                                 titlePosition.X -= titlePosition.Width;
2122                                 prevChartAreasRectangle.X -= titlePosition.Width + areaSpacing;
2123                                 prevChartAreasRectangle.Width += titlePosition.Width + areaSpacing;
2124                             }
2125                                                 }
2126                                                 if(title.Docking == Docking.Right)
2127                                                 {
2128                                                         titlePosition.X += areaSpacing;
2129                                                         if(!area.Position.Auto)
2130                                                         {
2131                                 titlePosition.X = prevChartAreasRectangle.Right + areaSpacing;
2132                                 prevChartAreasRectangle.Width += titlePosition.Width + areaSpacing;
2133                                                         }
2134                                                 }
2135
2136                         // Set title position without changing the 'Auto' flag
2137                                                 title.Position.SetPositionNoAuto(titlePosition.X, titlePosition.Y, titlePosition.Width, titlePosition.Height);
2138
2139                         // If custom position is used in the chart area reset the curent adjusted position
2140                         if (!area.Position.Auto)
2141                         {
2142                             chartAreasRectangle = prevChartAreasRectangle;
2143                         }
2144
2145                                         }
2146                                 }
2147
2148                         }
2149                 }
2150
2151                 /// <summary>
2152                 /// Recalculates all titles position inside chart area in the collection.
2153                 /// </summary>
2154                 /// <param name="chartPicture">Chart picture object.</param>
2155                 /// <param name="chartGraph">Chart graphics used.</param>
2156                 /// <param name="elementSpacing">Spacing size in percentage of the area.</param>
2157                 internal static void CalcInsideTitlePosition(
2158                         ChartPicture chartPicture,
2159                         ChartGraphics chartGraph, 
2160                         float elementSpacing)
2161                 {
2162                         if(chartPicture != null)
2163                         {
2164                                 // Check if all chart area names are valid
2165                                 foreach(Title title in chartPicture.Titles)
2166                                 {
2167                                         // Check if title visible
2168                                         if(!title.IsVisible())
2169                                         {
2170                                                 continue;
2171                                         }
2172
2173                     if (title.DockedToChartArea != Constants.NotSetValue)
2174                                         {
2175                                                 try
2176                                                 {
2177                                                         ChartArea area = chartPicture.ChartAreas[title.DockedToChartArea];
2178                                                 }
2179                                                 catch
2180                                                 {
2181                                                         throw(new ArgumentException( SR.ExceptionChartTitleDockedChartAreaIsMissing( (string)title.DockedToChartArea ) ) );
2182                                                 }
2183                                         }
2184                                 }
2185
2186                                 // Loop through all chart areas
2187                                 foreach(ChartArea area in chartPicture.ChartAreas)
2188                                 {
2189
2190                                         // Check if chart area is visible
2191                                         if(area.Visible)
2192
2193                                         {
2194                                                 // Get area position
2195                                                 RectangleF titlePlottingRectangle = area.PlotAreaPosition.ToRectangleF();
2196
2197                                                 // Get elemets spacing
2198                                                 float areaSpacing = Math.Min((titlePlottingRectangle.Height/100F) * elementSpacing, (titlePlottingRectangle.Width/100F) * elementSpacing);
2199
2200                                                 // Loop through all titles
2201                                                 foreach(Title title in chartPicture.Titles)
2202                                                 {
2203                                                         if(title.IsDockedInsideChartArea == true &&
2204                                                                 title.DockedToChartArea == area.Name && 
2205                                                                 title.Position.Auto)
2206                                                         {
2207                                                                 // Calculate title position
2208                                                                 RectangleF frameRect = RectangleF.Empty;
2209                                                                 title.CalcTitlePosition(chartGraph, 
2210                                                                         ref titlePlottingRectangle, 
2211                                                                         ref frameRect,
2212                                                                         areaSpacing);
2213                                                         }
2214                                                 }
2215                                         }
2216                                 }
2217                         }
2218                 }
2219
2220                 #endregion
2221
2222         #region Event handlers
2223         internal void ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e)
2224         {
2225             //If all the chart areas are removed and then the first one is added we don't want to dock the titles
2226             if (e.OldElement == null)
2227                 return;
2228
2229             foreach (Title title in this)
2230                 if (title.DockedToChartArea == e.OldName)
2231                     title.DockedToChartArea = e.NewName;
2232         }
2233         #endregion
2234
2235
2236         }
2237 }