OK, but it is so BIG
This is my main class of shape, I hope it's not very complicated to learn
using System;<br />
using System.Collections.Generic;<br />
using System.Text;<br />
using System.Drawing;<br />
using System.Drawing.Drawing2D;<br />
using System.Windows.Forms;<br />
using EZDesignerCore.ShapeAttribute;<br />
using EZDesignerCore.ShapeApperance;<br />
using Utils.GraphicsUtils;<br />
<br />
namespace EZDesignerCore.Shape<br />
{<br />
public abstract class AbstractShape : ICloneable, IDisposable<br />
{<br />
#region properties<br />
<br />
protected string _name;<br />
public string Name<br />
{<br />
get { return _name; }<br />
set { _name = value; }<br />
}<br />
<br />
protected string _text;<br />
public string Text<br />
{<br />
get { return _text; }<br />
set { _text = value; }<br />
}<br />
<br />
protected RectangleF _border;<br />
public RectangleF Border<br />
{<br />
get { return _border; }<br />
}<br />
<br />
public virtual PointF Location<br />
{<br />
get { return _border.Location; }<br />
set { _border.Location = value; }<br />
}<br />
<br />
public virtual SizeF Size<br />
{<br />
get { return _border.Size; }<br />
set { _border.Size = value; }<br />
}<br />
<br />
protected Spot _spot;<br />
public Spot Spot<br />
{<br />
get { return _spot; }<br />
}<br />
<br />
protected Apperance _apprerance;<br />
public Apperance Apprerance<br />
{<br />
get { return _apprerance; }<br />
}<br />
<br />
protected Restriction _restriction;<br />
public Restriction Restriction<br />
{<br />
get { return _restriction; }<br />
}<br />
<br />
protected State _state;<br />
internal State State<br />
{<br />
get { return _state; }<br />
set { _state = value; }<br />
}<br />
<br />
protected float _rotateDegree;<br />
public float RotateDegree<br />
{<br />
get { return _rotateDegree; }<br />
set { _rotateDegree = value; }<br />
}<br />
<br />
protected TextBox _editTextBox;<br />
public TextBox EditTextBox<br />
{<br />
get { return _editTextBox; }<br />
}<br />
<br />
#endregion<br />
<br />
PointF _startPoint = PointF.Empty;<br />
Control _control = null;<br />
Graphics _graphics = null;<br />
<br />
GraphicsPath _path;<br />
GraphicsPath _oldPath = null;<br />
protected float[] _childShapeRotateDegrees;<br />
<br />
#region constructor<br />
<br />
public AbstractShape()<br />
{<br />
_spot = new Spot();<br />
_apprerance = new Apperance();<br />
_state = new State();<br />
_restriction = new Restriction();<br />
_border = new Rectangle(0, 0, 10, 10);<br />
_name = "Object";<br />
_path = new GraphicsPath();<br />
}<br />
<br />
public abstract AbstractShape CreateInstance();<br />
<br />
#endregion<br />
<br />
public abstract GraphicsPath CreatePath(PointF startPoint, PointF endPoint);<br />
<br />
#region draw<br />
<br />
public void Draw(Graphics g)<br />
{<br />
Matrix oldMatrix = g.Transform;<br />
if (_rotateDegree != 0)<br />
{<br />
using (Matrix matrix = new Matrix())<br />
{<br />
matrix.RotateAt(_rotateDegree, _spot.RotatePoint);<br />
g.MultiplyTransform(matrix);<br />
}<br />
}<br />
<br />
DrawDetail(g);<br />
<br />
if (_rotateDegree != 0)<br />
{<br />
g.Transform = oldMatrix;<br />
}<br />
}<br />
<br />
protected abstract void DrawDetail(Graphics g);<br />
<br />
#endregion<br />
<br />
#region create shape<br />
<br />
public void EnterCreateMode(PointF point, Control control, Graphics graphics)<br />
{<br />
_control = control;<br />
_graphics = graphics;<br />
_startPoint = point;<br />
_state |= State.Creating;<br />
_control.MouseMove += new MouseEventHandler(EnterCreateMode_MouseMove);<br />
}<br />
<br />
void EnterCreateMode_MouseMove(object sender, MouseEventArgs e)<br />
{<br />
if (e.Button != MouseButtons.Left)<br />
return;<br />
<br />
DrawCreatingObject(_startPoint, e.Location, _graphics);<br />
}<br />
<br />
protected void DrawCreatingObject(PointF startPoint, PointF endPoint, Graphics g)<br />
{<br />
if (_oldPath != null)<br />
Rubberband.DrawXORPath(g, _oldPath, _childShapeRotateDegrees);<br />
<br />
if (_path != null)<br />
_path.Dispose();<br />
_path = CreatePath(startPoint, endPoint);<br />
Rubberband.DrawXORPath(g, _path, _childShapeRotateDegrees);<br />
_oldPath = _path;<br />
}<br />
<br />
public virtual void Create(PointF startPoint, PointF endPoint)<br />
{<br />
_border = Functions.StandardlizeRect(startPoint, endPoint);<br />
float width = Math.Max(5, _border.Size.Width);<br />
float height = Math.Max(5, _border.Size.Height);<br />
_border.Size = new SizeF(width, height);<br />
_spot.CalculateSpots(_border, _rotateDegree);<br />
}<br />
<br />
protected void LeaveCreatingMode(PointF point)<br />
{<br />
Create(_startPoint, point);<br />
GCPath();<br />
_state &= ~State.Creating;<br />
_control.MouseMove -= new MouseEventHandler(EnterCreateMode_MouseMove);<br />
}<br />
<br />
#endregion<br />
<br />
#region move<br />
<br />
public void EnterMovingMode(PointF point, Control control, Graphics graphics)<br />
{<br />
_control = control;<br />
_graphics = graphics;<br />
_startPoint = point;<br />
_state |= State.Moving;<br />
_control.MouseMove += new MouseEventHandler(EnterMovingMode_MouseMove);<br />
}<br />
<br />
void EnterMovingMode_MouseMove(object sender, MouseEventArgs e)<br />
{<br />
if (e.Button != MouseButtons.Left)<br />
return;<br />
<br />
DrawMovingObject(_startPoint, e.Location, _graphics);<br />
}<br />
<br />
PointF _oldMovingEndPoint;<br />
public void DrawMovingObject(PointF startPoint, PointF endPoint, Graphics g)<br />
{<br />
if (_oldPath != null)<br />
Rubberband.DrawXORPath(g, _oldPath, SizeF.Empty, PointF.Empty, new SizeF(_oldMovingEndPoint.X - startPoint.X, _oldMovingEndPoint.Y - startPoint.Y), _rotateDegree, _spot.RotatePoint, _childShapeRotateDegrees);<br />
<br />
if (_path != null)<br />
_path.Dispose();<br />
_path = CreatePath(_border.Location, new PointF(_border.Right, _border.Bottom));<br />
Rubberband.DrawXORPath(g, _path, SizeF.Empty, PointF.Empty, new SizeF(endPoint.X - startPoint.X, endPoint.Y - startPoint.Y), _rotateDegree, _spot.RotatePoint, _childShapeRotateDegrees);<br />
<br />
_oldPath = _path;<br />
_oldMovingEndPoint = endPoint;<br />
}<br />
<br />
public virtual void Move(float offsetX, float offsetY)<br />
{<br />
PointF[] pts = Functions.GetPointsFromRect(_border);<br />
using (Matrix matrix = new Matrix())<br />
{<br />
matrix.Translate(offsetX, offsetY);<br />
matrix.TransformPoints(pts);<br />
}<br />
<br />
_border = Functions.GetRectFromPoints(pts);<br />
_spot.CalculateSpots(_border, _rotateDegree);<br />
}<br />
<br />
protected void LeaveMovingMode(PointF point)<br />
{<br />
Move(point.X - _startPoint.X, point.Y - _startPoint.Y);<br />
GCPath();<br />
_state &= ~State.Moving;<br />
_control.MouseMove -= new MouseEventHandler(EnterMovingMode_MouseMove);<br />
}<br />
<br />
#endregion<br />
<br />
#region resize<br />
<br />
SpotLocation _spotLocation;<br />
public void EnterResizeMode(SpotLocation location, Control control, PointF point, Graphics graphics)<br />
{<br />
_control = control;<br />
_graphics = graphics;<br />
_startPoint = point;<br />
_spotLocation = location;<br />
_state |= State.Resizing;<br />
_control.MouseMove += new MouseEventHandler(EnterResizingMode_MouseMove);<br />
}<br />
<br />
void EnterResizingMode_MouseMove(object sender, MouseEventArgs e)<br />
{<br />
if (e.Button != MouseButtons.Left)<br />
return;<br />
<br />
DrawResizingObject(_spotLocation, _startPoint, e.Location, _graphics);<br />
}<br />
<br />
SizeF _oldScaleSize;<br />
protected void DrawResizingObject(SpotLocation location, PointF startPoint, PointF endPoint, Graphics g)<br />
{<br />
PointF scaleRootPoint;<br />
SizeF scaleSize;<br />
CalculateScaleInfo(location, startPoint, endPoint, out scaleRootPoint, out scaleSize);<br />
<br />
if (_oldPath != null)<br />
Rubberband.DrawXORPath(g, _path, _oldScaleSize, scaleRootPoint, SizeF.Empty, _rotateDegree, _spot.RotatePoint, _childShapeRotateDegrees);<br />
<br />
if (_path != null)<br />
_path.Dispose();<br />
_path = CreatePath(_border.Location, new PointF(_border.Right, _border.Bottom));<br />
Rubberband.DrawXORPath(g, _path, scaleSize, scaleRootPoint, SizeF.Empty, _rotateDegree, _spot.RotatePoint, _childShapeRotateDegrees);<br />
<br />
_oldPath = _path;<br />
_oldScaleSize = scaleSize;<br />
}<br />
<br />
protected void CalculateScaleInfo(SpotLocation location, PointF startPoint, PointF endPoint, out PointF scaleRootPoint, out SizeF scaleSize)<br />
{<br />
scaleRootPoint = PointF.Empty;<br />
scaleSize = SizeF.Empty;<br />
<br />
_spot.CalculateSpots(_border, 0);<br />
<br />
if (_rotateDegree != 0)<br />
{<br />
using (Matrix matrix = new Matrix())<br />
{<br />
matrix.RotateAt(-_rotateDegree, startPoint);<br />
PointF[] pts = new PointF[] { endPoint };<br />
matrix.TransformPoints(pts);<br />
endPoint = pts[0];<br />
}<br />
}<br />
<br />
float distanceX = startPoint.X - endPoint.X;<br />
float distanceY = startPoint.Y - endPoint.Y;<br />
<br />
float width = _border.Width;<br />
float height = _border.Height;<br />
<br />
switch (location)<br />
{<br />
case SpotLocation.Left:<br />
scaleRootPoint = _spot.Right;<br />
scaleSize = new SizeF((float)(width + distanceX) / width, 1);<br />
break;<br />
<br />
case SpotLocation.TopLeft:<br />
scaleRootPoint = _spot.BottomRight;<br />
scaleSize = new SizeF((float)(width + distanceX) / width, (float)(height + distanceY) / height);<br />
break;<br />
<br />
case SpotLocation.Top:<br />
scaleRootPoint = _spot.Bottom;<br />
scaleSize = new SizeF(1, (float)(height + distanceY) / height);<br />
break;<br />
<br />
case SpotLocation.TopRight:<br />
scaleRootPoint = _spot.BottomLeft;<br />
scaleSize = new SizeF((float)(width + (-distanceX)) / width, (float)(height + distanceY) / height);<br />
break;<br />
<br />
case SpotLocation.Right:<br />
scaleRootPoint = _spot.Left;<br />
scaleSize = new SizeF((float)(width + (-distanceX)) / width, 1);<br />
break;<br />
<br />
case SpotLocation.BottomRight:<br />
scaleRootPoint = _spot.TopLeft;<br />
scaleSize = new SizeF((float)(width + (-distanceX)) / width, (float)(height + (-distanceY)) / height);<br />
break;<br />
<br />
case SpotLocation.Bottom:<br />
scaleRootPoint = _spot.Top;<br />
scaleSize = new SizeF(1, (float)(height + (-distanceY)) / height);<br />
break;<br />
<br />
case SpotLocation.BottomLeft:<br />
scaleRootPoint = _spot.TopRight;<br />
scaleSize = new SizeF((float)(width + distanceX) / width, (float)(_border.Height + (-distanceY)) / height);<br />
break;<br />
}<br />
}<br />
<br />
protected PointF _resizeOffset;<br />
public virtual void Resize(PointF scaleRootPoint, SizeF scaleSize)<br />
{<br />
PointF[] pts = Functions.GetPointsFromRect(_border);<br />
RectangleF tmp = _border;<br />
<br />
using (Matrix matrix = new Matrix())<br />
{<br />
matrix.Translate(-scaleRootPoint.X, -scaleRootPoint.Y);<br />
matrix.TransformPoints(pts);<br />
matrix.Reset();<br />
matrix.Scale(scaleSize.Width, scaleSize.Height);<br />
matrix.TransformPoints(pts);<br />
matrix.Reset();<br />
matrix.Translate(scaleRootPoint.X, scaleRootPoint.Y);<br />
matrix.TransformPoints(pts);<br />
tmp = Functions.GetRectFromPoints(pts);<br />
<br />
if (_rotateDegree != 0)<br />
{<br />
matrix.Reset();<br />
matrix.RotateAt(_rotateDegree, _spot.RotatePoint);<br />
matrix.TransformPoints(pts);<br />
<br />
PointF newRotatePoint = Functions.GetRotatePoint(pts);<br />
<br />
pts = Functions.GetPointsFromRect(_border);<br />
PointF oldRotatePoint = Functions.GetRotatePoint(tmp);<br />
float offsetX = newRotatePoint.X - oldRotatePoint.X;<br />
float offsetY = newRotatePoint.Y - oldRotatePoint.Y;<br />
_resizeOffset = new PointF(offsetX, offsetY);<br />
matrix.Reset();<br />
matrix.Translate(offsetX, offsetY);<br />
matrix.TransformPoints(pts);<br />
<br />
tmp = Functions.GetRectFromPoints(pts);<br />
}<br />
}<br />
<br />
tmp = Functions.StandardlizeRect(tmp.Location, new PointF(tmp.X + tmp.Width, tmp.Y + tmp.Height));<br />
float width = Math.Max(5, tmp.Width);<br />
float height = Math.Max(5, tmp.Height);<br />
tmp.Size = new SizeF(width, height);<br />
_border = tmp;
_spot.CalculateSpots(_border, _rotateDegree);<br />
}<br />
<br />
protected void LeaveResizingMode(PointF point)<br />
{<br />
PointF scaleRootPoint;<br />
SizeF scaleSize;<br />
CalculateScaleInfo(_spotLocation, _startPoint, point, out scaleRootPoint, out scaleSize);<br />
<br />
Resize(scaleRootPoint, scaleSize);<br />
GCPath();<br />
_state &= ~State.Resizing;<br />
_control.MouseMove -= new MouseEventHandler(EnterResizingMode_MouseMove);<br />
}<br />
<br />
#endregion<br />
<br />
#region rotate<br />
<br />
static AbstractShape __firstShape;<br />
static float __rotateDegree;<br />
public void EnterRotateMode(Control control, PointF point, Graphics graphics, AbstractShape firstShape)<br />
{<br />
__firstShape = firstShape;<br />
_control = control;<br />
_graphics = graphics;<br />
_startPoint = point;<br />
_state |= State.Rotating;<br />
_control.MouseMove += new MouseEventHandler(EnterRotatingMode_MouseMove);<br />
}<br />
<br />
void EnterRotatingMode_MouseMove(object sender, MouseEventArgs e)<br />
{<br />
if (e.Button != MouseButtons.Left)<br />
return;<br />
<br />
if (this == __firstShape)<br />
__rotateDegree = CalculateRotateDegree(e.Location);<br />
<br />
DrawRotatingObject(_startPoint, e.Location, __rotateDegree, _graphics);<br />
}<br />
<br />
float _oldRotateDegree;<br />
public void DrawRotatingObject(PointF startPoint, PointF endPoint, float rotateDegree, Graphics g)<br />
{<br />
PointF[] pts = Functions.GetPointsFromRect(_border);<br />
using (Matrix matrix = new Matrix())<br />
{<br />
matrix.RotateAt(rotateDegree, _spot.RotatePoint);<br />
matrix.TransformPoints(pts);<br />
}<br />
<br />
if (_oldPath != null)<br />
Rubberband.DrawXORPath(g, _oldPath, SizeF.Empty, PointF.Empty, SizeF.Empty, _oldRotateDegree, _spot.RotatePoint, _childShapeRotateDegrees);<br />
<br />
if (_path != null)<br />
_path.Dispose();<br />
_path = CreatePath(_border.Location, new PointF(_border.Right, _border.Bottom));<br />
Rubberband.DrawXORPath(g, _path, SizeF.Empty, PointF.Empty, SizeF.Empty, rotateDegree, _spot.RotatePoint, _childShapeRotateDegrees);<br />
<br />
_oldPath = _path;<br />
_oldRotateDegree = rotateDegree;<br />
}<br />
<br />
public virtual void Rotate(float rotateDegree)<br />
{<br />
_rotateDegree = rotateDegree;<br />
_spot.CalculateSpots(_border, _rotateDegree);<br />
}<br />
<br />
protected void LeaveRotatingMode(PointF point)<br />
{<br />
Rotate(__rotateDegree);<br />
GCPath();<br />
_state &= ~State.Rotating;<br />
_control.MouseMove -= new MouseEventHandler(EnterRotatingMode_MouseMove);<br />
}<br />
<br />
float CalculateRotateDegree(PointF point)<br />
{<br />
PointF rootPoint = _spot.RotatePoint;<br />
<br />
double tg = ((float)point.X - rootPoint.X) / (-(float)point.Y + rootPoint.Y);<br />
float degree = (float)((Math.Atan(tg) / Math.PI) * 180);<br />
if ((point.X < rootPoint.X && point.Y > rootPoint.Y) || (point.X > rootPoint.X && point.Y > rootPoint.Y))<br />
degree += 180;<br />
return degree;<br />
}<br />
<br />
#endregion<br />
<br />
#region support functions<br />
<br />
public virtual bool Contains(PointF point)<br />
{<br />
using (GraphicsPath path = CreatePath(_border.Location, new PointF(_border.Right, _border.Bottom)))<br />
{<br />
if (_rotateDegree != 0)<br />
{<br />
using (Matrix matrix = new Matrix())<br />
{<br />
matrix.RotateAt(_rotateDegree, _spot.RotatePoint);<br />
path.Transform(matrix);<br />
}<br />
}<br />
return path.IsVisible(point);<br />
}<br />
}<br />
<br />
public void LeaveCurrentMode(PointF point)<br />
{<br />
if ((_state & State.Creating) != 0)<br />
LeaveCreatingMode(point);<br />
<br />
if ((_state & State.Moving) != 0)<br />
LeaveMovingMode(point);<br />
<br />
if ((_state & State.Resizing) != 0)<br />
LeaveResizingMode(point);<br />
<br />
if ((_state & State.Rotating) != 0)<br />
LeaveRotatingMode(point);<br />
}<br />
<br />
private void GCPath()<br />
{<br />
if (_oldPath != null)<br />
{<br />
_oldPath.Dispose();<br />
_oldPath = null;<br />
}<br />
if (_path != null)<br />
{<br />
_path.Dispose();<br />
_path = null;<br />
}<br />
}<br />
<br />
#endregion<br />
<br />
#region IClonable Members<br />
<br />
public virtual object Clone()<br />
{<br />
AbstractShape obj = this.CreateInstance();<br />
obj._name = _name;<br />
obj._text = _text;<br />
obj.Size = this.Size;<br />
obj.Location = this.Location;<br />
obj._apprerance = (Apperance)this._apprerance.Clone();<br />
obj._restriction = (Restriction)this._restriction.Clone();<br />
obj._spot = (Spot)this._spot.Clone();<br />
obj._rotateDegree = _rotateDegree;<br />
return obj;<br />
}<br />
<br />
#endregion<br />
<br />
#region IDisposable Members<br />
<br />
public virtual void Dispose()<br />
{<br />
if (this._apprerance != null)<br />
this._apprerance.Dispose();<br />
if (this._editTextBox != null && this._editTextBox.IsDisposed == false)<br />
this._editTextBox.Dispose();<br />
__firstShape = null;<br />
}<br />
<br />
#endregion<br />
}<br />
}
|