1207 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			1207 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.ComponentModel;
 | |
| using System.Drawing;
 | |
| using System.Drawing.Design;
 | |
| using System.Drawing.Drawing2D;
 | |
| using DevComponents.Charts.TextMarkup;
 | |
| using DevComponents.DotNetBar.Charts.Style;
 | |
| 
 | |
| namespace DevComponents.DotNetBar.Charts
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Represents the collection of ChartTitles.
 | |
|     /// </summary>
 | |
|     [Editor("DevComponents.Charts.Design.ChartTitleCollectionEditor, DevComponents.Charts.Design, " +
 | |
|             "Version=14.1.0.37, Culture=neutral,  PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
 | |
|     public class ChartTitleCollection : CustomNamedCollection<ChartTitle>
 | |
|     {
 | |
|         public ChartTitleCollection()
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         #region GetUniqueName
 | |
| 
 | |
|         public string GetUniqueName()
 | |
|         {
 | |
|             return (GetUniqueName("Title"));
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| 
 | |
|     /// <summary>
 | |
|     /// ChartTitle
 | |
|     /// </summary>
 | |
|     public class ChartTitle : ChartNote
 | |
|     {
 | |
|         #region Private variables
 | |
| 
 | |
|         private States _States;
 | |
|         private XyAlignment _XyAlignment = XyAlignment.NotSet;
 | |
|         private RotateDegrees _RotateDegrees = RotateDegrees.NotSet;
 | |
| 
 | |
|         private ChartTitleVisualStyle _ChartTitleVisualStyle;
 | |
|         private EffectiveStyle<ChartTitleVisualStyle> _EffectiveTitleStyle;
 | |
| 
 | |
|         private Rectangle _FrameBounds;
 | |
|         private Rectangle _ContentBounds;
 | |
|         private int _TextHeight;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Constructors
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates a new ChartTitle
 | |
|         /// </summary>
 | |
|         public ChartTitle()
 | |
|             : this(null, null)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates a new ChartTitle
 | |
|         /// </summary>
 | |
|         /// <param name="name">Title name</param>
 | |
|         public ChartTitle(string name)
 | |
|             : this(name, null)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates a new ChartTitle
 | |
|         /// </summary>
 | |
|         /// <param name="name">Title Name</param>
 | |
|         /// <param name="text">Title Text</param>
 | |
|         public ChartTitle(string name, string text)
 | |
|         {
 | |
|             InitDefaultStates();
 | |
| 
 | |
|             Name = name;
 | |
|             Text = text;
 | |
| 
 | |
|             _EffectiveTitleStyle = new EffectiveStyle<ChartTitleVisualStyle>(this);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region InitDefaultStates
 | |
| 
 | |
|         private void InitDefaultStates()
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Public properties
 | |
| 
 | |
|         #region ChartTitleVisualStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the visual style for the Title.
 | |
|         /// </summary>
 | |
|         [Category("Style")]
 | |
|         [Description("Indicates the visual style for the Title.")]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
 | |
|         public ChartTitleVisualStyle ChartTitleVisualStyle
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_ChartTitleVisualStyle == null)
 | |
|                 {
 | |
|                     _ChartTitleVisualStyle = new ChartTitleVisualStyle();
 | |
| 
 | |
|                     StyleVisualChangeHandler(null, _ChartTitleVisualStyle);
 | |
|                 }
 | |
| 
 | |
|                 return (_ChartTitleVisualStyle);
 | |
|             }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (_ChartTitleVisualStyle != value)
 | |
|                 {
 | |
|                     ChartTitleVisualStyle oldValue = _ChartTitleVisualStyle;
 | |
| 
 | |
|                     _ChartTitleVisualStyle = value;
 | |
| 
 | |
|                     OnStyleChanged("ChartTitleVisualStyle", oldValue, value);
 | |
| 
 | |
|                     if (oldValue != null)
 | |
|                         oldValue.Dispose();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region EffectiveTitleStyle
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a reference to the title's effective (cached, composite) style.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
 | |
|         public ChartTitleVisualStyle EffectiveTitleStyle
 | |
|         {
 | |
|             get { return (_EffectiveTitleStyle.Style); }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RotateDegrees
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the title's display rotation.
 | |
|         /// </summary>
 | |
|         [DefaultValue(RotateDegrees.NotSet), Category("Layout")]
 | |
|         [Description("Indicates the title's display rotation.")]
 | |
|         public RotateDegrees RotateDegrees
 | |
|         {
 | |
|             get { return (_RotateDegrees); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _RotateDegrees)
 | |
|                 {
 | |
|                     _RotateDegrees = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("RotateDegrees", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region XyAlignment
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the X/Y Alignment for the title.
 | |
|         /// </summary>
 | |
|         [DefaultValue(XyAlignment.NotSet), Category("Layout")]
 | |
|         [Description("Indicates the X/Y Alignment for the title.")]
 | |
|         public XyAlignment XyAlignment
 | |
|         {
 | |
|             get { return (_XyAlignment); }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 if (value != _XyAlignment)
 | |
|                 {
 | |
|                     _XyAlignment = value;
 | |
| 
 | |
|                     OnPropertyChangedEx("XyAlignment", VisualChangeType.Layout);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MeasureOverride
 | |
| 
 | |
|         protected override void MeasureOverride(ChartLayoutInfo layoutInfo)
 | |
|         {
 | |
|             Graphics g = layoutInfo.Graphics;
 | |
|             ChartTitleVisualStyle style = EffectiveTitleStyle;
 | |
| 
 | |
|             Size size = Size.Empty;
 | |
|             Rectangle layoutBounds = layoutInfo.LayoutBounds;
 | |
| 
 | |
|             RotateDegrees rotDegrees = GetRotateDegrees(style);
 | |
| 
 | |
|             if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270)
 | |
|                 layoutBounds.Size = new Size(layoutBounds.Height, layoutBounds.Width);
 | |
| 
 | |
|             Thickness brdThickness = style.BorderThickness;
 | |
|             Size ncSize = GetNonContentSize(style, brdThickness);
 | |
| 
 | |
|             layoutBounds.Width -= ncSize.Width;
 | |
|             layoutBounds.Height -= ncSize.Height;
 | |
| 
 | |
|             Alignment imageAlignment = style.ImageAlignment;
 | |
|             Size imageSize = style.GetFigureSize(g);
 | |
| 
 | |
|             if (layoutBounds.Width > 0 && layoutBounds.Height > 0)
 | |
|             {
 | |
|                 if (imageSize.IsEmpty == false)
 | |
|                 {
 | |
|                     if (style.IsOverlayImage == true)
 | |
|                         imageAlignment = Alignment.MiddleCenter;
 | |
| 
 | |
|                     else if (imageAlignment == Alignment.NotSet)
 | |
|                         imageAlignment = Alignment.MiddleLeft;
 | |
| 
 | |
|                     switch (imageAlignment)
 | |
|                     {
 | |
|                         case Alignment.TopLeft:
 | |
|                         case Alignment.TopRight:
 | |
|                         case Alignment.BottomLeft:
 | |
|                         case Alignment.BottomRight:
 | |
|                         case Alignment.MiddleLeft:
 | |
|                         case Alignment.MiddleRight:
 | |
|                             if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270)
 | |
|                                 layoutBounds.Height -= imageSize.Width;
 | |
|                             else
 | |
|                                 layoutBounds.Width -= imageSize.Width;
 | |
|                             break;
 | |
| 
 | |
|                         case Alignment.TopCenter:
 | |
|                         case Alignment.BottomCenter:
 | |
|                             layoutBounds.Height -= imageSize.Height;
 | |
|                             break;
 | |
|                     }
 | |
| 
 | |
|                     if (layoutBounds.Size.Width > 0 && layoutBounds.Size.Height > 0)
 | |
|                         size = MeasureText(g, style, layoutBounds.Size);
 | |
| 
 | |
|                     switch (imageAlignment)
 | |
|                     {
 | |
|                         case Alignment.TopLeft:
 | |
|                         case Alignment.TopRight:
 | |
|                         case Alignment.MiddleLeft:
 | |
|                         case Alignment.MiddleRight:
 | |
|                         case Alignment.BottomLeft:
 | |
|                         case Alignment.BottomRight:
 | |
|                             size.Width += imageSize.Width;
 | |
|                             size.Height = Math.Max(imageSize.Height, size.Height);
 | |
|                             break;
 | |
| 
 | |
|                         case Alignment.TopCenter:
 | |
|                         case Alignment.BottomCenter:
 | |
|                             size.Height += imageSize.Height;
 | |
|                             size.Width = Math.Max(imageSize.Width, size.Width);
 | |
|                             break;
 | |
| 
 | |
|                         case Alignment.MiddleCenter:
 | |
|                             size.Height = Math.Max(imageSize.Height, size.Height);
 | |
|                             size.Width = Math.Max(imageSize.Width, size.Width);
 | |
|                             break;
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     size = MeasureText(g, style, layoutBounds.Size);
 | |
|                 }
 | |
| 
 | |
|                 size.Width += ncSize.Width;
 | |
|                 size.Height += ncSize.Height;
 | |
|             }
 | |
| 
 | |
|             if (FixedHeight > 0)
 | |
|                 size.Height = Dpi.Height(FixedHeight);
 | |
| 
 | |
|             Rectangle bounds = layoutBounds;
 | |
| 
 | |
|             if (style.Stretch == Tbool.True)
 | |
|             {
 | |
|                 switch (XyAlignment)
 | |
|                 {
 | |
|                     case XyAlignment.Left:
 | |
|                     case XyAlignment.Right:
 | |
|                         if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270)
 | |
|                             size.Width = layoutInfo.LayoutBounds.Height;
 | |
|                         break;
 | |
| 
 | |
|                     default:
 | |
|                         if (rotDegrees != RotateDegrees.Rotate90 && rotDegrees != RotateDegrees.Rotate270)
 | |
|                             size.Width = layoutInfo.LayoutBounds.Width;
 | |
|                         break;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             Rectangle rb = bounds;
 | |
| 
 | |
|             if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270)
 | |
|                 bounds.Size = new Size(size.Height, size.Width);
 | |
|             else
 | |
|                 bounds.Size = size;
 | |
| 
 | |
|             if (bounds.Width > layoutInfo.LayoutBounds.Width)
 | |
|                 bounds.Width = layoutInfo.LayoutBounds.Width;
 | |
| 
 | |
|             if (bounds.Height > layoutInfo.LayoutBounds.Height)
 | |
|                 bounds.Height = layoutInfo.LayoutBounds.Height;
 | |
| 
 | |
|             Size = bounds.Size;
 | |
| 
 | |
|             bounds = AlignTitle(layoutInfo, bounds, style);
 | |
| 
 | |
|             _FrameBounds = GetAdjustedBoundsRot(bounds, style.Margin);
 | |
| 
 | |
|             if (style.DropShadow.Enabled == Tbool.True)
 | |
|             {
 | |
|                 _FrameBounds.Width -= 3;
 | |
|                 _FrameBounds.Height -= 3;
 | |
|             }
 | |
| 
 | |
|             _ContentBounds = _FrameBounds;
 | |
| 
 | |
|             if (brdThickness.IsEmpty == false)
 | |
|             {
 | |
|                 _ContentBounds.X += brdThickness.Left;
 | |
|                 _ContentBounds.Width -= brdThickness.Horizontal;
 | |
| 
 | |
|                 _ContentBounds.Y += brdThickness.Top;
 | |
|                 _ContentBounds.Height -= brdThickness.Vertical;
 | |
|             }
 | |
| 
 | |
|             if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270)
 | |
|                 _ContentBounds = GetAdjustedBoundsRot(_ContentBounds, style.Padding);
 | |
|             else
 | |
|                 _ContentBounds = GetAdjustedBounds(_ContentBounds, style.Padding);
 | |
| 
 | |
|             if (imageSize.IsEmpty == false)
 | |
|             {
 | |
|                 if (rotDegrees == RotateDegrees.Rotate90 || rotDegrees == RotateDegrees.Rotate270)
 | |
|                     AdjustVerticalContent(rotDegrees, imageAlignment, imageSize);
 | |
|                 else
 | |
|                     AdjustHorizontalContent(imageAlignment, imageSize);
 | |
|             }
 | |
| 
 | |
|             BoundsRelative = bounds;
 | |
|         }
 | |
| 
 | |
|         #region GetAdjustedBoundsRot
 | |
| 
 | |
|         internal Rectangle GetAdjustedBoundsRot(Rectangle bounds, Thickness thickness)
 | |
|         {
 | |
|             if (thickness.IsEmpty == false)
 | |
|             {
 | |
|                 if (bounds.Width > Dpi.Height(thickness.Vertical))
 | |
|                 {
 | |
|                     bounds.X += Dpi.Height(thickness.Top);
 | |
|                     bounds.Width -= Dpi.Height(thickness.Vertical);
 | |
|                 }
 | |
| 
 | |
|                 if (bounds.Height > Dpi.Width(thickness.Horizontal))
 | |
|                 {
 | |
|                     bounds.Y += Dpi.Width(thickness.Left);
 | |
|                     bounds.Height -= Dpi.Width(thickness.Horizontal);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (bounds);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetNonContentSize
 | |
| 
 | |
|         private Size GetNonContentSize(ChartTitleVisualStyle style, Thickness brdThickness)
 | |
|         {
 | |
|             Size size = Size.Empty;
 | |
| 
 | |
|             size.Width = Dpi.Width(style.Margin.Horizontal + brdThickness.Horizontal + style.Padding.Horizontal);
 | |
|             size.Height = Dpi.Height(style.Margin.Vertical + brdThickness.Vertical + style.Padding.Vertical);
 | |
| 
 | |
|             if (style.DropShadow.Enabled == Tbool.True)
 | |
|             {
 | |
|                 size.Width += 3;
 | |
|                 size.Height += 3;
 | |
|             }
 | |
| 
 | |
|             return (size);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region AdjustVerticalContent
 | |
| 
 | |
|         private void AdjustVerticalContent(
 | |
|             RotateDegrees rotDegrees, Alignment imageAlignment, Size imageSize)
 | |
|         {
 | |
|             switch (imageAlignment)
 | |
|             {
 | |
|                 case Alignment.TopLeft:
 | |
|                 case Alignment.MiddleLeft:
 | |
|                 case Alignment.BottomLeft:
 | |
|                     if (rotDegrees == RotateDegrees.Rotate90)
 | |
|                         _ContentBounds.Y += imageSize.Width;
 | |
| 
 | |
|                     else if (rotDegrees == RotateDegrees.Rotate270)
 | |
|                         _ContentBounds.Y += imageSize.Width;
 | |
|                     else
 | |
|                         _ContentBounds.X += imageSize.Height;
 | |
| 
 | |
|                     _ContentBounds.Height -= imageSize.Width;
 | |
|                     break;
 | |
| 
 | |
|                 case Alignment.TopCenter:
 | |
|                     if (rotDegrees == RotateDegrees.Rotate90)
 | |
|                         _ContentBounds.X += imageSize.Height;
 | |
| 
 | |
|                     else if (rotDegrees == RotateDegrees.Rotate270)
 | |
|                         _ContentBounds.X += imageSize.Height;
 | |
|                     else
 | |
|                         _ContentBounds.Y += imageSize.Width;
 | |
| 
 | |
|                     _ContentBounds.Width -= imageSize.Height;
 | |
|                     break;
 | |
| 
 | |
|                 case Alignment.BottomCenter:
 | |
|                     _ContentBounds.Width -= imageSize.Height;
 | |
|                     break;
 | |
| 
 | |
|                 case Alignment.TopRight:
 | |
|                 case Alignment.MiddleRight:
 | |
|                 case Alignment.BottomRight:
 | |
|                     _ContentBounds.Height -= imageSize.Width;
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region AdjustHorizontalContent
 | |
| 
 | |
|         private void AdjustHorizontalContent(
 | |
|             Alignment imageAlignment, Size imageSize)
 | |
|         {
 | |
|             switch (imageAlignment)
 | |
|             {
 | |
|                 case Alignment.TopLeft:
 | |
|                 case Alignment.MiddleLeft:
 | |
|                 case Alignment.BottomLeft:
 | |
|                     _ContentBounds.X += imageSize.Width;
 | |
|                     _ContentBounds.Width -= imageSize.Width;
 | |
|                     break;
 | |
| 
 | |
|                 case Alignment.TopCenter:
 | |
|                     _ContentBounds.Y += imageSize.Height;
 | |
|                     _ContentBounds.Height -= imageSize.Height;
 | |
|                     break;
 | |
| 
 | |
|                 case Alignment.BottomCenter:
 | |
|                     _ContentBounds.Height -= imageSize.Height;
 | |
|                     break;
 | |
| 
 | |
|                 case Alignment.TopRight:
 | |
|                 case Alignment.MiddleRight:
 | |
|                 case Alignment.BottomRight:
 | |
|                     _ContentBounds.Width -= imageSize.Width;
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region MeasureText
 | |
| 
 | |
|         private Size MeasureText(Graphics g, ChartTitleVisualStyle style, Size vsize)
 | |
|         {
 | |
|             Size size = Size.Empty;
 | |
| 
 | |
|             string s = Text;
 | |
| 
 | |
|             if (string.IsNullOrEmpty(s) == false)
 | |
|             {
 | |
|                 if (TextMarkup != null)
 | |
|                 {
 | |
|                     size = GetMarkupTextSize(g,
 | |
|                         TextMarkup, style, (vsize.Width > 0 ? vsize.Width : 10000));
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     using (StringFormat sf = new StringFormat())
 | |
|                     {
 | |
|                         style.GetStringFormatFlags(sf);
 | |
| 
 | |
|                         if (style.MaxLineCount <= 1)
 | |
|                             sf.FormatFlags |= StringFormatFlags.NoWrap;
 | |
| 
 | |
|                         size = g.MeasureString(Text, style.Font, vsize, sf).ToSize();
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 size.Width++;
 | |
|                 size.Height++;
 | |
| 
 | |
|                 if (style.MaxLineCount > 1)
 | |
|                 {
 | |
|                     int lineHeight = (int)(Math.Ceiling(style.Font.GetHeight())) * style.MaxLineCount;
 | |
| 
 | |
|                     if (size.Height > lineHeight)
 | |
|                         size.Height = lineHeight;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             _TextHeight = size.Height;
 | |
| 
 | |
|             return (size);
 | |
|         }
 | |
| 
 | |
|         #region GetMarkupTextSize
 | |
| 
 | |
|         private Size GetMarkupTextSize(Graphics g,
 | |
|             BodyElement textMarkup, ChartTitleVisualStyle style, int width)
 | |
|         {
 | |
|             MarkupDrawContext d =
 | |
|                 new MarkupDrawContext(g, style.Font, style.TextColor, false);
 | |
| 
 | |
|             textMarkup.InvalidateElementsSize();
 | |
|             textMarkup.Measure(new Size(width, 0), d);
 | |
| 
 | |
|             return (textMarkup.Bounds.Size);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region AlignTitle
 | |
| 
 | |
|         private Rectangle AlignTitle(
 | |
|             ChartLayoutInfo layoutInfo, Rectangle bounds, ChartTitleVisualStyle style)
 | |
|         {
 | |
|             Rectangle layoutBounds = layoutInfo.LayoutBounds;
 | |
| 
 | |
|             switch (XyAlignment)
 | |
|             {
 | |
|                 case XyAlignment.Left:
 | |
|                     layoutInfo.LayoutBounds.X += Size.Width;
 | |
|                     layoutInfo.LayoutBounds.Width -= Size.Width;
 | |
|                     break;
 | |
| 
 | |
|                 case XyAlignment.Bottom:
 | |
|                     bounds.Y = layoutBounds.Bottom - Size.Height;
 | |
|                     layoutInfo.LayoutBounds.Height -= Size.Height;
 | |
|                     break;
 | |
| 
 | |
|                 case XyAlignment.Right:
 | |
|                     bounds.X = layoutBounds.Right - Size.Width;
 | |
|                     layoutInfo.LayoutBounds.Width -= Size.Width;
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     layoutInfo.LayoutBounds.Y += Size.Height;
 | |
|                     layoutInfo.LayoutBounds.Height -= Size.Height;
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             if (XyAlignment == XyAlignment.Left || XyAlignment == XyAlignment.Right)
 | |
|             {
 | |
|                 if (bounds.Height < layoutBounds.Height)
 | |
|                 {
 | |
|                     switch (style.Alignment)
 | |
|                     {
 | |
|                         case Alignment.TopCenter:
 | |
|                         case Alignment.MiddleCenter:
 | |
|                         case Alignment.BottomCenter:
 | |
|                             bounds.Y += (layoutBounds.Height - bounds.Height) / 2;
 | |
|                             break;
 | |
| 
 | |
|                         case Alignment.TopLeft:
 | |
|                         case Alignment.MiddleLeft:
 | |
|                         case Alignment.BottomLeft:
 | |
|                             bounds.Y = layoutBounds.Bottom - bounds.Height;
 | |
|                             break;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 if (bounds.Width < layoutBounds.Width)
 | |
|                 {
 | |
|                     switch (style.Alignment)
 | |
|                     {
 | |
|                         case Alignment.TopCenter:
 | |
|                         case Alignment.MiddleCenter:
 | |
|                         case Alignment.BottomCenter:
 | |
|                             bounds.X += (layoutBounds.Width - bounds.Width) / 2;
 | |
|                             break;
 | |
| 
 | |
|                         case Alignment.TopRight:
 | |
|                         case Alignment.MiddleRight:
 | |
|                         case Alignment.BottomRight:
 | |
|                             bounds.X = layoutBounds.Right - bounds.Width;
 | |
|                             break;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (bounds);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ArrangeOverride
 | |
| 
 | |
|         protected override void ArrangeOverride(ChartLayoutInfo layoutInfo)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderOverride
 | |
| 
 | |
|         protected override void RenderOverride(ChartRenderInfo renderInfo)
 | |
|         {
 | |
|             Graphics g = renderInfo.Graphics;
 | |
| 
 | |
|             Rectangle scFrameBounds = GetScrollBounds(_FrameBounds);
 | |
|             Rectangle scContentBounds = GetScrollBounds(_ContentBounds);
 | |
| 
 | |
|             if (scFrameBounds.Height > 0 && scFrameBounds.Width > 0)
 | |
|             {
 | |
|                 ChartTitleVisualStyle tstyle = EffectiveTitleStyle;
 | |
| 
 | |
|                 Rectangle rfb = scFrameBounds;
 | |
|                 Rectangle rcb = scContentBounds;
 | |
| 
 | |
|                 RotateDegrees rotDegrees = GetRotateDegrees(tstyle);
 | |
| 
 | |
|                 if (rotDegrees != RotateDegrees.None)
 | |
|                 {
 | |
|                     TransformBounds(g, scFrameBounds, rotDegrees);
 | |
| 
 | |
|                     rfb = TranslateFrameBounds(scFrameBounds, rotDegrees);
 | |
|                     rcb = TranslateContentBounds(scFrameBounds, scContentBounds, rotDegrees);
 | |
|                 }
 | |
| 
 | |
|                 RenderBackground(g, rfb, tstyle);
 | |
|                 RenderTextAndFigure(g, rfb, rcb, rotDegrees, tstyle);
 | |
| 
 | |
|                 if (rotDegrees != RotateDegrees.None)
 | |
|                     g.ResetTransform();
 | |
| 
 | |
|                 tstyle.RenderBorder(g, scFrameBounds);
 | |
| 
 | |
|                 if (tstyle.DropShadow.Enabled == Tbool.True)
 | |
|                     tstyle.DropShadow.RenderDropShadow(g, scFrameBounds, true, true);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region TransformBounds
 | |
| 
 | |
|         private void TransformBounds(Graphics g, Rectangle rfb, RotateDegrees rotDegrees)
 | |
|         {
 | |
|             switch (rotDegrees)
 | |
|             {
 | |
|                 case RotateDegrees.Rotate90:
 | |
|                     g.TranslateTransform(rfb.Right, rfb.Y);
 | |
|                     g.RotateTransform(90);
 | |
|                     break;
 | |
| 
 | |
|                 case RotateDegrees.Rotate180:
 | |
|                     g.TranslateTransform(rfb.Right, rfb.Bottom);
 | |
|                     g.RotateTransform(-180);
 | |
|                     break;
 | |
| 
 | |
|                 case RotateDegrees.Rotate270:
 | |
|                     g.TranslateTransform(rfb.X, rfb.Bottom);
 | |
|                     g.RotateTransform(-90);
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region TranslateFrameBounds
 | |
| 
 | |
|         private Rectangle TranslateFrameBounds(Rectangle rfb, RotateDegrees rotDegrees)
 | |
|         {
 | |
|             Rectangle tfb = new Rectangle(0, 0, rfb.Width, rfb.Height);
 | |
| 
 | |
|             switch (rotDegrees)
 | |
|             {
 | |
|                 case RotateDegrees.Rotate90:
 | |
|                 case RotateDegrees.Rotate270:
 | |
|                     tfb.Width = rfb.Height;
 | |
|                     tfb.Height = rfb.Width;
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             return (tfb);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region TranslateContentBounds
 | |
| 
 | |
|         private Rectangle TranslateContentBounds(Rectangle rfb, Rectangle rcb, RotateDegrees rotDegrees)
 | |
|         {
 | |
|             Rectangle tcb = new Rectangle(rcb.X - rfb.X, rcb.Y - rfb.Y, rcb.Width, rcb.Height);
 | |
| 
 | |
|             switch (rotDegrees)
 | |
|             {
 | |
|                 case RotateDegrees.Rotate90:
 | |
|                     int X = tcb.X;
 | |
|                     tcb.X = tcb.Y;
 | |
|                     tcb.Y = X;
 | |
| 
 | |
|                     tcb.Width = rcb.Height;
 | |
|                     tcb.Height = rcb.Width;
 | |
|                     break;
 | |
| 
 | |
|                 case RotateDegrees.Rotate270:
 | |
|                     int X1 = tcb.X;
 | |
|                     tcb.X = tcb.Y;
 | |
|                     tcb.Y = X1;
 | |
| 
 | |
|                     tcb.Width = rcb.Height;
 | |
|                     tcb.Height = rcb.Width;
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             return (tcb);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CalcImageBounds
 | |
| 
 | |
|         private Rectangle CalcImageBounds(
 | |
|             Rectangle rfb, RotateDegrees rotDegrees, ChartTitleVisualStyle style)
 | |
|         {
 | |
|             if (style.BorderThickness.IsEmpty == false)
 | |
|             {
 | |
|                 switch (rotDegrees)
 | |
|                 {
 | |
|                     case RotateDegrees.Rotate90:
 | |
|                         rfb.X += Dpi.Height(style.BorderThickness.Top);
 | |
|                         rfb.Width -= Dpi.Height(style.BorderThickness.Vertical);
 | |
| 
 | |
|                         rfb.Y += Dpi.Width(style.BorderThickness.Right);
 | |
|                         rfb.Height -= Dpi.Width(style.BorderThickness.Horizontal);
 | |
|                         break;
 | |
| 
 | |
|                     case RotateDegrees.Rotate270:
 | |
|                         rfb.X += Dpi.Height(style.BorderThickness.Bottom);
 | |
|                         rfb.Width -= Dpi.Height(style.BorderThickness.Vertical);
 | |
| 
 | |
|                         rfb.Y += Dpi.Width(style.BorderThickness.Left);
 | |
|                         rfb.Height -= Dpi.Width(style.BorderThickness.Horizontal);
 | |
|                         break;
 | |
| 
 | |
|                     case RotateDegrees.Rotate180:
 | |
|                         rfb.X += Dpi.Width(style.BorderThickness.Right);
 | |
|                         rfb.Width -= Dpi.Width(style.BorderThickness.Horizontal);
 | |
| 
 | |
|                         rfb.Y += Dpi.Height(style.BorderThickness.Bottom);
 | |
|                         rfb.Height -= Dpi.Height(style.BorderThickness.Vertical);
 | |
|                         break;
 | |
| 
 | |
|                     default:
 | |
|                         rfb.X += Dpi.Width(style.BorderThickness.Left);
 | |
|                         rfb.Width -= Dpi.Width(style.BorderThickness.Horizontal);
 | |
| 
 | |
|                         rfb.Y += Dpi.Height(style.BorderThickness.Top);
 | |
|                         rfb.Height -= Dpi.Height(style.BorderThickness.Vertical);
 | |
|                         break;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (rfb);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderBackground
 | |
| 
 | |
|         private void RenderBackground(
 | |
|             Graphics g, Rectangle r, ChartTitleVisualStyle style)
 | |
|         {
 | |
|             if (r.Width > 2 && r.Height > 2)
 | |
|             {
 | |
|                 using (Brush br = style.Background.GetBrush(r))
 | |
|                     g.FillRectangle(br, r);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderTextAndFigure
 | |
| 
 | |
|         private void RenderTextAndFigure(Graphics g, Rectangle rfb,
 | |
|             Rectangle rcb, RotateDegrees rotDegrees, ChartTitleVisualStyle tstyle)
 | |
|         {
 | |
|             Rectangle rib = Rectangle.Empty;
 | |
| 
 | |
|             object figure = tstyle.GetFigure();
 | |
| 
 | |
|             if (figure != null)
 | |
|             {
 | |
|                 rib = CalcImageBounds(rfb, rotDegrees, tstyle);
 | |
| 
 | |
|                 if (tstyle.ImageOverlay != ImageOverlay.Top)
 | |
|                     RenderFigure(g, figure, rib, tstyle);
 | |
|             }
 | |
| 
 | |
|             RenderText(g, rcb, tstyle);
 | |
| 
 | |
|             if (figure != null)
 | |
|             {
 | |
|                 if (tstyle.ImageOverlay == ImageOverlay.Top)
 | |
|                     RenderFigure(g, figure, rib, tstyle);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderFigure
 | |
| 
 | |
|         private void RenderFigure(Graphics g,
 | |
|             object figure, Rectangle r, ChartTitleVisualStyle tstyle)
 | |
|         {
 | |
|             Rectangle t = tstyle.GetFigureBounds(g, r);
 | |
| 
 | |
|             t.Intersect(r);
 | |
| 
 | |
|             if (t.Width > 0 && t.Height > 0)
 | |
|             {
 | |
|                 SymbolDef sd = figure as SymbolDef;
 | |
| 
 | |
|                 if (sd != null && sd.IsValidSymbol == true)
 | |
|                 {
 | |
|                     using (Brush br = new SolidBrush(sd.SymbolColor))
 | |
|                         g.DrawString(sd.SymbolRealized, sd.SymbolFont, br, t);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     Image image = figure as Image;
 | |
| 
 | |
|                     if (image != null)
 | |
|                         g.DrawImage(image, t);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RenderText
 | |
| 
 | |
|         private void RenderText(
 | |
|             Graphics g, Rectangle r, ChartTitleVisualStyle style)
 | |
|         {
 | |
|             if (r.Width > 0 && r.Height > 0)
 | |
|             {
 | |
|                 string s = Text;
 | |
| 
 | |
|                 if (string.IsNullOrEmpty(s) == false)
 | |
|                 {
 | |
|                     if (TextMarkup != null)
 | |
|                     {
 | |
|                         RenderTextMarkup(g, r, style);
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         using (SolidBrush br = new SolidBrush(style.TextColor))
 | |
|                         {
 | |
|                             using (StringFormat sf = new StringFormat())
 | |
|                             {
 | |
|                                 style.GetStringFormatFlags(sf);
 | |
| 
 | |
|                                 if (style.MaxLineCount <= 1)
 | |
|                                     sf.FormatFlags |= StringFormatFlags.NoWrap;
 | |
| 
 | |
|                                 if (r.Height > _TextHeight)
 | |
|                                 {
 | |
|                                     if (sf.LineAlignment == StringAlignment.Center)
 | |
|                                     {
 | |
|                                         r.Y += (r.Height - _TextHeight) / 2;
 | |
|                                         r.Height = _TextHeight;
 | |
|                                     }
 | |
|                                 }
 | |
| 
 | |
|                                 g.DrawString(Text, style.Font, br, r, sf);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #region RenderTextMarkup
 | |
| 
 | |
|         private void RenderTextMarkup(
 | |
|             Graphics g, Rectangle r, ChartTitleVisualStyle style)
 | |
|         {
 | |
|             MarkupDrawContext d =
 | |
|                 new MarkupDrawContext(g, style.Font, style.TextColor, false);
 | |
| 
 | |
|             TextMarkup.Arrange(r, d);
 | |
| 
 | |
|             Size size = TextMarkup.Bounds.Size;
 | |
| 
 | |
|             switch (style.Alignment)
 | |
|             {
 | |
|                 case Alignment.MiddleLeft:
 | |
|                 case Alignment.MiddleCenter:
 | |
|                 case Alignment.MiddleRight:
 | |
|                     if (r.Height > size.Height)
 | |
|                         r.Y += (r.Height - size.Height) / 2;
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     if (r.Height > size.Height)
 | |
|                         r.Y = r.Bottom - size.Height;
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             TextMarkup.Bounds = new Rectangle(r.Location, size);
 | |
| 
 | |
|             Region oldClip = g.Clip;
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 g.SetClip(r, CombineMode.Intersect);
 | |
| 
 | |
|                 TextMarkup.Render(d);
 | |
|             }
 | |
|             finally
 | |
|             {
 | |
|                 g.Clip = oldClip;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetRotateDegrees
 | |
| 
 | |
|         private RotateDegrees GetRotateDegrees(ChartTitleVisualStyle style)
 | |
|         {
 | |
|             switch (RotateDegrees)
 | |
|             {
 | |
|                 case RotateDegrees.Auto:
 | |
|                 case RotateDegrees.NotSet:
 | |
| 
 | |
|                 switch (XyAlignment)
 | |
|                 {
 | |
|                     case XyAlignment.Left:
 | |
|                         return (RotateDegrees.Rotate270);
 | |
| 
 | |
|                     case XyAlignment.Right:
 | |
|                         return (RotateDegrees.Rotate90);
 | |
| 
 | |
|                     default:
 | |
|                         return (RotateDegrees.None);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             return (RotateDegrees);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Style Support
 | |
| 
 | |
|         #region ApplyStyles
 | |
| 
 | |
|         public override void ApplyStyles(BaseVisualStyle style)
 | |
|         {
 | |
|             ChartTitleVisualStyle tstyle = style as ChartTitleVisualStyle;
 | |
| 
 | |
|             if (tstyle != null)
 | |
|             {
 | |
|                 ApplyParentStyles(tstyle, Parent as ChartContainer);
 | |
| 
 | |
|                 tstyle.ApplyStyle(ChartTitleVisualStyle);
 | |
| 
 | |
|                 tstyle.ApplyDefaults();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ApplyParentStyles
 | |
| 
 | |
|         private void ApplyParentStyles(ChartTitleVisualStyle tstyle, ChartContainer item)
 | |
|         {
 | |
|             if (item != null)
 | |
|             {
 | |
|                 ApplyParentStyles(tstyle, item.Parent as ChartContainer);
 | |
| 
 | |
|                 if (item is ChartPanel)
 | |
|                     tstyle.ApplyStyle(((ChartPanel)item).DefaultVisualStyles.ChartTitleVisualStyle);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 tstyle.ApplyStyle(ChartControl.BaseVisualStyles.ChartTitleVisualStyle);
 | |
|                 tstyle.ApplyStyle(ChartControl.DefaultVisualStyles.ChartTitleVisualStyle);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region InvalidateStyle
 | |
| 
 | |
|         ///<summary>
 | |
|         ///Invalidate the cached Styles
 | |
|         ///</summary>
 | |
|         public void InvalidateStyle()
 | |
|         {
 | |
|             ClearEffectiveStyles();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ClearEffectiveStyles
 | |
| 
 | |
|         protected override void ClearEffectiveStyles()
 | |
|         {
 | |
|             base.ClearEffectiveStyles();
 | |
| 
 | |
|             _EffectiveTitleStyle.InvalidateStyle();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Copy/CopyTo
 | |
| 
 | |
|         public override ChartVisualElement Copy()
 | |
|         {
 | |
|             ChartTitle copy = new ChartTitle();
 | |
| 
 | |
|             CopyTo(copy);
 | |
| 
 | |
|             return (copy);
 | |
|         }
 | |
| 
 | |
|         public override void CopyTo(ChartVisualElement copy)
 | |
|         {
 | |
|             ChartTitle c = copy as ChartTitle;
 | |
| 
 | |
|             if (c != null)
 | |
|             {
 | |
|                 base.CopyTo(c);
 | |
| 
 | |
|                 c.ChartTitleVisualStyle = 
 | |
|                     (_ChartTitleVisualStyle != null) ? ChartTitleVisualStyle.Copy() : null;
 | |
| 
 | |
|                 c.RotateDegrees = RotateDegrees;
 | |
|                 c.XyAlignment = XyAlignment;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetSerialData
 | |
| 
 | |
|         internal override SerialElementCollection GetSerialData(string serialName)
 | |
|         {
 | |
|             SerialElementCollection sec = new SerialElementCollection();
 | |
| 
 | |
|             if (serialName != null)
 | |
|             {
 | |
|                 if (serialName.Equals("") == true)
 | |
|                     serialName = "ChartTitle";
 | |
| 
 | |
|                 sec.AddStartElement(serialName);
 | |
|             }
 | |
| 
 | |
|             if (_ChartTitleVisualStyle != null && _ChartTitleVisualStyle.IsEmpty == false)
 | |
|                 sec.AddElement(_ChartTitleVisualStyle.GetSerialData("ChartTitleVisualStyle"));
 | |
| 
 | |
|             sec.AddValue("RotateDegrees", RotateDegrees, RotateDegrees.NotSet);
 | |
|             sec.AddValue("XyAlignment", XyAlignment, XyAlignment.NotSet);
 | |
| 
 | |
|             sec.AddElement(base.GetSerialData(null));
 | |
| 
 | |
|             if (serialName != null)
 | |
|                 sec.AddEndElement(serialName);
 | |
| 
 | |
|             return (sec);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region PutSerialData
 | |
| 
 | |
|         #region ProcessValue
 | |
| 
 | |
|         internal override void ProcessValue(SerialElement se)
 | |
|         {
 | |
|             switch (se.Name)
 | |
|             {
 | |
|                 case "RotateDegrees":
 | |
|                     RotateDegrees = (RotateDegrees)se.GetValueEnum(typeof(RotateDegrees));
 | |
|                     break;
 | |
| 
 | |
|                 case "XyAlignment":
 | |
|                     XyAlignment = (XyAlignment)se.GetValueEnum(typeof(XyAlignment));
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     base.ProcessValue(se);
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ProcessCollection
 | |
| 
 | |
|         internal override void ProcessCollection(SerialElement se)
 | |
|         {
 | |
|             SerialElementCollection sec = se.Sec;
 | |
| 
 | |
|             switch (se.Name)
 | |
|             {
 | |
|                 case "ChartTitleVisualStyle":
 | |
|                     sec.PutSerialData(ChartTitleVisualStyle);
 | |
|                     break;
 | |
| 
 | |
|                 default:
 | |
|                     base.ProcessCollection(se);
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region States
 | |
| 
 | |
|         [Flags]
 | |
|         private enum States : uint
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         #region TestState
 | |
| 
 | |
|         private bool TestState(States state)
 | |
|         {
 | |
|             return ((_States & state) == state);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region SetState
 | |
| 
 | |
|         private void SetState(States state, bool value)
 | |
|         {
 | |
|             if (value == true)
 | |
|                 _States |= state;
 | |
|             else
 | |
|                 _States &= ~state;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region IDisposable
 | |
| 
 | |
|         public override void Dispose()
 | |
|         {
 | |
|             ChartTitleVisualStyle = null;
 | |
| 
 | |
|             base.Dispose();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| }
 |