536cd135cc
Former-commit-id: 5624ac747d633e885131e8349322922b6a59baaa
536 lines
14 KiB
C#
536 lines
14 KiB
C#
//-------------------------------------------------------------
|
||
// <copyright company=’Microsoft Corporation’>
|
||
// Copyright © Microsoft Corporation. All Rights Reserved.
|
||
// </copyright>
|
||
//-------------------------------------------------------------
|
||
// @owner=alexgor, deliant
|
||
//=================================================================
|
||
// File: ElementPosition.cs
|
||
//
|
||
// Namespace: System.Web.UI.WebControls[Windows.Forms].Charting
|
||
//
|
||
// Classes: ElementPosition
|
||
//
|
||
// Purpose: Class is used to store relative position of the chart
|
||
// elements like Legend, Title and others. It uses
|
||
// relative coordinate system where top left corner is
|
||
// 0,0 and bottom right is 100,100.
|
||
//
|
||
// If Auto property is set to true, all position properties
|
||
// (X,Y,Width and Height) are ignored and they automatically
|
||
// calculated during chart rendering.
|
||
//
|
||
// Note that setting any of the position properties will
|
||
// automatically set Auto property to false.
|
||
//
|
||
// Reviewed: AG - August 7, 2002
|
||
// AG - Microsoft 5, 2007
|
||
//
|
||
//===================================================================
|
||
|
||
|
||
#region Used Namespaces
|
||
|
||
using System;
|
||
using System.Collections;
|
||
using System.Collections.Specialized;
|
||
using System.ComponentModel;
|
||
using System.ComponentModel.Design;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Drawing.Design;
|
||
using System.Drawing.Drawing2D;
|
||
using System.Diagnostics.CodeAnalysis;
|
||
using System.Globalization;
|
||
|
||
#if Microsoft_CONTROL
|
||
using System.Windows.Forms.DataVisualization.Charting;
|
||
using System.Windows.Forms.DataVisualization.Charting.Data;
|
||
using System.Windows.Forms.DataVisualization.Charting.ChartTypes;
|
||
using System.Windows.Forms.DataVisualization.Charting.Utilities;
|
||
using System.Windows.Forms.DataVisualization.Charting.Borders3D;
|
||
#else
|
||
using System.Web;
|
||
using System.Web.UI;
|
||
using System.Web.UI.DataVisualization.Charting;
|
||
using System.Web.UI.DataVisualization.Charting.Data;
|
||
#endif
|
||
|
||
|
||
#endregion
|
||
|
||
#if Microsoft_CONTROL
|
||
namespace System.Windows.Forms.DataVisualization.Charting
|
||
#else
|
||
namespace System.Web.UI.DataVisualization.Charting
|
||
|
||
#endif
|
||
{
|
||
/// <summary>
|
||
/// ElementPosition is the base class for many chart visual
|
||
/// elements like Legend, Title and ChartArea. It provides
|
||
/// the position of the chart element in relative coordinates,
|
||
/// from (0,0) to (100,100).
|
||
/// </summary>
|
||
[
|
||
SRDescription("DescriptionAttributeElementPosition_ElementPosition"),
|
||
DefaultProperty("Data"),
|
||
]
|
||
#if ASPPERM_35
|
||
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
|
||
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
|
||
#endif
|
||
public class ElementPosition : ChartElement
|
||
{
|
||
#region Fields
|
||
|
||
// Private data members, which store properties values
|
||
private float _x = 0;
|
||
private float _y = 0;
|
||
private float _width = 0;
|
||
private float _height = 0;
|
||
internal bool _auto = true;
|
||
|
||
// Indicates the auto position of all areas must be reset
|
||
internal bool resetAreaAutoPosition = false;
|
||
|
||
#endregion
|
||
|
||
#region Constructors
|
||
|
||
/// <summary>
|
||
/// ElementPosition default constructor
|
||
/// </summary>
|
||
public ElementPosition()
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// ElementPosition default constructor
|
||
/// </summary>
|
||
internal ElementPosition(IChartElement parent)
|
||
: base(parent)
|
||
{
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// ElementPosition constructor.
|
||
/// </summary>
|
||
/// <param name="x">X position.</param>
|
||
/// <param name="y">Y position.</param>
|
||
/// <param name="width">Width.</param>
|
||
/// <param name="height">Height.</param>
|
||
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly",
|
||
Justification = "X and Y are cartesian coordinates and well understood")]
|
||
public ElementPosition(float x, float y, float width, float height)
|
||
{
|
||
this._auto = false;
|
||
this._x = x;
|
||
this._y = y;
|
||
this._width = width;
|
||
this._height = height;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Methods
|
||
|
||
/// <summary>
|
||
/// Asks the user at design-time if he wants to change the Auto position
|
||
/// of all areas at the same time.
|
||
/// </summary>
|
||
/// <param name="autoValue">Value to be set for the Auto property.</param>
|
||
private void ResetAllAreasAutoPosition(bool autoValue)
|
||
{
|
||
if(resetAreaAutoPosition)
|
||
{
|
||
// Proceed only if at design time
|
||
if(Chart != null && Chart.IsDesignMode() && !Chart.serializing && Chart.Site != null)
|
||
{
|
||
// Check if there is more than one area and Auto position set to the same value
|
||
if(Chart.ChartAreas.Count > 1)
|
||
{
|
||
bool firstAutoValue = Chart.ChartAreas[0].Position.Auto;
|
||
bool sameAutoValue = true;
|
||
foreach(ChartArea area in Chart.ChartAreas)
|
||
{
|
||
if(area.Position.Auto != firstAutoValue)
|
||
{
|
||
sameAutoValue = false;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Proceed only all Auto values are the same
|
||
if(sameAutoValue)
|
||
{
|
||
string message = SR.MessageChangingChartAreaPositionProperty;
|
||
if (autoValue)
|
||
{
|
||
message += SR.MessageChangingChartAreaPositionConfirmAutomatic;
|
||
}
|
||
else
|
||
{
|
||
message += SR.MessageChangingChartAreaPositionConfirmCustom;
|
||
}
|
||
|
||
|
||
IDesignerMessageBoxDialog confirm = Chart.Site.GetService(typeof(IDesignerMessageBoxDialog)) as IDesignerMessageBoxDialog;
|
||
if (confirm != null && confirm.ShowQuestion(message))
|
||
{
|
||
foreach (ChartArea area in Chart.ChartAreas)
|
||
{
|
||
if (autoValue)
|
||
{
|
||
this.SetPositionNoAuto(0f, 0f, 0f, 0f);
|
||
}
|
||
area.Position._auto = autoValue;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Convert element position into RectangleF
|
||
/// </summary>
|
||
/// <returns>RectangleF structure.</returns>
|
||
public RectangleF ToRectangleF()
|
||
{
|
||
return new RectangleF(_x, _y, _width, _height);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Initializes ElementPosition from RectangleF
|
||
/// </summary>
|
||
/// <param name="rect">RectangleF structure.</param>
|
||
public void FromRectangleF(RectangleF rect)
|
||
{
|
||
if (rect == null)
|
||
throw new ArgumentNullException("rect");
|
||
|
||
this._x = rect.X;
|
||
this._y = rect.Y;
|
||
this._width = rect.Width;
|
||
this._height = rect.Height;
|
||
this._auto = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets the size of the ElementPosition object.
|
||
/// </summary>
|
||
/// <returns>The size of the ElementPosition object.</returns>
|
||
[Browsable(false)]
|
||
[Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)]
|
||
public SizeF Size
|
||
{
|
||
get { return new SizeF(this._width, this._height); }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets the bottom position in relative coordinates.
|
||
/// </summary>
|
||
/// <returns>Bottom position.</returns>
|
||
[Browsable(false)]
|
||
[Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)]
|
||
public float Bottom
|
||
{
|
||
get { return this._y + this._height; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets the right position in relative coordinates.
|
||
/// </summary>
|
||
/// <returns>Right position.</returns>
|
||
[Browsable(false)]
|
||
[Utilities.SerializationVisibility(Utilities.SerializationVisibility.Hidden)]
|
||
public float Right
|
||
{
|
||
get{ return this._x + this._width; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// Determines whether the specified Object is equal to the current Object.
|
||
/// </summary>
|
||
/// <param name="obj">The Object to compare with the current Object.</param>
|
||
/// <returns>true if the specified Object is equal to the current Object; otherwise, false.</returns>
|
||
internal override bool EqualsInternal(object obj)
|
||
{
|
||
ElementPosition pos = obj as ElementPosition;
|
||
if(pos != null)
|
||
{
|
||
if(this._auto == true && this._auto == pos._auto)
|
||
{
|
||
return true;
|
||
}
|
||
else if(this._x == pos._x && this._y == pos._y &&
|
||
this._width == pos._width && this._height == pos._height)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Returns a string that represents the element position data.
|
||
/// </summary>
|
||
/// <returns>Element position data as a string.</returns>
|
||
internal override string ToStringInternal()
|
||
{
|
||
string posString = Constants.AutoValue;
|
||
if(!this._auto)
|
||
{
|
||
posString =
|
||
this._x.ToString(System.Globalization.CultureInfo.CurrentCulture)+", "+
|
||
this._y.ToString(System.Globalization.CultureInfo.CurrentCulture)+", "+
|
||
this._width.ToString(System.Globalization.CultureInfo.CurrentCulture)+", "+
|
||
this._height.ToString(System.Globalization.CultureInfo.CurrentCulture);
|
||
}
|
||
return posString;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Set the element position without modifying the "Auto" property
|
||
/// </summary>
|
||
/// <param name="x">X position.</param>
|
||
/// <param name="y">Y position.</param>
|
||
/// <param name="width">Width.</param>
|
||
/// <param name="height">Height.</param>
|
||
internal void SetPositionNoAuto(float x, float y, float width, float height)
|
||
{
|
||
bool oldValue = this._auto;
|
||
this._x = x;
|
||
this._y = y;
|
||
this._width = width;
|
||
this._height = height;
|
||
this._auto = oldValue;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Element Position properties
|
||
|
||
/// <summary>
|
||
/// X position of element.
|
||
/// </summary>
|
||
[
|
||
SRCategory("CategoryAttributeMisc"),
|
||
Bindable(true),
|
||
DefaultValue(0.0F),
|
||
SRDescription("DescriptionAttributeElementPosition_X"),
|
||
NotifyParentPropertyAttribute(true),
|
||
RefreshPropertiesAttribute(RefreshProperties.All),
|
||
#if !Microsoft_CONTROL
|
||
PersistenceMode(PersistenceMode.Attribute)
|
||
#endif
|
||
]
|
||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "X")]
|
||
public float X
|
||
{
|
||
get
|
||
{
|
||
return _x;
|
||
}
|
||
set
|
||
{
|
||
if(value < 0.0 || value > 100.0)
|
||
{
|
||
throw(new ArgumentOutOfRangeException("value", SR.ExceptionElementPositionArgumentOutOfRange));
|
||
}
|
||
_x = value;
|
||
Auto = false;
|
||
|
||
// Adjust width
|
||
if( (_x + Width) > 100)
|
||
{
|
||
Width = 100 - _x;
|
||
}
|
||
|
||
this.Invalidate();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Y position of element.
|
||
/// </summary>
|
||
[
|
||
SRCategory("CategoryAttributeMisc"),
|
||
Bindable(true),
|
||
DefaultValue(0.0F),
|
||
SRDescription("DescriptionAttributeElementPosition_Y"),
|
||
NotifyParentPropertyAttribute(true),
|
||
RefreshPropertiesAttribute(RefreshProperties.All),
|
||
#if !Microsoft_CONTROL
|
||
PersistenceMode(PersistenceMode.Attribute)
|
||
#endif
|
||
]
|
||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Y")]
|
||
public float Y
|
||
{
|
||
get
|
||
{
|
||
return _y;
|
||
}
|
||
set
|
||
{
|
||
if(value < 0.0 || value > 100.0)
|
||
{
|
||
throw(new ArgumentOutOfRangeException("value", SR.ExceptionElementPositionArgumentOutOfRange));
|
||
}
|
||
_y = value;
|
||
Auto = false;
|
||
|
||
// Adjust heigth
|
||
if( (_y + Height) > 100)
|
||
{
|
||
Height = 100 - _y;
|
||
}
|
||
|
||
this.Invalidate();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Width of element.
|
||
/// </summary>
|
||
[
|
||
SRCategory("CategoryAttributeMisc"),
|
||
Bindable(true),
|
||
DefaultValue(0.0F),
|
||
SRDescription("DescriptionAttributeElementPosition_Width"),
|
||
NotifyParentPropertyAttribute(true),
|
||
RefreshPropertiesAttribute(RefreshProperties.All),
|
||
#if !Microsoft_CONTROL
|
||
PersistenceMode(PersistenceMode.Attribute)
|
||
#endif
|
||
]
|
||
public float Width
|
||
{
|
||
get
|
||
{
|
||
return _width;
|
||
}
|
||
set
|
||
{
|
||
if(value < 0.0 || value > 100.0)
|
||
{
|
||
throw(new ArgumentOutOfRangeException("value", SR.ExceptionElementPositionArgumentOutOfRange));
|
||
}
|
||
_width = value;
|
||
Auto = false;
|
||
|
||
// Adjust x
|
||
if( (_x + Width) > 100)
|
||
{
|
||
_x = 100 - Width;
|
||
}
|
||
|
||
this.Invalidate();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Height of element.
|
||
/// </summary>
|
||
[
|
||
SRCategory("CategoryAttributeMisc"),
|
||
Bindable(true),
|
||
DefaultValue(0.0F),
|
||
SRDescription("DescriptionAttributeElementPosition_Height"),
|
||
NotifyParentPropertyAttribute(true),
|
||
RefreshPropertiesAttribute(RefreshProperties.All),
|
||
#if !Microsoft_CONTROL
|
||
PersistenceMode(PersistenceMode.Attribute)
|
||
#endif
|
||
]
|
||
public float Height
|
||
{
|
||
get
|
||
{
|
||
return _height;
|
||
}
|
||
set
|
||
{
|
||
if(value < 0.0 || value > 100.0)
|
||
{
|
||
throw(new ArgumentOutOfRangeException("value", SR.ExceptionElementPositionArgumentOutOfRange));
|
||
}
|
||
_height = value;
|
||
Auto = false;
|
||
|
||
// Adjust y
|
||
if( (_y + Height) > 100)
|
||
{
|
||
_y = 100 - Height;
|
||
|
||
}
|
||
|
||
this.Invalidate();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Gets or sets a flag which indicates whether positioning is on.
|
||
/// </summary>
|
||
[
|
||
SRCategory("CategoryAttributeMisc"),
|
||
Bindable(true),
|
||
DefaultValue(true),
|
||
SRDescription("DescriptionAttributeElementPosition_Auto"),
|
||
NotifyParentPropertyAttribute(true),
|
||
RefreshPropertiesAttribute(RefreshProperties.All),
|
||
#if !Microsoft_CONTROL
|
||
PersistenceMode(PersistenceMode.Attribute)
|
||
#endif
|
||
]
|
||
public bool Auto
|
||
{
|
||
get
|
||
{
|
||
return _auto;
|
||
}
|
||
set
|
||
{
|
||
if(value != _auto)
|
||
{
|
||
ResetAllAreasAutoPosition(value);
|
||
|
||
if(value)
|
||
{
|
||
this._x = 0;
|
||
this._y = 0;
|
||
this._width = 0;
|
||
this._height = 0;
|
||
}
|
||
_auto = value;
|
||
|
||
this.Invalidate();
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
|
||
/// <summary>
|
||
/// Used for invoking windows forms MesageBox dialog.
|
||
/// </summary>
|
||
internal interface IDesignerMessageBoxDialog
|
||
{
|
||
/// <summary>
|
||
/// Shows Yes/No MessageBox.
|
||
/// </summary>
|
||
/// <param name="message">The message.</param>
|
||
/// <returns>
|
||
/// true if user confirms with Yes
|
||
/// </returns>
|
||
bool ShowQuestion(string message);
|
||
}
|
||
}
|