766 lines
20 KiB
C#

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Charts.Style
{
/// <summary>
/// Represents the visual style of a PointMarker
/// </summary>
[ToolboxItem(false), DesignTimeVisible(false)]
[TypeConverter(typeof(VisualStylesConverter))]
public class PointMarkerVisualStyle : BaseVisualStyle
{
#region Private variables
private PointMarkerType _Type = PointMarkerType.NotSet;
private Background _Background;
private Color _BorderColor = Color.Empty;
private Size _Size = Size.Empty;
private int _BorderWidth = -1;
private int _PointCount;
private int _Rotation = -1;
private Image _Image;
private int _ImageIndex = -1;
private ImageList _ImageList;
private Image _MarkerImage;
#endregion
#region Public properties
#region Background
/// <summary>
/// Gets or sets the Marker background for series points.
/// </summary>
[Description("Indicates the Marker background for series points")]
public Background Background
{
get
{
if (_Background == null)
{
_Background = Background.Empty;
UpdateChangeHandler(null, _Background);
}
return (_Background);
}
set
{
if (_Background != value)
{
UpdateChangeHandler(_Background, value);
_Background = value;
OnPropertyChangedEx("Background", VisualChangeType.Render);
}
}
}
/// <summary>
/// Gets whether property should be serialized.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
private bool ShouldSerializeBackground()
{
return (_Background != null && _Background.IsEmpty == false);
}
/// <summary>
/// Resets property to its default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
private void ResetBackground()
{
Background = null;
}
#endregion
#region BorderColor
/// <summary>
/// Gets or sets the Marker border color for series points.
/// </summary>
[Description("Indicates the point Marker Border Color for series points")]
public Color BorderColor
{
get { return (_BorderColor); }
set
{
if (_BorderColor != value)
{
_BorderColor = value;
OnPropertyChangedEx("BorderColor", VisualChangeType.Render);
}
}
}
/// <summary>
/// Gets whether property should be serialized.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
private bool ShouldSerializeBorderColor()
{
return (_BorderColor.IsEmpty == false);
}
/// <summary>
/// Resets property to its default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
private void ResetBorderColor()
{
BorderColor = Color.Empty;
}
#endregion
#region BorderWidth
/// <summary>
/// Gets or sets the Marker border width for series points.
/// </summary>
[DefaultValue(-1)]
[Description("Indicates the point Marker Border width for series points")]
public int BorderWidth
{
get { return (_BorderWidth); }
set
{
if (_BorderWidth != value)
{
_BorderWidth = value;
OnPropertyChangedEx("BorderWidth", VisualChangeType.Render);
}
}
}
#endregion
#region Image
/// <summary>
/// Gets or sets the PointMarker Image
/// </summary>
[DefaultValue(null), Category("Appearance")]
[Description("Indicates the PointMarker image")]
public Image Image
{
get { return (_Image); }
set
{
if (_Image != value)
{
_Image = value;
FreeMarkerImage();
OnPropertyChangedEx("Image", VisualChangeType.Layout);
}
}
}
#endregion
#region ImageIndex
/// <summary>
/// Gets or sets the PointMarker image index
/// </summary>
[DefaultValue(-1)]
[Category("Appearance"), Description("Indicates the image index")]
[Editor("DevComponents.SuperGrid.Design.ImageIndexEditor, DevComponents.SuperGrid.Design, Version=14.1.0.37, Culture=neutral, PublicKeyToken=90f470f34c89ccaf", typeof(UITypeEditor))]
[TypeConverter(typeof(ImageIndexConverter))]
public int ImageIndex
{
get { return (_ImageIndex); }
set
{
if (_ImageIndex != value)
{
_ImageIndex = value;
FreeMarkerImage();
OnPropertyChangedEx("ImageIndex", VisualChangeType.Layout);
}
}
}
#endregion
#region ImageList
/// <summary>
/// Gets or sets the ImageList.
/// </summary>
[Browsable(true), Category("Appearance"), DefaultValue(null)]
[Description("Indicates the ImageList.")]
public ImageList ImageList
{
get { return (_ImageList); }
set
{
if (_ImageList != value)
{
_ImageList = value;
FreeMarkerImage();
OnPropertyChangedEx("ImageList", VisualChangeType.Layout);
}
}
}
#endregion
#region PointCount
/// <summary>
/// Gets or sets the number of points for series markers (3 = triangle, 4 square, etc).
/// </summary>
[DefaultValue(0)]
[Description("Indicates the number of points for series markers (3 = triangle, 4 square, etc).")]
public int PointCount
{
get { return (_PointCount); }
set
{
if (_PointCount != value)
{
if (value < 0)
throw new Exception("PointMarkerPoints must be >= 0");
_PointCount = value;
OnPropertyChangedEx("PointCount", VisualChangeType.Render);
}
}
}
#endregion
#region Rotation
/// <summary>
/// Gets or sets the Marker rotation angle for series points.
/// </summary>
[Description("Indicates the Marker rotation angle for series points.")]
[DefaultValue(-1)]
public int Rotation
{
get { return (_Rotation); }
set
{
if (_Rotation != value)
{
_Rotation = value;
OnPropertyChangedEx("Rotation", VisualChangeType.Render);
}
}
}
#endregion
#region Size
/// <summary>
/// Gets or sets the Marker size for series points
/// </summary>
[Description("Indicates the Marker size for series points.")]
public Size Size
{
get { return (_Size); }
set
{
if (_Size != value)
{
_Size = value;
OnPropertyChangedEx("Size", VisualChangeType.Render);
}
}
}
/// <summary>
/// Gets whether property should be serialized.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
private bool ShouldSerializeSize()
{
return (Size.IsEmpty == false);
}
/// <summary>
/// Resets property to its default value.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
private void ResetSize()
{
Size = Size.Empty;
}
#endregion
#region Type
/// <summary>
/// Gets or sets the Marker type.
/// </summary>
[Description("Indicates the Marker type.")]
[DefaultValue(PointMarkerType.NotSet)]
public PointMarkerType Type
{
get { return (_Type); }
set
{
if (_Type != value)
{
_Type = value;
OnPropertyChangedEx("Type", VisualChangeType.Render);
}
}
}
#endregion
#region IsEmpty
/// <summary>
/// Gets whether the style is logically Empty.
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Description("Gets whether the style is logically Empty.")]
public override bool IsEmpty
{
get
{
return ((_Background == null || _Background.IsEmpty == true) &&
(_BorderColor == null || _BorderColor.IsEmpty == true) &&
(_BorderWidth == -1) &&
(_Image == null) &&
(_ImageIndex == -1) &&
(_ImageList == null) &&
(_PointCount <= 0) &&
(_Rotation == -1) &&
(_Size.IsEmpty == true) &&
(_Type == PointMarkerType.NotSet) &&
(base.IsEmpty == true));
}
}
#endregion
#endregion
#region GetPointMarkerImage
internal Image GetPointMarkerImage()
{
if (_MarkerImage != null)
return (_MarkerImage);
_MarkerImage = GetPointMarkerImageEx();
if (_MarkerImage != null)
{
if (Dpi.UseFactor == true)
{
Size size = _MarkerImage.Size;
size.Width *= Dpi.Width1;
size.Height *= Dpi.Width1;
_MarkerImage = new Bitmap(_MarkerImage, size);
}
}
return (_MarkerImage);
}
#region GetPointMarkerImageEx
private Image GetPointMarkerImageEx()
{
if (_Image != null)
return (_Image);
if (_ImageIndex >= 0)
{
ImageList imageList = ImageList;
if (imageList != null && _ImageIndex < imageList.Images.Count)
return (imageList.Images[_ImageIndex]);
}
return (null);
}
#endregion
#endregion
#region FreeMarkerImage
private void FreeMarkerImage()
{
if (_MarkerImage != null)
{
_MarkerImage.Dispose();
_MarkerImage = null;
}
}
#endregion
#region RenderMarker
internal void RenderMarker(
Graphics g, PointMarker pointMarker, Rectangle bounds, Color color)
{
Image marker = GetPointMarkerImage();
if (marker != null)
{
g.DrawImage(marker, bounds);
}
else
{
if (Type != PointMarkerType.NotSet && Type != PointMarkerType.None)
{
if (Background.IsEmpty == true)
{
using (Background back = new Background(color))
{
marker = pointMarker.GetMarkerBitmap(g, Type, PointCount,
bounds.Size, Rotation, back, BorderColor, BorderWidth);
}
}
else
{
marker = pointMarker.GetMarkerBitmap(g, Type, PointCount,
bounds.Size, Rotation, Background, BorderColor, BorderWidth);
}
}
if (marker != null)
{
// Make allowances for the fact that GetPointMarker() adjusts the
// size and pos of the image to allow for better anti-aliasing
bounds.X--;
bounds.Y--;
g.DrawImageUnscaled(marker, bounds);
}
else
{
RenderDefaultMarker(g, bounds, color);
}
}
}
#region RenderDefaultMarker
private void RenderDefaultMarker(Graphics g, Rectangle bounds, Color color)
{
bounds.Width++;
bounds.Height++;
Background background = Background;
if (background.IsEmpty == true)
{
if (color.IsEmpty == true)
color = Color.DimGray;
using (Brush br = new SolidBrush(color))
g.FillRectangle(br, bounds);
}
else
{
using (Brush br = background.GetBrush(bounds))
g.FillRectangle(br, bounds);
}
if (BorderColor.IsEmpty == false && BorderWidth > 0)
{
using (Pen pen = new Pen(BorderColor, BorderWidth))
{
pen.Alignment = System.Drawing.Drawing2D.PenAlignment.Inset;
g.DrawRectangle(pen, bounds);
}
}
}
#endregion
#endregion
#region ApplyStyle
/// <summary>
/// Applies the style to instance of this style.
/// </summary>
/// <param name="style">Style to apply.</param>
public void ApplyStyle(PointMarkerVisualStyle style)
{
if (style != null)
{
base.ApplyStyle(style);
if (style._Background != null && style._Background.IsEmpty == false)
Background = style._Background.Copy();
if (style.BorderColor.IsEmpty == false)
BorderColor = style.BorderColor;
if (style.BorderWidth >= 0)
BorderWidth = style.BorderWidth;
if (style.Image != null)
Image = style.Image;
if (style.ImageIndex >= 0)
ImageIndex = style.ImageIndex;
if (style._ImageList != null)
ImageList = style._ImageList;
if (style.PointCount > 0)
PointCount = style.PointCount;
if (style.Rotation != -1)
Rotation = style.Rotation;
if (style.Size.IsEmpty == false)
Size = style.Size;
if (style.Type != PointMarkerType.NotSet)
Type = style.Type;
}
}
#endregion
#region ApplyDefaults
public override void ApplyDefaults()
{
if (PointCount <= 0)
PointCount = 5;
if (Size.IsEmpty)
Size = new Size(5, 5);
if (BorderWidth == -1)
BorderWidth = 1;
base.ApplyDefaults();
}
#endregion
#region Copy
/// <summary>
/// Returns the copy of the style.
/// </summary>
/// <returns>Copy of the style.</returns>
public new PointMarkerVisualStyle Copy()
{
PointMarkerVisualStyle style = new PointMarkerVisualStyle();
CopyTo(style);
return (style);
}
#endregion
#region CopyTo
/// <summary>
/// Returns the copy of the style.
/// </summary>
/// <returns>Copy of the style.</returns>
public void CopyTo(PointMarkerVisualStyle style)
{
base.CopyTo(style);
style.Background = (_Background != null) ? _Background.Copy() : null;
style.BorderColor = _BorderColor;
style.BorderWidth = _BorderWidth;
style.Image = _Image;
style.ImageIndex = _ImageIndex;
style.ImageList = _ImageList;
style.PointCount = _PointCount;
style.Rotation = _Rotation;
style.Size = _Size;
style.Type = _Type;
}
#endregion
#region GetSerialData
internal override SerialElementCollection GetSerialData(string serialName)
{
SerialElementCollection sec = new SerialElementCollection();
if (serialName != null)
{
if (serialName.Equals("") == true)
serialName = "PointMarkerVisualStyle";
sec.AddStartElement(serialName);
}
if (_Background != null && _Background.IsEmpty == false)
sec.AddElement(_Background.GetSerialData("Background"));
sec.AddValue("BorderColor", _BorderColor, Color.Empty);
sec.AddValue("BorderWidth", _BorderWidth, -1);
sec.AddValue("Image", Image);
sec.AddValue("ImageIndex", _ImageIndex, -1);
if (_ImageList != null)
sec.AddValue("ImageList", XmlSerializableImageList.ConvertToString(ImageList));
sec.AddValue("PointCount", _PointCount, 0);
sec.AddValue("Rotation", _Rotation, -1);
sec.AddValue("Size", _Size, Size.Empty);
sec.AddValue("Type", _Type, PointMarkerType.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 "BorderColor":
BorderColor = se.GetValueColor();
break;
case "BorderWidth":
BorderWidth = int.Parse(se.StringValue);
break;
case "Image":
Image = se.GetValueImage();
break;
case "ImageIndex":
ImageIndex = int.Parse(se.StringValue);
break;
case "ImageList":
ImageList = XmlSerializableImageList.ConvertFromString(se.StringValue);
break;
case "PointCount":
PointCount = int.Parse(se.StringValue);
break;
case "Rotation":
Rotation = int.Parse(se.StringValue);
break;
case "Size":
Size = se.GetValueSize();
break;
case "Type":
Type = (PointMarkerType)se.GetValueEnum(typeof(PointMarkerType));
break;
default:
base.ProcessValue(se);
break;
}
}
#endregion
#region ProcessCollection
internal override void ProcessCollection(SerialElement se)
{
SerialElementCollection sec = se.Sec;
switch (se.Name)
{
case "Background":
sec.PutSerialData(Background);
break;
default:
base.ProcessCollection(se);
break;
}
}
#endregion
#endregion
#region IDisposable
/// <summary>
/// Dispose
/// </summary>
public override void Dispose()
{
Background = null;
base.Dispose();
}
#endregion
}
}