using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.Windows.Forms; namespace DevComponents.DotNetBar.Charts.Style { /// /// Represents the visual style of a PointMarker /// [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 /// /// Gets or sets the Marker background for series points. /// [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); } } } /// /// Gets whether property should be serialized. /// [EditorBrowsable(EditorBrowsableState.Never)] private bool ShouldSerializeBackground() { return (_Background != null && _Background.IsEmpty == false); } /// /// Resets property to its default value. /// [EditorBrowsable(EditorBrowsableState.Never)] private void ResetBackground() { Background = null; } #endregion #region BorderColor /// /// Gets or sets the Marker border color for series points. /// [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); } } } /// /// Gets whether property should be serialized. /// [EditorBrowsable(EditorBrowsableState.Never)] private bool ShouldSerializeBorderColor() { return (_BorderColor.IsEmpty == false); } /// /// Resets property to its default value. /// [EditorBrowsable(EditorBrowsableState.Never)] private void ResetBorderColor() { BorderColor = Color.Empty; } #endregion #region BorderWidth /// /// Gets or sets the Marker border width for series points. /// [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 /// /// Gets or sets the PointMarker Image /// [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 /// /// Gets or sets the PointMarker image index /// [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 /// /// Gets or sets the ImageList. /// [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 /// /// Gets or sets the number of points for series markers (3 = triangle, 4 square, etc). /// [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 /// /// Gets or sets the Marker rotation angle for series points. /// [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 /// /// Gets or sets the Marker size for series points /// [Description("Indicates the Marker size for series points.")] public Size Size { get { return (_Size); } set { if (_Size != value) { _Size = value; OnPropertyChangedEx("Size", VisualChangeType.Render); } } } /// /// Gets whether property should be serialized. /// [EditorBrowsable(EditorBrowsableState.Never)] private bool ShouldSerializeSize() { return (Size.IsEmpty == false); } /// /// Resets property to its default value. /// [EditorBrowsable(EditorBrowsableState.Never)] private void ResetSize() { Size = Size.Empty; } #endregion #region Type /// /// Gets or sets the Marker type. /// [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 /// /// Gets whether the style is logically Empty. /// [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 /// /// Applies the style to instance of this style. /// /// Style to apply. 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 /// /// Returns the copy of the style. /// /// Copy of the style. public new PointMarkerVisualStyle Copy() { PointMarkerVisualStyle style = new PointMarkerVisualStyle(); CopyTo(style); return (style); } #endregion #region CopyTo /// /// Returns the copy of the style. /// /// Copy of the style. 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 /// /// Dispose /// public override void Dispose() { Background = null; base.Dispose(); } #endregion } }